Commit d1e7b4e3 authored by Max Kellermann's avatar Max Kellermann

audio_format: convert to C++

parent 67f591a9
......@@ -51,7 +51,6 @@ src_mpd_LDADD = \
mpd_headers = \
src/check.h \
src/ack.h \
src/audio_format.h \
src/filter_internal.h \
src/command.h \
src/conf.h \
......@@ -97,7 +96,7 @@ src_mpd_SOURCES = \
src/notify.cxx src/notify.hxx \
src/AudioConfig.cxx src/AudioConfig.hxx \
src/CheckAudioFormat.cxx src/CheckAudioFormat.hxx \
src/audio_format.c \
src/AudioFormat.cxx src/AudioFormat.hxx \
src/AudioParser.cxx src/AudioParser.hxx \
src/protocol/ArgParser.cxx src/protocol/ArgParser.hxx \
src/protocol/Result.cxx src/protocol/Result.hxx \
......@@ -1173,8 +1172,7 @@ test_run_decoder_SOURCES = test/run_decoder.cxx \
src/Tag.cxx src/TagNames.c src/TagPool.cxx src/TagHandler.cxx \
src/ReplayGainInfo.cxx \
src/fd_util.c \
src/CheckAudioFormat.cxx \
src/audio_format.c \
src/AudioFormat.cxx src/CheckAudioFormat.cxx \
$(ARCHIVE_SRC) \
$(INPUT_SRC) \
$(TAG_SRC) \
......@@ -1221,7 +1219,7 @@ test_run_filter_SOURCES = test/run_filter.cxx \
test/stdbin.h \
src/FilterPlugin.cxx src/FilterRegistry.cxx \
src/CheckAudioFormat.cxx \
src/audio_format.c \
src/AudioFormat.cxx \
src/AudioParser.cxx \
src/ReplayGainInfo.cxx \
src/AudioCompress/compress.c
......@@ -1240,7 +1238,7 @@ test_run_encoder_SOURCES = test/run_encoder.cxx \
test/stdbin.h \
src/Tag.cxx src/TagNames.c src/TagPool.cxx \
src/CheckAudioFormat.cxx \
src/audio_format.c \
src/AudioFormat.cxx \
src/AudioParser.cxx
test_run_encoder_LDADD = \
$(ENCODER_LIBS) \
......@@ -1258,7 +1256,7 @@ test_test_vorbis_encoder_SOURCES = test/test_vorbis_encoder.cxx \
test/stdbin.h \
src/Tag.cxx src/TagNames.c src/TagPool.cxx \
src/CheckAudioFormat.cxx \
src/audio_format.c \
src/AudioFormat.cxx \
src/AudioParser.cxx \
$(ENCODER_SRC)
test_test_vorbis_encoder_CPPFLAGS = $(AM_CPPFLAGS) \
......@@ -1289,7 +1287,7 @@ test_run_normalize_LDADD = \
$(GLIB_LIBS)
test_run_convert_SOURCES = test/run_convert.cxx \
src/audio_format.c \
src/AudioFormat.cxx \
src/CheckAudioFormat.cxx \
src/AudioParser.cxx
test_run_convert_LDADD = \
......@@ -1313,7 +1311,7 @@ test_run_output_SOURCES = test/run_output.cxx \
test/stdbin.h \
src/IOThread.cxx \
src/CheckAudioFormat.cxx \
src/audio_format.c \
src/AudioFormat.cxx \
src/AudioParser.cxx \
src/Timer.cxx src/clock.c \
src/Tag.cxx src/TagNames.c src/TagPool.cxx \
......
......@@ -19,18 +19,19 @@
#include "config.h"
#include "AudioConfig.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "AudioParser.hxx"
#include "conf.h"
#include "mpd_error.h"
static struct audio_format configured_audio_format;
static AudioFormat configured_audio_format;
void getOutputAudioFormat(const struct audio_format *inAudioFormat,
struct audio_format *outAudioFormat)
AudioFormat
getOutputAudioFormat(AudioFormat inAudioFormat)
{
*outAudioFormat = *inAudioFormat;
audio_format_mask_apply(outAudioFormat, &configured_audio_format);
AudioFormat out_audio_format = inAudioFormat;
out_audio_format.ApplyMask(configured_audio_format);
return out_audio_format;
}
void initAudioConfig(void)
......@@ -42,7 +43,7 @@ void initAudioConfig(void)
if (param == NULL)
return;
ret = audio_format_parse(&configured_audio_format, param->value,
ret = audio_format_parse(configured_audio_format, param->value,
true, &error);
if (!ret)
MPD_ERROR("error parsing line %i: %s",
......
......@@ -20,10 +20,10 @@
#ifndef MPD_AUDIO_CONFIG_HXX
#define MPD_AUDIO_CONFIG_HXX
struct audio_format;
struct AudioFormat;
void getOutputAudioFormat(const struct audio_format *inFormat,
struct audio_format *outFormat);
AudioFormat
getOutputAudioFormat(AudioFormat inFormat);
/* make sure initPlayerData is called before this function!! */
void initAudioConfig(void);
......
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -17,53 +17,52 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "audio_format.h"
#include "AudioFormat.hxx"
#include <assert.h>
#include <stdio.h>
void
audio_format_mask_apply(struct audio_format *af,
const struct audio_format *mask)
AudioFormat::ApplyMask(AudioFormat mask)
{
assert(audio_format_valid(af));
assert(audio_format_mask_valid(mask));
assert(IsValid());
assert(mask.IsMaskValid());
if (mask->sample_rate != 0)
af->sample_rate = mask->sample_rate;
if (mask.sample_rate != 0)
sample_rate = mask.sample_rate;
if (mask->format != SAMPLE_FORMAT_UNDEFINED)
af->format = mask->format;
if (mask.format != SampleFormat::UNDEFINED)
format = mask.format;
if (mask->channels != 0)
af->channels = mask->channels;
if (mask.channels != 0)
channels = mask.channels;
assert(audio_format_valid(af));
assert(IsValid());
}
const char *
sample_format_to_string(enum sample_format format)
sample_format_to_string(SampleFormat format)
{
switch (format) {
case SAMPLE_FORMAT_UNDEFINED:
case SampleFormat::UNDEFINED:
return "?";
case SAMPLE_FORMAT_S8:
case SampleFormat::S8:
return "8";
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
return "16";
case SAMPLE_FORMAT_S24_P32:
case SampleFormat::S24_P32:
return "24";
case SAMPLE_FORMAT_S32:
case SampleFormat::S32:
return "32";
case SAMPLE_FORMAT_FLOAT:
case SampleFormat::FLOAT:
return "f";
case SAMPLE_FORMAT_DSD:
case SampleFormat::DSD:
return "dsd";
}
......@@ -73,15 +72,14 @@ sample_format_to_string(enum sample_format format)
}
const char *
audio_format_to_string(const struct audio_format *af,
audio_format_to_string(const AudioFormat af,
struct audio_format_string *s)
{
assert(af != NULL);
assert(s != NULL);
assert(s != nullptr);
snprintf(s->buffer, sizeof(s->buffer), "%u:%s:%u",
af->sample_rate, sample_format_to_string(af->format),
af->channels);
af.sample_rate, sample_format_to_string(af.format),
af.channels);
return s->buffer;
}
/*
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_AUDIO_FORMAT_HXX
#define MPD_AUDIO_FORMAT_HXX
#include "gcc.h"
#include <stdint.h>
#include <assert.h>
#if defined(WIN32) && GCC_CHECK_VERSION(4,6)
/* on WIN32, "FLOAT" is already defined, and this triggers -Wshadow */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#endif
enum class SampleFormat : uint8_t {
UNDEFINED = 0,
S8,
S16,
/**
* Signed 24 bit integer samples, packed in 32 bit integers
* (the most significant byte is filled with the sign bit).
*/
S24_P32,
S32,
/**
* 32 bit floating point samples in the host's format. The
* range is -1.0f to +1.0f.
*/
FLOAT,
/**
* Direct Stream Digital. 1-bit samples; each frame has one
* byte (8 samples) per channel.
*/
DSD,
};
#if defined(WIN32) && GCC_CHECK_VERSION(4,6)
#pragma GCC diagnostic pop
#endif
static constexpr unsigned MAX_CHANNELS = 8;
/**
* This structure describes the format of a raw PCM stream.
*/
struct AudioFormat {
/**
* The sample rate in Hz. A better name for this attribute is
* "frame rate", because technically, you have two samples per
* frame in stereo sound.
*/
uint32_t sample_rate;
/**
* The format samples are stored in. See the #sample_format
* enum for valid values.
*/
SampleFormat format;
/**
* The number of channels. Only mono (1) and stereo (2) are
* fully supported currently.
*/
uint8_t channels;
AudioFormat() = default;
constexpr AudioFormat(uint32_t _sample_rate,
SampleFormat _format, uint8_t _channels)
:sample_rate(_sample_rate),
format(_format), channels(_channels) {}
static constexpr AudioFormat Undefined() {
return AudioFormat(0, SampleFormat::UNDEFINED,0);
}
/**
* Clears the #audio_format object, i.e. sets all attributes to an
* undefined (invalid) value.
*/
void Clear() {
sample_rate = 0;
format = SampleFormat::UNDEFINED;
channels = 0;
}
/**
* Checks whether the object has a defined value.
*/
constexpr bool IsDefined() const {
return sample_rate != 0;
}
/**
* Checks whether the object is full, i.e. all attributes are
* defined. This is more complete than IsDefined(), but
* slower.
*/
constexpr bool IsFullyDefined() const {
return sample_rate != 0 && format != SampleFormat::UNDEFINED &&
channels != 0;
}
/**
* Checks whether the object has at least one defined value.
*/
constexpr bool IsMaskDefined() const {
return sample_rate != 0 || format != SampleFormat::UNDEFINED ||
channels != 0;
}
bool IsValid() const;
bool IsMaskValid() const;
constexpr bool operator==(const AudioFormat other) const {
return sample_rate == other.sample_rate &&
format == other.format &&
channels == other.channels;
}
constexpr bool operator!=(const AudioFormat other) const {
return !(*this == other);
}
void ApplyMask(AudioFormat mask);
/**
* Returns the size of each (mono) sample in bytes.
*/
unsigned GetSampleSize() const;
/**
* Returns the size of each full frame in bytes.
*/
unsigned GetFrameSize() const;
/**
* Returns the floating point factor which converts a time
* span to a storage size in bytes.
*/
double GetTimeToSize() const;
};
/**
* Buffer for audio_format_string().
*/
struct audio_format_string {
char buffer[24];
};
/**
* Checks whether the sample rate is valid.
*
* @param sample_rate the sample rate in Hz
*/
static constexpr inline bool
audio_valid_sample_rate(unsigned sample_rate)
{
return sample_rate > 0 && sample_rate < (1 << 30);
}
/**
* Checks whether the sample format is valid.
*
* @param bits the number of significant bits per sample
*/
static inline bool
audio_valid_sample_format(SampleFormat format)
{
switch (format) {
case SampleFormat::S8:
case SampleFormat::S16:
case SampleFormat::S24_P32:
case SampleFormat::S32:
case SampleFormat::FLOAT:
case SampleFormat::DSD:
return true;
case SampleFormat::UNDEFINED:
break;
}
return false;
}
/**
* Checks whether the number of channels is valid.
*/
static constexpr inline bool
audio_valid_channel_count(unsigned channels)
{
return channels >= 1 && channels <= MAX_CHANNELS;
}
/**
* Returns false if the format is not valid for playback with MPD.
* This function performs some basic validity checks.
*/
inline bool
AudioFormat::IsValid() const
{
return audio_valid_sample_rate(sample_rate) &&
audio_valid_sample_format(format) &&
audio_valid_channel_count(channels);
}
/**
* Returns false if the format mask is not valid for playback with
* MPD. This function performs some basic validity checks.
*/
inline bool
AudioFormat::IsMaskValid() const
{
return (sample_rate == 0 ||
audio_valid_sample_rate(sample_rate)) &&
(format == SampleFormat::UNDEFINED ||
audio_valid_sample_format(format)) &&
(channels == 0 || audio_valid_channel_count(channels));
}
gcc_const
static inline unsigned
sample_format_size(SampleFormat format)
{
switch (format) {
case SampleFormat::S8:
return 1;
case SampleFormat::S16:
return 2;
case SampleFormat::S24_P32:
case SampleFormat::S32:
case SampleFormat::FLOAT:
return 4;
case SampleFormat::DSD:
/* each frame has 8 samples per channel */
return 1;
case SampleFormat::UNDEFINED:
return 0;
}
assert(false);
gcc_unreachable();
}
inline unsigned
AudioFormat::GetSampleSize() const
{
return sample_format_size(format);
}
inline unsigned
AudioFormat::GetFrameSize() const
{
return GetSampleSize() * channels;
}
inline double
AudioFormat::GetTimeToSize() const
{
return sample_rate * GetFrameSize();
}
/**
* Renders a #sample_format enum into a string, e.g. for printing it
* in a log file.
*
* @param format a #sample_format enum value
* @return the string
*/
gcc_pure gcc_malloc
const char *
sample_format_to_string(SampleFormat format);
/**
* Renders the #audio_format object into a string, e.g. for printing
* it in a log file.
*
* @param af the #audio_format object
* @param s a buffer to print into
* @return the string, or NULL if the #audio_format object is invalid
*/
gcc_pure gcc_malloc
const char *
audio_format_to_string(AudioFormat af,
struct audio_format_string *s);
#endif
......@@ -24,7 +24,7 @@
#include "config.h"
#include "AudioParser.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "CheckAudioFormat.hxx"
#include "gcc.h"
......@@ -69,27 +69,27 @@ parse_sample_rate(const char *src, bool mask, uint32_t *sample_rate_r,
static bool
parse_sample_format(const char *src, bool mask,
enum sample_format *sample_format_r,
SampleFormat *sample_format_r,
const char **endptr_r, GError **error_r)
{
unsigned long value;
char *endptr;
enum sample_format sample_format;
SampleFormat sample_format;
if (mask && *src == '*') {
*sample_format_r = SAMPLE_FORMAT_UNDEFINED;
*sample_format_r = SampleFormat::UNDEFINED;
*endptr_r = src + 1;
return true;
}
if (*src == 'f') {
*sample_format_r = SAMPLE_FORMAT_FLOAT;
*sample_format_r = SampleFormat::FLOAT;
*endptr_r = src + 1;
return true;
}
if (memcmp(src, "dsd", 3) == 0) {
*sample_format_r = SAMPLE_FORMAT_DSD;
*sample_format_r = SampleFormat::DSD;
*endptr_r = src + 3;
return true;
}
......@@ -103,11 +103,11 @@ parse_sample_format(const char *src, bool mask,
switch (value) {
case 8:
sample_format = SAMPLE_FORMAT_S8;
sample_format = SampleFormat::S8;
break;
case 16:
sample_format = SAMPLE_FORMAT_S16;
sample_format = SampleFormat::S16;
break;
case 24:
......@@ -115,11 +115,11 @@ parse_sample_format(const char *src, bool mask,
/* for backwards compatibility */
endptr += 2;
sample_format = SAMPLE_FORMAT_S24_P32;
sample_format = SampleFormat::S24_P32;
break;
case 32:
sample_format = SAMPLE_FORMAT_S32;
sample_format = SampleFormat::S32;
break;
default:
......@@ -162,14 +162,14 @@ parse_channel_count(const char *src, bool mask, uint8_t *channels_r,
}
bool
audio_format_parse(struct audio_format *dest, const char *src,
audio_format_parse(AudioFormat &dest, const char *src,
bool mask, GError **error_r)
{
uint32_t rate;
enum sample_format sample_format;
SampleFormat sample_format;
uint8_t channels;
audio_format_clear(dest);
dest.Clear();
/* parse sample rate */
......@@ -191,7 +191,7 @@ audio_format_parse(struct audio_format *dest, const char *src,
#if GCC_CHECK_VERSION(4,7)
/* workaround -Wmaybe-uninitialized false positive */
sample_format = SAMPLE_FORMAT_UNDEFINED;
sample_format = SampleFormat::UNDEFINED;
#endif
if (!parse_sample_format(src, mask, &sample_format, &src, error_r))
......@@ -214,9 +214,10 @@ audio_format_parse(struct audio_format *dest, const char *src,
return false;
}
audio_format_init(dest, rate, sample_format, channels);
assert(mask ? audio_format_mask_valid(dest)
: audio_format_valid(dest));
dest = AudioFormat(rate, sample_format, channels);
assert(mask
? dest.IsMaskValid()
: dest.IsValid());
return true;
}
......@@ -27,7 +27,7 @@
#include "gerror.h"
struct audio_format;
struct AudioFormat;
/**
* Parses a string in the form "SAMPLE_RATE:BITS:CHANNELS" into an
......@@ -41,7 +41,7 @@ struct audio_format;
* @return true on success
*/
bool
audio_format_parse(struct audio_format *dest, const char *src,
audio_format_parse(AudioFormat &dest, const char *src,
bool mask, GError **error_r);
#endif
......@@ -18,7 +18,7 @@
*/
#include "CheckAudioFormat.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include <assert.h>
......@@ -35,11 +35,12 @@ audio_check_sample_rate(unsigned long sample_rate, GError **error_r)
}
bool
audio_check_sample_format(enum sample_format sample_format, GError **error_r)
audio_check_sample_format(SampleFormat sample_format, GError **error_r)
{
if (!audio_valid_sample_format(sample_format)) {
g_set_error(error_r, audio_format_quark(), 0,
"Invalid sample format: %u", sample_format);
"Invalid sample format: %u",
unsigned(sample_format));
return false;
}
......@@ -59,15 +60,15 @@ audio_check_channel_count(unsigned channels, GError **error_r)
}
bool
audio_format_init_checked(struct audio_format *af, unsigned long sample_rate,
enum sample_format sample_format, unsigned channels,
audio_format_init_checked(AudioFormat &af, unsigned long sample_rate,
SampleFormat sample_format, unsigned channels,
GError **error_r)
{
if (audio_check_sample_rate(sample_rate, error_r) &&
audio_check_sample_format(sample_format, error_r) &&
audio_check_channel_count(channels, error_r)) {
audio_format_init(af, sample_rate, sample_format, channels);
assert(audio_format_valid(af));
af = AudioFormat(sample_rate, sample_format, channels);
assert(af.IsValid());
return true;
} else
return false;
......
......@@ -20,7 +20,7 @@
#ifndef MPD_CHECK_AUDIO_FORMAT_HXX
#define MPD_CHECK_AUDIO_FORMAT_HXX
#include "audio_format.h"
#include "AudioFormat.hxx"
#include <glib.h>
......@@ -38,7 +38,7 @@ bool
audio_check_sample_rate(unsigned long sample_rate, GError **error_r);
bool
audio_check_sample_format(enum sample_format, GError **error_r);
audio_check_sample_format(SampleFormat sample_format, GError **error_r);
bool
audio_check_channel_count(unsigned sample_format, GError **error_r);
......@@ -47,8 +47,8 @@ audio_check_channel_count(unsigned sample_format, GError **error_r);
* Wrapper for audio_format_init(), which checks all attributes.
*/
bool
audio_format_init_checked(struct audio_format *af, unsigned long sample_rate,
enum sample_format sample_format, unsigned channels,
audio_format_init_checked(AudioFormat &af, unsigned long sample_rate,
SampleFormat sample_format, unsigned channels,
GError **error_r);
#endif
......@@ -20,7 +20,7 @@
#include "config.h"
#include "CrossFade.hxx"
#include "MusicChunk.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "Tag.hxx"
#include <cmath>
......@@ -97,8 +97,8 @@ unsigned cross_fade_calc(float duration, float total_time,
float mixramp_db, float mixramp_delay,
float replay_gain_db, float replay_gain_prev_db,
char *mixramp_start, char *mixramp_prev_end,
const struct audio_format *af,
const struct audio_format *old_format,
const AudioFormat af,
const AudioFormat old_format,
unsigned max_chunks)
{
unsigned int chunks = 0;
......@@ -107,13 +107,13 @@ unsigned cross_fade_calc(float duration, float total_time,
if (duration < 0 || duration >= total_time ||
/* we can't crossfade when the audio formats are different */
!audio_format_equals(af, old_format))
af != old_format)
return 0;
assert(duration >= 0);
assert(audio_format_valid(af));
assert(af.IsValid());
chunks_f = (float)audio_format_time_to_size(af) / (float)CHUNK_SIZE;
chunks_f = (float)af.GetTimeToSize() / (float)CHUNK_SIZE;
if (std::isnan(mixramp_delay) || !mixramp_start || !mixramp_prev_end) {
chunks = (chunks_f * duration + 0.5);
......
......@@ -20,7 +20,7 @@
#ifndef MPD_CROSSFADE_HXX
#define MPD_CROSSFADE_HXX
struct audio_format;
struct AudioFormat;
struct music_chunk;
/**
......@@ -44,8 +44,7 @@ unsigned cross_fade_calc(float duration, float total_time,
float mixramp_db, float mixramp_delay,
float replay_gain_db, float replay_gain_prev_db,
char *mixramp_start, char *mixramp_prev_end,
const struct audio_format *af,
const struct audio_format *old_format,
AudioFormat af, AudioFormat old_format,
unsigned max_chunks);
#endif
......@@ -40,7 +40,7 @@
void
decoder_initialized(struct decoder *decoder,
const struct audio_format *audio_format,
const AudioFormat audio_format,
bool seekable, float total_time)
{
struct decoder_control *dc = decoder->dc;
......@@ -52,12 +52,11 @@ decoder_initialized(struct decoder *decoder,
assert(decoder->stream_tag == NULL);
assert(decoder->decoder_tag == NULL);
assert(!decoder->seeking);
assert(audio_format != NULL);
assert(audio_format_defined(audio_format));
assert(audio_format_valid(audio_format));
assert(audio_format.IsDefined());
assert(audio_format.IsValid());
dc->in_audio_format = *audio_format;
getOutputAudioFormat(audio_format, &dc->out_audio_format);
dc->in_audio_format = audio_format;
dc->out_audio_format = getOutputAudioFormat(audio_format);
dc->seekable = seekable;
dc->total_time = total_time;
......@@ -68,13 +67,12 @@ decoder_initialized(struct decoder *decoder,
dc->Unlock();
g_debug("audio_format=%s, seekable=%s",
audio_format_to_string(&dc->in_audio_format, &af_string),
audio_format_to_string(dc->in_audio_format, &af_string),
seekable ? "true" : "false");
if (!audio_format_equals(&dc->in_audio_format,
&dc->out_audio_format))
if (dc->in_audio_format != dc->out_audio_format)
g_debug("converting to %s",
audio_format_to_string(&dc->out_audio_format,
audio_format_to_string(dc->out_audio_format,
&af_string));
}
......@@ -371,7 +369,7 @@ decoder_data(struct decoder *decoder,
assert(dc->state == DECODE_STATE_DECODE);
assert(dc->pipe != NULL);
assert(length % audio_format_frame_size(&dc->in_audio_format) == 0);
assert(length % dc->in_audio_format.GetFrameSize() == 0);
dc->Lock();
cmd = decoder_get_virtual_command(decoder);
......@@ -398,10 +396,10 @@ decoder_data(struct decoder *decoder,
return cmd;
}
if (!audio_format_equals(&dc->in_audio_format, &dc->out_audio_format)) {
data = decoder->conv_state.Convert(&dc->in_audio_format,
if (dc->in_audio_format != dc->out_audio_format) {
data = decoder->conv_state.Convert(dc->in_audio_format,
data, length,
&dc->out_audio_format,
dc->out_audio_format,
&length,
&error);
if (data == NULL) {
......@@ -457,7 +455,7 @@ decoder_data(struct decoder *decoder,
length -= nbytes;
decoder->timestamp += (double)nbytes /
audio_format_time_to_size(&dc->out_audio_format);
dc->out_audio_format.GetTimeToSize();
if (dc->end_ms > 0 &&
decoder->timestamp >= dc->end_ms / 1000.0)
......
......@@ -33,7 +33,7 @@
#include "input_stream.h"
#include "replay_gain_info.h"
#include "Tag.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "conf.h"
/**
......@@ -48,7 +48,7 @@
*/
void
decoder_initialized(struct decoder *decoder,
const struct audio_format *audio_format,
AudioFormat audio_format,
bool seekable, float total_time);
/**
......
......@@ -21,7 +21,7 @@
#define MPD_DECODER_CONTROL_HXX
#include "DecoderCommand.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
......@@ -85,10 +85,10 @@ struct decoder_control {
double seek_where;
/** the format of the song file */
struct audio_format in_audio_format;
AudioFormat in_audio_format;
/** the format being sent to the music pipe */
struct audio_format out_audio_format;
AudioFormat out_audio_format;
/**
* The song currently being decoded. This attribute is set by
......
......@@ -26,7 +26,7 @@
#define MPD_ENCODER_API_HXX
#include "EncoderPlugin.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "Tag.hxx"
#include "conf.h"
......
......@@ -27,7 +27,7 @@
#include <stddef.h>
struct EncoderPlugin;
struct audio_format;
struct AudioFormat;
struct config_param;
struct Tag;
......@@ -55,7 +55,7 @@ struct EncoderPlugin {
void (*finish)(Encoder *encoder);
bool (*open)(Encoder *encoder,
struct audio_format *audio_format,
AudioFormat &audio_format,
GError **error);
void (*close)(Encoder *encoder);
......@@ -122,7 +122,7 @@ encoder_finish(Encoder *encoder)
* @return true on success
*/
static inline bool
encoder_open(Encoder *encoder, struct audio_format *audio_format,
encoder_open(Encoder *encoder, AudioFormat &audio_format,
GError **error)
{
assert(!encoder->open);
......
......@@ -25,7 +25,7 @@
#ifndef MPD_FILTER_INTERNAL_HXX
#define MPD_FILTER_INTERNAL_HXX
struct audio_format;
struct AudioFormat;
class Filter {
public:
......@@ -40,10 +40,10 @@ public:
* format
* @param error location to store the error occurring, or NULL
* to ignore errors.
* @return the format of outgoing data
* @return the format of outgoing data or
* AudioFormat::Undefined() on error
*/
virtual const audio_format *Open(audio_format &af,
GError **error_r) = 0;
virtual AudioFormat Open(AudioFormat &af, GError **error_r) = 0;
/**
* Closes the filter. After that, you may call Open() again.
......
......@@ -19,7 +19,7 @@
#include "config.h"
#include "MusicChunk.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "Tag.hxx"
#include <assert.h>
......@@ -31,22 +31,21 @@ music_chunk::~music_chunk()
#ifndef NDEBUG
bool
music_chunk::CheckFormat(const struct audio_format &other_format) const
music_chunk::CheckFormat(const AudioFormat other_format) const
{
assert(audio_format_valid(&other_format));
assert(other_format.IsValid());
return length == 0 ||
audio_format_equals(&audio_format, &other_format);
return length == 0 || audio_format == other_format;
}
#endif
void *
music_chunk::Write(const struct audio_format &af,
music_chunk::Write(const AudioFormat af,
float data_time, uint16_t _bit_rate,
size_t *max_length_r)
{
assert(CheckFormat(af));
assert(length == 0 || audio_format_valid(&audio_format));
assert(length == 0 || audio_format.IsValid());
if (length == 0) {
/* if the chunk is empty, nobody has set bitRate and
......@@ -56,7 +55,7 @@ music_chunk::Write(const struct audio_format &af,
times = data_time;
}
const size_t frame_size = audio_format_frame_size(&af);
const size_t frame_size = af.GetFrameSize();
size_t num_frames = (sizeof(data) - length) / frame_size;
if (num_frames == 0)
return NULL;
......@@ -70,12 +69,12 @@ music_chunk::Write(const struct audio_format &af,
}
bool
music_chunk::Expand(const struct audio_format &af, size_t _length)
music_chunk::Expand(const AudioFormat af, size_t _length)
{
const size_t frame_size = audio_format_frame_size(&af);
const size_t frame_size = af.GetFrameSize();
assert(length + _length <= sizeof(data));
assert(audio_format_equals(&audio_format, &af));
assert(audio_format == af);
length += _length;
......
......@@ -23,7 +23,7 @@
#include "replay_gain_info.h"
#ifndef NDEBUG
#include "audio_format.h"
#include "AudioFormat.hxx"
#endif
#include <stdint.h>
......@@ -33,7 +33,7 @@ enum {
CHUNK_SIZE = 4096,
};
struct audio_format;
struct AudioFormat;
struct Tag;
/**
......@@ -90,7 +90,7 @@ struct music_chunk {
char data[CHUNK_SIZE];
#ifndef NDEBUG
struct audio_format audio_format;
AudioFormat audio_format;
#endif
music_chunk()
......@@ -111,7 +111,7 @@ struct music_chunk {
* specified audio_format.
*/
gcc_pure
bool CheckFormat(const struct audio_format &audio_format) const;
bool CheckFormat(AudioFormat audio_format) const;
#endif
/**
......@@ -128,7 +128,7 @@ struct music_chunk {
* here
* @return a writable buffer, or NULL if the chunk is full
*/
void *Write(const struct audio_format &af,
void *Write(AudioFormat af,
float data_time, uint16_t bit_rate,
size_t *max_length_r);
......@@ -142,7 +142,7 @@ struct music_chunk {
* @param length the number of bytes which were appended
* @return true if the chunk is full
*/
bool Expand(const struct audio_format &af, size_t length);
bool Expand(AudioFormat af, size_t length);
};
void
......
......@@ -41,13 +41,13 @@ struct music_pipe {
mutable Mutex mutex;
#ifndef NDEBUG
struct audio_format audio_format;
AudioFormat audio_format;
#endif
music_pipe()
:head(nullptr), tail_r(&head), size(0) {
#ifndef NDEBUG
audio_format_clear(&audio_format);
audio_format.Clear();
#endif
}
......@@ -73,13 +73,12 @@ music_pipe_free(struct music_pipe *mp)
bool
music_pipe_check_format(const struct music_pipe *pipe,
const struct audio_format *audio_format)
const AudioFormat audio_format)
{
assert(pipe != NULL);
assert(audio_format != NULL);
return !audio_format_defined(&pipe->audio_format) ||
audio_format_equals(&pipe->audio_format, audio_format);
return !pipe->audio_format.IsDefined() ||
pipe->audio_format == audio_format;
}
bool
......@@ -131,7 +130,7 @@ music_pipe_shift(struct music_pipe *mp)
chunk->next = (struct music_chunk *)(void *)0x01010101;
if (mp->size == 0)
audio_format_clear(&mp->audio_format);
mp->audio_format.Clear();
#endif
}
......@@ -151,16 +150,16 @@ void
music_pipe_push(struct music_pipe *mp, struct music_chunk *chunk)
{
assert(!chunk->IsEmpty());
assert(chunk->length == 0 || audio_format_valid(&chunk->audio_format));
assert(chunk->length == 0 || chunk->audio_format.IsValid());
const ScopeLock protect(mp->mutex);
assert(mp->size > 0 || !audio_format_defined(&mp->audio_format));
assert(!audio_format_defined(&mp->audio_format) ||
assert(mp->size > 0 || !mp->audio_format.IsDefined());
assert(!mp->audio_format.IsDefined() ||
chunk->CheckFormat(mp->audio_format));
#ifndef NDEBUG
if (!audio_format_defined(&mp->audio_format) && chunk->length > 0)
if (!mp->audio_format.IsDefined() && chunk->length > 0)
mp->audio_format = chunk->audio_format;
#endif
......
......@@ -23,7 +23,7 @@
#include "gcc.h"
#ifndef NDEBUG
struct audio_format;
struct AudioFormat;
#endif
struct music_chunk;
......@@ -56,7 +56,7 @@ music_pipe_free(struct music_pipe *mp);
*/
bool
music_pipe_check_format(const struct music_pipe *pipe,
const struct audio_format *audio_format);
AudioFormat audio_format);
/**
* Checks if the specified chunk is enqueued in the music pipe.
......
......@@ -22,7 +22,7 @@
#include "OutputPlugin.hxx"
#include "OutputInternal.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "Tag.hxx"
#include "conf.h"
......
......@@ -36,7 +36,7 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "output"
static struct audio_format input_audio_format;
static AudioFormat input_audio_format;
static struct audio_output **audio_outputs;
static unsigned int num_audio_outputs;
......@@ -246,12 +246,12 @@ audio_output_all_update(void)
unsigned int i;
bool ret = false;
if (!audio_format_defined(&input_audio_format))
if (!input_audio_format.IsDefined())
return false;
for (i = 0; i < num_audio_outputs; ++i)
ret = audio_output_update(audio_outputs[i],
&input_audio_format, g_mp) || ret;
input_audio_format, g_mp) || ret;
return ret;
}
......@@ -291,14 +291,13 @@ audio_output_all_play(struct music_chunk *chunk, GError **error_r)
}
bool
audio_output_all_open(const struct audio_format *audio_format,
audio_output_all_open(const AudioFormat audio_format,
struct music_buffer *buffer,
GError **error_r)
{
bool ret = false, enabled = false;
unsigned int i;
assert(audio_format != NULL);
assert(buffer != NULL);
assert(g_music_buffer == NULL || g_music_buffer == buffer);
assert((g_mp == NULL) == (g_music_buffer == NULL));
......@@ -315,10 +314,9 @@ audio_output_all_open(const struct audio_format *audio_format,
/* if the pipe hasn't been cleared, the the audio
format must not have changed */
assert(music_pipe_empty(g_mp) ||
audio_format_equals(audio_format,
&input_audio_format));
audio_format == input_audio_format);
input_audio_format = *audio_format;
input_audio_format = audio_format;
audio_output_all_reset_reopen();
audio_output_all_enable_disable();
......@@ -547,7 +545,7 @@ audio_output_all_close(void)
g_music_buffer = NULL;
audio_format_clear(&input_audio_format);
input_audio_format.Clear();
audio_output_all_elapsed_time = -1.0;
}
......@@ -570,7 +568,7 @@ audio_output_all_release(void)
g_music_buffer = NULL;
audio_format_clear(&input_audio_format);
input_audio_format.Clear();
audio_output_all_elapsed_time = -1.0;
}
......
......@@ -29,7 +29,7 @@
#include "replay_gain_info.h"
#include "gerror.h"
struct audio_format;
struct AudioFormat;
struct music_buffer;
struct music_chunk;
struct player_control;
......@@ -76,14 +76,13 @@ audio_output_all_enable_disable(void);
/**
* Opens all audio outputs which are not disabled.
*
* @param audio_format the preferred audio format, or NULL to reuse
* the previous format
* @param audio_format the preferred audio format
* @param buffer the #music_buffer where consumed #music_chunk objects
* should be returned
* @return true on success, false on failure
*/
bool
audio_output_all_open(const struct audio_format *audio_format,
audio_output_all_open(AudioFormat audio_format,
struct music_buffer *buffer,
GError **error_r);
......
......@@ -139,14 +139,14 @@ audio_output_disable(struct audio_output *ao)
*/
static bool
audio_output_open(struct audio_output *ao,
const struct audio_format *audio_format,
const AudioFormat audio_format,
const struct music_pipe *mp)
{
bool open;
assert(ao != NULL);
assert(ao->allow_play);
assert(audio_format_valid(audio_format));
assert(audio_format.IsValid());
assert(mp != NULL);
if (ao->fail_timer != NULL) {
......@@ -154,8 +154,7 @@ audio_output_open(struct audio_output *ao,
ao->fail_timer = NULL;
}
if (ao->open &&
audio_format_equals(audio_format, &ao->in_audio_format)) {
if (ao->open && audio_format == ao->in_audio_format) {
assert(ao->pipe == mp ||
(ao->always_on && ao->pause));
......@@ -176,7 +175,7 @@ audio_output_open(struct audio_output *ao,
return true;
}
ao->in_audio_format = *audio_format;
ao->in_audio_format = audio_format;
ao->chunk = NULL;
ao->pipe = mp;
......@@ -225,7 +224,7 @@ audio_output_close_locked(struct audio_output *ao)
bool
audio_output_update(struct audio_output *ao,
const struct audio_format *audio_format,
const AudioFormat audio_format,
const struct music_pipe *mp)
{
assert(mp != NULL);
......
......@@ -25,7 +25,7 @@
#include <stddef.h>
struct audio_output;
struct audio_format;
struct AudioFormat;
struct config_param;
struct music_pipe;
struct player_control;
......@@ -53,7 +53,7 @@ audio_output_disable(struct audio_output *ao);
*/
bool
audio_output_update(struct audio_output *ao,
const struct audio_format *audio_format,
AudioFormat audio_format,
const struct music_pipe *mp);
void
......
......@@ -155,16 +155,16 @@ ao_base_init(struct audio_output *ao,
NULL);
if (p != NULL) {
bool success =
audio_format_parse(&ao->config_audio_format,
audio_format_parse(ao->config_audio_format,
p, true, error_r);
if (!success)
return false;
} else
audio_format_clear(&ao->config_audio_format);
ao->config_audio_format.Clear();
} else {
ao->name = "default detected output";
audio_format_clear(&ao->config_audio_format);
ao->config_audio_format.Clear();
}
ao->plugin = plugin;
......
......@@ -20,7 +20,7 @@
#ifndef MPD_OUTPUT_INTERNAL_HXX
#define MPD_OUTPUT_INTERNAL_HXX
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "pcm/PcmBuffer.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
......@@ -134,13 +134,13 @@ struct audio_output {
/**
* The configured audio format.
*/
struct audio_format config_audio_format;
AudioFormat config_audio_format;
/**
* The audio_format in which audio data is received from the
* player thread (which in turn receives it from the decoder).
*/
struct audio_format in_audio_format;
AudioFormat in_audio_format;
/**
* The audio_format which is really sent to the device. This
......@@ -148,7 +148,7 @@ struct audio_output {
* in_audio_format, but may have been modified by
* plugin->open().
*/
struct audio_format out_audio_format;
AudioFormat out_audio_format;
/**
* The buffer used to allocate the cross-fading result.
......
......@@ -54,7 +54,7 @@ ao_plugin_disable(struct audio_output *ao)
}
bool
ao_plugin_open(struct audio_output *ao, struct audio_format *audio_format,
ao_plugin_open(struct audio_output *ao, AudioFormat &audio_format,
GError **error)
{
return ao->plugin->open(ao, audio_format, error);
......
......@@ -26,7 +26,7 @@
#include <stddef.h>
struct config_param;
struct audio_format;
struct AudioFormat;
struct Tag;
/**
......@@ -89,7 +89,7 @@ struct audio_output_plugin {
* @param error location to store the error occurring, or NULL
* to ignore errors
*/
bool (*open)(struct audio_output *data, struct audio_format *audio_format,
bool (*open)(struct audio_output *data, AudioFormat &audio_format,
GError **error);
/**
......@@ -181,7 +181,7 @@ void
ao_plugin_disable(struct audio_output *ao);
bool
ao_plugin_open(struct audio_output *ao, struct audio_format *audio_format,
ao_plugin_open(struct audio_output *ao, AudioFormat &audio_format,
GError **error);
void
......
......@@ -94,11 +94,11 @@ ao_disable(struct audio_output *ao)
}
}
static const struct audio_format *
ao_filter_open(struct audio_output *ao, audio_format &format,
static AudioFormat
ao_filter_open(struct audio_output *ao, AudioFormat &format,
GError **error_r)
{
assert(audio_format_valid(&format));
assert(format.IsValid());
/* the replay_gain filter cannot fail here */
if (ao->replay_gain_filter != NULL)
......@@ -106,9 +106,8 @@ ao_filter_open(struct audio_output *ao, audio_format &format,
if (ao->other_replay_gain_filter != NULL)
ao->other_replay_gain_filter->Open(format, error_r);
const struct audio_format *af
= ao->filter->Open(format, error_r);
if (af == NULL) {
const AudioFormat af = ao->filter->Open(format, error_r);
if (!af.IsDefined()) {
if (ao->replay_gain_filter != NULL)
ao->replay_gain_filter->Close();
if (ao->other_replay_gain_filter != NULL)
......@@ -139,7 +138,7 @@ ao_open(struct audio_output *ao)
assert(!ao->open);
assert(ao->pipe != NULL);
assert(ao->chunk == NULL);
assert(audio_format_valid(&ao->in_audio_format));
assert(ao->in_audio_format.IsValid());
if (ao->fail_timer != NULL) {
/* this can only happen when this
......@@ -158,9 +157,9 @@ ao_open(struct audio_output *ao)
/* open the filter */
const audio_format *filter_audio_format =
const AudioFormat filter_audio_format =
ao_filter_open(ao, ao->in_audio_format, &error);
if (filter_audio_format == NULL) {
if (!filter_audio_format.IsDefined()) {
g_warning("Failed to open filter for \"%s\" [%s]: %s",
ao->name, ao->plugin->name, error->message);
g_error_free(error);
......@@ -169,14 +168,13 @@ ao_open(struct audio_output *ao)
return;
}
assert(audio_format_valid(filter_audio_format));
assert(filter_audio_format.IsValid());
ao->out_audio_format = *filter_audio_format;
audio_format_mask_apply(&ao->out_audio_format,
&ao->config_audio_format);
ao->out_audio_format = filter_audio_format;
ao->out_audio_format.ApplyMask(ao->config_audio_format);
ao->mutex.unlock();
success = ao_plugin_open(ao, &ao->out_audio_format, &error);
success = ao_plugin_open(ao, ao->out_audio_format, &error);
ao->mutex.lock();
assert(!ao->open);
......@@ -198,12 +196,11 @@ ao_open(struct audio_output *ao)
g_debug("opened plugin=%s name=\"%s\" "
"audio_format=%s",
ao->plugin->name, ao->name,
audio_format_to_string(&ao->out_audio_format, &af_string));
audio_format_to_string(ao->out_audio_format, &af_string));
if (!audio_format_equals(&ao->in_audio_format,
&ao->out_audio_format))
if (ao->in_audio_format != ao->out_audio_format)
g_debug("converting from %s",
audio_format_to_string(&ao->in_audio_format,
audio_format_to_string(ao->in_audio_format,
&af_string));
}
......@@ -235,12 +232,12 @@ ao_close(struct audio_output *ao, bool drain)
static void
ao_reopen_filter(struct audio_output *ao)
{
const struct audio_format *filter_audio_format;
GError *error = NULL;
ao_filter_close(ao);
filter_audio_format = ao_filter_open(ao, ao->in_audio_format, &error);
if (filter_audio_format == NULL) {
const AudioFormat filter_audio_format =
ao_filter_open(ao, ao->in_audio_format, &error);
if (!filter_audio_format.IsDefined()) {
g_warning("Failed to open filter for \"%s\" [%s]: %s",
ao->name, ao->plugin->name, error->message);
g_error_free(error);
......@@ -268,7 +265,7 @@ ao_reopen_filter(struct audio_output *ao)
static void
ao_reopen(struct audio_output *ao)
{
if (!audio_format_fully_defined(&ao->config_audio_format)) {
if (!ao->config_audio_format.IsFullyDefined()) {
if (ao->open) {
const struct music_pipe *mp = ao->pipe;
ao_close(ao, true);
......@@ -279,8 +276,7 @@ ao_reopen(struct audio_output *ao)
the output's open() method determine the effective
out_audio_format */
ao->out_audio_format = ao->in_audio_format;
audio_format_mask_apply(&ao->out_audio_format,
&ao->config_audio_format);
ao->out_audio_format.ApplyMask(ao->config_audio_format);
}
if (ao->open)
......@@ -327,7 +323,7 @@ ao_chunk_data(struct audio_output *ao, const struct music_chunk *chunk,
(void)ao;
assert(length % audio_format_frame_size(&ao->in_audio_format) == 0);
assert(length % ao->in_audio_format.GetFrameSize() == 0);
if (length > 0 && replay_gain_filter != NULL) {
if (chunk->replay_gain_serial != *replay_gain_serial_p) {
......@@ -399,10 +395,10 @@ ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
void *dest = ao->cross_fade_buffer.Get(other_length);
memcpy(dest, other_data, other_length);
if (!pcm_mix(dest, data, length,
sample_format(ao->in_audio_format.format),
ao->in_audio_format.format,
1.0 - chunk->mix_ratio)) {
g_warning("Cannot cross-fade format %s",
sample_format_to_string(sample_format(ao->in_audio_format.format)));
sample_format_to_string(ao->in_audio_format.format));
return NULL;
}
......@@ -479,7 +475,7 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
}
assert(nbytes <= size);
assert(nbytes % audio_format_frame_size(&ao->out_audio_format) == 0);
assert(nbytes % ao->out_audio_format.GetFrameSize() == 0);
data += nbytes;
size -= nbytes;
......
......@@ -31,7 +31,7 @@
#include "protocol/ArgParser.hxx"
extern "C" {
#include "audio_format.h"
#include "AudioFormat.hxx"
}
#include "replay_gain_config.h"
......@@ -178,12 +178,12 @@ handle_status(Client *client,
player_status.elapsed_time,
player_status.bit_rate);
if (audio_format_defined(&player_status.audio_format)) {
if (player_status.audio_format.IsDefined()) {
struct audio_format_string af_string;
client_printf(client,
COMMAND_STATUS_AUDIO ": %s\n",
audio_format_to_string(&player_status.audio_format,
audio_format_to_string(player_status.audio_format,
&af_string));
}
}
......
......@@ -20,7 +20,7 @@
#ifndef MPD_PLAYER_H
#define MPD_PLAYER_H
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
......@@ -85,7 +85,7 @@ enum player_error {
struct player_status {
enum player_state state;
uint16_t bit_rate;
struct audio_format audio_format;
AudioFormat audio_format;
float total_time;
float elapsed_time;
};
......@@ -130,7 +130,7 @@ struct player_control {
GError *error;
uint16_t bit_rate;
struct audio_format audio_format;
AudioFormat audio_format;
float total_time;
float elapsed_time;
......
......@@ -115,7 +115,7 @@ struct player {
/**
* The current audio format for the audio outputs.
*/
struct audio_format play_audio_format;
AudioFormat play_audio_format;
/**
* The time stamp of the chunk most recently sent to the
......@@ -279,7 +279,7 @@ player_wait_for_decoder(struct player *player)
/* update player_control's song information */
pc->total_time = pc->next_song->GetDuration();
pc->bit_rate = 0;
audio_format_clear(&pc->audio_format);
pc->audio_format.Clear();
/* clear the queued song */
pc->next_song = NULL;
......@@ -323,12 +323,12 @@ player_open_output(struct player *player)
{
struct player_control *pc = player->pc;
assert(audio_format_defined(&player->play_audio_format));
assert(player->play_audio_format.IsDefined());
assert(pc->state == PLAYER_STATE_PLAY ||
pc->state == PLAYER_STATE_PAUSE);
GError *error = NULL;
if (audio_output_all_open(&player->play_audio_format, player_buffer,
if (audio_output_all_open(player->play_audio_format, player_buffer,
&error)) {
player->output_open = true;
player->paused = false;
......@@ -439,7 +439,7 @@ static bool
player_send_silence(struct player *player)
{
assert(player->output_open);
assert(audio_format_defined(&player->play_audio_format));
assert(player->play_audio_format.IsDefined());
struct music_chunk *chunk = music_buffer_allocate(player_buffer);
if (chunk == NULL) {
......@@ -451,8 +451,7 @@ player_send_silence(struct player *player)
chunk->audio_format = player->play_audio_format;
#endif
size_t frame_size =
audio_format_frame_size(&player->play_audio_format);
const size_t frame_size = player->play_audio_format.GetFrameSize();
/* this formula ensures that we don't send
partial frames */
unsigned num_frames = sizeof(chunk->data) / frame_size;
......@@ -597,7 +596,7 @@ static void player_process_command(struct player *player)
pc->Lock();
pc->state = PLAYER_STATE_PAUSE;
} else if (!audio_format_defined(&player->play_audio_format)) {
} else if (!player->play_audio_format.IsDefined()) {
/* the decoder hasn't provided an audio format
yet - don't open the audio device yet */
pc->Lock();
......@@ -689,10 +688,10 @@ update_song_tag(Song *song, const Tag &new_tag)
static bool
play_chunk(struct player_control *pc,
Song *song, struct music_chunk *chunk,
const struct audio_format *format,
const AudioFormat format,
GError **error_r)
{
assert(chunk->CheckFormat(*format));
assert(chunk->CheckFormat(format));
if (chunk->tag != NULL)
update_song_tag(song, *chunk->tag);
......@@ -712,7 +711,7 @@ play_chunk(struct player_control *pc,
return false;
pc->total_play_time += (double)chunk->length /
audio_format_time_to_size(format);
format.GetTimeToSize();
return true;
}
......@@ -825,7 +824,7 @@ play_next_chunk(struct player *player)
GError *error = NULL;
if (!play_chunk(player->pc, player->song, chunk,
&player->play_audio_format, &error)) {
player->play_audio_format, &error)) {
g_warning("%s", error->message);
music_buffer_return(player_buffer, chunk);
......@@ -1019,8 +1018,8 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
dc->replay_gain_prev_db,
dc->mixramp_start,
dc->mixramp_prev_end,
&dc->out_audio_format,
&player.play_audio_format,
dc->out_audio_format,
player.play_audio_format,
music_buffer_size(player_buffer) -
pc->buffered_before_play);
if (player.cross_fade_chunks > 0) {
......
......@@ -19,7 +19,7 @@
#include "config.h"
#include "Timer.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "clock.h"
#include <glib.h>
......@@ -28,10 +28,10 @@
#include <limits.h>
#include <stddef.h>
Timer::Timer(const struct audio_format &af)
Timer::Timer(const AudioFormat af)
: time(0),
started(false),
rate(af.sample_rate * audio_format_frame_size(&af))
rate(af.sample_rate * af.GetFrameSize())
{
}
......
......@@ -22,14 +22,14 @@
#include <stdint.h>
struct audio_format;
struct AudioFormat;
class Timer {
uint64_t time;
bool started;
const int rate;
public:
explicit Timer(const struct audio_format& af);
explicit Timer(AudioFormat af);
bool IsStarted() const { return started; }
......
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_AUDIO_FORMAT_H
#define MPD_AUDIO_FORMAT_H
#include "gcc.h"
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
enum sample_format {
SAMPLE_FORMAT_UNDEFINED = 0,
SAMPLE_FORMAT_S8,
SAMPLE_FORMAT_S16,
/**
* Signed 24 bit integer samples, packed in 32 bit integers
* (the most significant byte is filled with the sign bit).
*/
SAMPLE_FORMAT_S24_P32,
SAMPLE_FORMAT_S32,
/**
* 32 bit floating point samples in the host's format. The
* range is -1.0f to +1.0f.
*/
SAMPLE_FORMAT_FLOAT,
/**
* Direct Stream Digital. 1-bit samples; each frame has one
* byte (8 samples) per channel.
*/
SAMPLE_FORMAT_DSD,
};
static const unsigned MAX_CHANNELS = 8;
/**
* This structure describes the format of a raw PCM stream.
*/
struct audio_format {
/**
* The sample rate in Hz. A better name for this attribute is
* "frame rate", because technically, you have two samples per
* frame in stereo sound.
*/
uint32_t sample_rate;
/**
* The format samples are stored in. See the #sample_format
* enum for valid values.
*/
uint8_t format;
/**
* The number of channels. Only mono (1) and stereo (2) are
* fully supported currently.
*/
uint8_t channels;
};
/**
* Buffer for audio_format_string().
*/
struct audio_format_string {
char buffer[24];
};
/**
* Clears the #audio_format object, i.e. sets all attributes to an
* undefined (invalid) value.
*/
static inline void audio_format_clear(struct audio_format *af)
{
af->sample_rate = 0;
af->format = SAMPLE_FORMAT_UNDEFINED;
af->channels = 0;
}
/**
* Initializes an #audio_format object, i.e. sets all
* attributes to valid values.
*/
static inline void audio_format_init(struct audio_format *af,
uint32_t sample_rate,
enum sample_format format, uint8_t channels)
{
af->sample_rate = sample_rate;
af->format = (uint8_t)format;
af->channels = channels;
}
/**
* Checks whether the specified #audio_format object has a defined
* value.
*/
static inline bool audio_format_defined(const struct audio_format *af)
{
return af->sample_rate != 0;
}
/**
* Checks whether the specified #audio_format object is full, i.e. all
* attributes are defined. This is more complete than
* audio_format_defined(), but slower.
*/
static inline bool
audio_format_fully_defined(const struct audio_format *af)
{
return af->sample_rate != 0 && af->format != SAMPLE_FORMAT_UNDEFINED &&
af->channels != 0;
}
/**
* Checks whether the specified #audio_format object has at least one
* defined value.
*/
static inline bool
audio_format_mask_defined(const struct audio_format *af)
{
return af->sample_rate != 0 || af->format != SAMPLE_FORMAT_UNDEFINED ||
af->channels != 0;
}
/**
* Checks whether the sample rate is valid.
*
* @param sample_rate the sample rate in Hz
*/
static inline bool
audio_valid_sample_rate(unsigned sample_rate)
{
return sample_rate > 0 && sample_rate < (1 << 30);
}
/**
* Checks whether the sample format is valid.
*
* @param bits the number of significant bits per sample
*/
static inline bool
audio_valid_sample_format(enum sample_format format)
{
switch (format) {
case SAMPLE_FORMAT_S8:
case SAMPLE_FORMAT_S16:
case SAMPLE_FORMAT_S24_P32:
case SAMPLE_FORMAT_S32:
case SAMPLE_FORMAT_FLOAT:
case SAMPLE_FORMAT_DSD:
return true;
case SAMPLE_FORMAT_UNDEFINED:
break;
}
return false;
}
/**
* Checks whether the number of channels is valid.
*/
static inline bool
audio_valid_channel_count(unsigned channels)
{
return channels >= 1 && channels <= MAX_CHANNELS;
}
/**
* Returns false if the format is not valid for playback with MPD.
* This function performs some basic validity checks.
*/
gcc_pure
static inline bool audio_format_valid(const struct audio_format *af)
{
return audio_valid_sample_rate(af->sample_rate) &&
audio_valid_sample_format((enum sample_format)af->format) &&
audio_valid_channel_count(af->channels);
}
/**
* Returns false if the format mask is not valid for playback with
* MPD. This function performs some basic validity checks.
*/
gcc_pure
static inline bool audio_format_mask_valid(const struct audio_format *af)
{
return (af->sample_rate == 0 ||
audio_valid_sample_rate(af->sample_rate)) &&
(af->format == SAMPLE_FORMAT_UNDEFINED ||
audio_valid_sample_format((enum sample_format)af->format)) &&
(af->channels == 0 || audio_valid_channel_count(af->channels));
}
static inline bool audio_format_equals(const struct audio_format *a,
const struct audio_format *b)
{
return a->sample_rate == b->sample_rate &&
a->format == b->format &&
a->channels == b->channels;
}
#ifdef __cplusplus
extern "C" {
#endif
void
audio_format_mask_apply(struct audio_format *af,
const struct audio_format *mask);
gcc_const
static inline unsigned
sample_format_size(enum sample_format format)
{
switch (format) {
case SAMPLE_FORMAT_S8:
return 1;
case SAMPLE_FORMAT_S16:
return 2;
case SAMPLE_FORMAT_S24_P32:
case SAMPLE_FORMAT_S32:
case SAMPLE_FORMAT_FLOAT:
return 4;
case SAMPLE_FORMAT_DSD:
/* each frame has 8 samples per channel */
return 1;
case SAMPLE_FORMAT_UNDEFINED:
return 0;
}
assert(false);
gcc_unreachable();
}
/**
* Returns the size of each (mono) sample in bytes.
*/
gcc_pure
static inline unsigned audio_format_sample_size(const struct audio_format *af)
{
return sample_format_size((enum sample_format)af->format);
}
/**
* Returns the size of each full frame in bytes.
*/
gcc_pure
static inline unsigned
audio_format_frame_size(const struct audio_format *af)
{
return audio_format_sample_size(af) * af->channels;
}
/**
* Returns the floating point factor which converts a time span to a
* storage size in bytes.
*/
gcc_pure
static inline double audio_format_time_to_size(const struct audio_format *af)
{
return af->sample_rate * audio_format_frame_size(af);
}
/**
* Renders a #sample_format enum into a string, e.g. for printing it
* in a log file.
*
* @param format a #sample_format enum value
* @return the string
*/
gcc_pure gcc_malloc
const char *
sample_format_to_string(enum sample_format format);
/**
* Renders the #audio_format object into a string, e.g. for printing
* it in a log file.
*
* @param af the #audio_format object
* @param s a buffer to print into
* @return the string, or NULL if the #audio_format object is invalid
*/
gcc_pure gcc_malloc
const char *
audio_format_to_string(const struct audio_format *af,
struct audio_format_string *s);
#ifdef __cplusplus
}
#endif
#endif
......@@ -60,11 +60,10 @@ adplug_file_decode(struct decoder *decoder, const char *path_fs)
if (player == nullptr)
return;
struct audio_format audio_format;
audio_format_init(&audio_format, sample_rate, SAMPLE_FORMAT_S16, 2);
assert(audio_format_valid(&audio_format));
const AudioFormat audio_format(sample_rate, SampleFormat::S16, 2);
assert(audio_format.IsValid());
decoder_initialized(decoder, &audio_format, false,
decoder_initialized(decoder, audio_format, false,
player->songlength() / 1000.);
int16_t buffer[2048];
......
......@@ -114,27 +114,27 @@ setup_virtual_fops(struct input_stream *stream)
return vf;
}
static enum sample_format
static SampleFormat
audiofile_bits_to_sample_format(int bits)
{
switch (bits) {
case 8:
return SAMPLE_FORMAT_S8;
return SampleFormat::S8;
case 16:
return SAMPLE_FORMAT_S16;
return SampleFormat::S16;
case 24:
return SAMPLE_FORMAT_S24_P32;
return SampleFormat::S24_P32;
case 32:
return SAMPLE_FORMAT_S32;
return SampleFormat::S32;
}
return SAMPLE_FORMAT_UNDEFINED;
return SampleFormat::UNDEFINED;
}
static enum sample_format
static SampleFormat
audiofile_setup_sample_format(AFfilehandle af_fp)
{
int fs, bits;
......@@ -160,7 +160,7 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
AFvirtualfile *vf;
int fs, frame_count;
AFfilehandle af_fp;
struct audio_format audio_format;
AudioFormat audio_format;
float total_time;
uint16_t bit_rate;
int ret;
......@@ -180,7 +180,7 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
return;
}
if (!audio_format_init_checked(&audio_format,
if (!audio_format_init_checked(audio_format,
afGetRate(af_fp, AF_DEFAULT_TRACK),
audiofile_setup_sample_format(af_fp),
afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK),
......@@ -199,7 +199,7 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
decoder_initialized(decoder, &audio_format, true, total_time);
decoder_initialized(decoder, audio_format, true, total_time);
do {
ret = afReadFrames(af_fp, AF_DEFAULT_TRACK, chunk,
......
......@@ -433,9 +433,9 @@ dsdiff_stream_decode(struct decoder *decoder, struct input_stream *is)
return;
GError *error = nullptr;
struct audio_format audio_format;
if (!audio_format_init_checked(&audio_format, metadata.sample_rate / 8,
SAMPLE_FORMAT_DSD,
AudioFormat audio_format;
if (!audio_format_init_checked(audio_format, metadata.sample_rate / 8,
SampleFormat::DSD,
metadata.channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
......@@ -448,7 +448,7 @@ dsdiff_stream_decode(struct decoder *decoder, struct input_stream *is)
(float) metadata.sample_rate;
/* success: file was recognized */
decoder_initialized(decoder, &audio_format, false, songtime);
decoder_initialized(decoder, audio_format, false, songtime);
/* every iteration of the following loop decodes one "DSD"
chunk from a DFF file */
......@@ -487,9 +487,9 @@ dsdiff_scan_stream(struct input_stream *is,
if (!dsdiff_read_metadata(nullptr, is, &metadata, &chunk_header))
return false;
struct audio_format audio_format;
if (!audio_format_init_checked(&audio_format, metadata.sample_rate / 8,
SAMPLE_FORMAT_DSD,
AudioFormat audio_format;
if (!audio_format_init_checked(audio_format, metadata.sample_rate / 8,
SampleFormat::DSD,
metadata.channels, nullptr))
/* refuse to parse files which we cannot play anyway */
return false;
......
......@@ -285,9 +285,9 @@ dsf_stream_decode(struct decoder *decoder, struct input_stream *is)
return;
GError *error = NULL;
struct audio_format audio_format;
if (!audio_format_init_checked(&audio_format, metadata.sample_rate / 8,
SAMPLE_FORMAT_DSD,
AudioFormat audio_format;
if (!audio_format_init_checked(audio_format, metadata.sample_rate / 8,
SampleFormat::DSD,
metadata.channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
......@@ -299,7 +299,7 @@ dsf_stream_decode(struct decoder *decoder, struct input_stream *is)
(float) metadata.sample_rate;
/* success: file was recognized */
decoder_initialized(decoder, &audio_format, false, songtime);
decoder_initialized(decoder, audio_format, false, songtime);
if (!dsf_decode_chunk(decoder, is, metadata.channels,
chunk_size,
......@@ -317,9 +317,9 @@ dsf_scan_stream(struct input_stream *is,
if (!dsf_read_metadata(NULL, is, &metadata))
return false;
struct audio_format audio_format;
if (!audio_format_init_checked(&audio_format, metadata.sample_rate / 8,
SAMPLE_FORMAT_DSD,
AudioFormat audio_format;
if (!audio_format_init_checked(audio_format, metadata.sample_rate / 8,
SampleFormat::DSD,
metadata.channels, NULL))
/* refuse to parse files which we cannot play anyway */
return false;
......
......@@ -248,7 +248,7 @@ faad_song_duration(DecoderBuffer *buffer, struct input_stream *is)
*/
static bool
faad_decoder_init(NeAACDecHandle decoder, DecoderBuffer *buffer,
struct audio_format *audio_format, GError **error_r)
AudioFormat &audio_format, GError **error_r)
{
int32_t nbytes;
uint32_t sample_rate;
......@@ -285,7 +285,7 @@ faad_decoder_init(NeAACDecHandle decoder, DecoderBuffer *buffer,
decoder_buffer_consume(buffer, nbytes);
return audio_format_init_checked(audio_format, sample_rate,
SAMPLE_FORMAT_S16, channels, error_r);
SampleFormat::S16, channels, error_r);
}
/**
......@@ -325,7 +325,7 @@ faad_get_file_time_float(struct input_stream *is)
if (length < 0) {
bool ret;
struct audio_format audio_format;
AudioFormat audio_format;
NeAACDecHandle decoder = NeAACDecOpen();
......@@ -336,7 +336,7 @@ faad_get_file_time_float(struct input_stream *is)
decoder_buffer_fill(buffer);
ret = faad_decoder_init(decoder, buffer, &audio_format, nullptr);
ret = faad_decoder_init(decoder, buffer, audio_format, nullptr);
if (ret)
length = 0;
......@@ -370,7 +370,7 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
{
GError *error = nullptr;
float total_time = 0;
struct audio_format audio_format;
AudioFormat audio_format;
bool ret;
uint16_t bit_rate = 0;
DecoderBuffer *buffer;
......@@ -400,7 +400,7 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
/* initialize it */
ret = faad_decoder_init(decoder, buffer, &audio_format, &error);
ret = faad_decoder_init(decoder, buffer, audio_format, &error);
if (!ret) {
g_warning("%s", error->message);
g_error_free(error);
......@@ -410,7 +410,7 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
/* initialize the MPD core */
decoder_initialized(mpd_decoder, &audio_format, false, total_time);
decoder_initialized(mpd_decoder, audio_format, false, total_time);
/* the decoder loop */
......
......@@ -52,6 +52,11 @@ extern "C" {
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "ffmpeg"
/* suppress the ffmpeg compatibility macro */
#ifdef SampleFormat
#undef SampleFormat
#endif
static GLogLevelFlags
level_ffmpeg_to_glib(int level)
{
......@@ -297,20 +302,20 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
}
G_GNUC_CONST
static enum sample_format
static SampleFormat
ffmpeg_sample_format(enum AVSampleFormat sample_fmt)
{
switch (sample_fmt) {
case AV_SAMPLE_FMT_S16:
case AV_SAMPLE_FMT_S16P:
return SAMPLE_FORMAT_S16;
return SampleFormat::S16;
case AV_SAMPLE_FMT_S32:
case AV_SAMPLE_FMT_S32P:
return SAMPLE_FORMAT_S32;
return SampleFormat::S32;
case AV_SAMPLE_FMT_FLTP:
return SAMPLE_FORMAT_FLOAT;
return SampleFormat::FLOAT;
default:
break;
......@@ -325,7 +330,7 @@ ffmpeg_sample_format(enum AVSampleFormat sample_fmt)
else
g_warning("Unsupported libavcodec SampleFormat value: %d",
sample_fmt);
return SAMPLE_FORMAT_UNDEFINED;
return SampleFormat::UNDEFINED;
}
static AVInputFormat *
......@@ -420,14 +425,14 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
return;
}
const enum sample_format sample_format =
const SampleFormat sample_format =
ffmpeg_sample_format(codec_context->sample_fmt);
if (sample_format == SAMPLE_FORMAT_UNDEFINED)
if (sample_format == SampleFormat::UNDEFINED)
return;
GError *error = NULL;
struct audio_format audio_format;
if (!audio_format_init_checked(&audio_format,
AudioFormat audio_format;
if (!audio_format_init_checked(audio_format,
codec_context->sample_rate,
sample_format,
codec_context->channels, &error)) {
......@@ -455,7 +460,7 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
? format_context->duration / AV_TIME_BASE
: 0;
decoder_initialized(decoder, &audio_format,
decoder_initialized(decoder, audio_format,
input->seekable, total_time);
AVFrame *frame = avcodec_alloc_frame();
......
......@@ -26,6 +26,11 @@ extern "C" {
#include <libavutil/dict.h>
}
/* suppress the ffmpeg compatibility macro */
#ifdef SampleFormat
#undef SampleFormat
#endif
struct tag_handler;
void
......
......@@ -40,24 +40,24 @@ flac_data::flac_data(struct decoder *_decoder,
{
}
static enum sample_format
static SampleFormat
flac_sample_format(unsigned bits_per_sample)
{
switch (bits_per_sample) {
case 8:
return SAMPLE_FORMAT_S8;
return SampleFormat::S8;
case 16:
return SAMPLE_FORMAT_S16;
return SampleFormat::S16;
case 24:
return SAMPLE_FORMAT_S24_P32;
return SampleFormat::S24_P32;
case 32:
return SAMPLE_FORMAT_S32;
return SampleFormat::S32;
default:
return SAMPLE_FORMAT_UNDEFINED;
return SampleFormat::UNDEFINED;
}
}
......@@ -69,7 +69,7 @@ flac_got_stream_info(struct flac_data *data,
return;
GError *error = nullptr;
if (!audio_format_init_checked(&data->audio_format,
if (!audio_format_init_checked(data->audio_format,
stream_info->sample_rate,
flac_sample_format(stream_info->bits_per_sample),
stream_info->channels, &error)) {
......@@ -79,7 +79,7 @@ flac_got_stream_info(struct flac_data *data,
return;
}
data->frame_size = audio_format_frame_size(&data->audio_format);
data->frame_size = data->audio_format.GetFrameSize();
if (data->total_frames == 0)
data->total_frames = stream_info->total_samples;
......@@ -132,7 +132,7 @@ flac_got_first_frame(struct flac_data *data, const FLAC__FrameHeader *header)
return false;
GError *error = nullptr;
if (!audio_format_init_checked(&data->audio_format,
if (!audio_format_init_checked(data->audio_format,
header->sample_rate,
flac_sample_format(header->bits_per_sample),
header->channels, &error)) {
......@@ -142,9 +142,9 @@ flac_got_first_frame(struct flac_data *data, const FLAC__FrameHeader *header)
return false;
}
data->frame_size = audio_format_frame_size(&data->audio_format);
data->frame_size = data->audio_format.GetFrameSize();
decoder_initialized(data->decoder, &data->audio_format,
decoder_initialized(data->decoder, data->audio_format,
data->input_stream->seekable,
(float)data->total_frames /
(float)data->audio_format.sample_rate);
......@@ -170,7 +170,7 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
buffer = data->buffer.Get(buffer_size);
flac_convert(buffer, frame->header.channels,
(enum sample_format)data->audio_format.format, buf,
data->audio_format.format, buf,
0, frame->header.blocksize);
if (nbytes > 0)
......
......@@ -56,7 +56,7 @@ struct flac_data : public FlacInput {
* The validated audio format of the FLAC file. This
* attribute is defined if "initialized" is true.
*/
struct audio_format audio_format;
AudioFormat audio_format;
/**
* The total number of frames in this song. The decoder
......
......@@ -144,7 +144,7 @@ flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
if (data->initialized) {
/* done */
decoder_initialized(data->decoder, &data->audio_format,
decoder_initialized(data->decoder, data->audio_format,
data->input_stream->seekable,
(float)data->total_frames /
(float)data->audio_format.sample_rate);
......
......@@ -76,12 +76,12 @@ flac_convert_8(int8_t *dest,
void
flac_convert(void *dest,
unsigned int num_channels, enum sample_format sample_format,
unsigned int num_channels, SampleFormat sample_format,
const FLAC__int32 *const buf[],
unsigned int position, unsigned int end)
{
switch (sample_format) {
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
if (num_channels == 2)
flac_convert_stereo16((int16_t*)dest, buf,
position, end);
......@@ -90,20 +90,20 @@ flac_convert(void *dest,
position, end);
break;
case SAMPLE_FORMAT_S24_P32:
case SAMPLE_FORMAT_S32:
case SampleFormat::S24_P32:
case SampleFormat::S32:
flac_convert_32((int32_t*)dest, num_channels, buf,
position, end);
break;
case SAMPLE_FORMAT_S8:
case SampleFormat::S8:
flac_convert_8((int8_t*)dest, num_channels, buf,
position, end);
break;
case SAMPLE_FORMAT_FLOAT:
case SAMPLE_FORMAT_DSD:
case SAMPLE_FORMAT_UNDEFINED:
case SampleFormat::FLOAT:
case SampleFormat::DSD:
case SampleFormat::UNDEFINED:
assert(false);
gcc_unreachable();
}
......
......@@ -20,13 +20,13 @@
#ifndef MPD_FLAC_PCM_HXX
#define MPD_FLAC_PCM_HXX
#include "audio_format.h"
#include "AudioFormat.hxx"
#include <FLAC/ordinals.h>
void
flac_convert(void *dest,
unsigned int num_channels, enum sample_format sample_format,
unsigned int num_channels, SampleFormat sample_format,
const FLAC__int32 *const buf[],
unsigned int position, unsigned int end);
......
......@@ -166,9 +166,8 @@ fluidsynth_file_decode(struct decoder *decoder, const char *path_fs)
/* initialization complete - announce the audio format to the
MPD core */
struct audio_format audio_format;
audio_format_init(&audio_format, sample_rate, SAMPLE_FORMAT_S16, 2);
decoder_initialized(decoder, &audio_format, false, -1);
const AudioFormat audio_format(sample_rate, SampleFormat::S16, 2);
decoder_initialized(decoder, audio_format, false, -1);
while (fluid_player_get_status(player) == FLUID_PLAYER_PLAYING) {
int16_t buffer[2048];
......
......@@ -153,9 +153,9 @@ gme_file_decode(struct decoder *decoder, const char *path_fs)
/* initialize the MPD decoder */
GError *error = nullptr;
struct audio_format audio_format;
if (!audio_format_init_checked(&audio_format, GME_SAMPLE_RATE,
SAMPLE_FORMAT_S16, GME_CHANNELS,
AudioFormat audio_format;
if (!audio_format_init_checked(audio_format, GME_SAMPLE_RATE,
SampleFormat::S16, GME_CHANNELS,
&error)) {
g_warning("%s", error->message);
g_error_free(error);
......@@ -164,7 +164,7 @@ gme_file_decode(struct decoder *decoder, const char *path_fs)
return;
}
decoder_initialized(decoder, &audio_format, true, song_len);
decoder_initialized(decoder, audio_format, true, song_len);
gme_err = gme_start_track(emu, song_num);
if (gme_err != nullptr)
......
......@@ -1124,11 +1124,11 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
return;
}
struct audio_format audio_format;
AudioFormat audio_format;
GError *error = nullptr;
if (!audio_format_init_checked(&audio_format,
if (!audio_format_init_checked(audio_format,
data.frame.header.samplerate,
SAMPLE_FORMAT_S24_P32,
SampleFormat::S24_P32,
MAD_NCHANNELS(&data.frame.header),
&error)) {
g_warning("%s", error->message);
......@@ -1138,7 +1138,7 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
return;
}
decoder_initialized(decoder, &audio_format,
decoder_initialized(decoder, audio_format,
input_stream_is_seekable(input_stream),
data.total_time);
......
......@@ -147,7 +147,6 @@ mikmod_decoder_file_decode(struct decoder *decoder, const char *path_fs)
{
char *path2;
MODULE *handle;
struct audio_format audio_format;
int ret;
SBYTE buffer[MIKMOD_FRAME_SIZE];
enum decoder_command cmd = DECODE_COMMAND_NONE;
......@@ -164,10 +163,10 @@ mikmod_decoder_file_decode(struct decoder *decoder, const char *path_fs)
/* Prevent module from looping forever */
handle->loop = 0;
audio_format_init(&audio_format, mikmod_sample_rate, SAMPLE_FORMAT_S16, 2);
assert(audio_format_valid(&audio_format));
const AudioFormat audio_format(mikmod_sample_rate, SampleFormat::S16, 2);
assert(audio_format.IsValid());
decoder_initialized(decoder, &audio_format, false, 0);
decoder_initialized(decoder, audio_format, false, 0);
Player_Start(handle);
while (cmd == DECODE_COMMAND_NONE && Player_Active()) {
......
......@@ -94,7 +94,6 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
ModPlugFile *f;
ModPlug_Settings settings;
GByteArray *bdatas;
struct audio_format audio_format;
int ret;
char audio_buffer[MODPLUG_FRAME_SIZE];
enum decoder_command cmd = DECODE_COMMAND_NONE;
......@@ -122,10 +121,10 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
return;
}
audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2);
assert(audio_format_valid(&audio_format));
static constexpr AudioFormat audio_format(44100, SampleFormat::S16, 2);
assert(audio_format.IsValid());
decoder_initialized(decoder, &audio_format,
decoder_initialized(decoder, audio_format,
input_stream_is_seekable(is),
ModPlug_GetLength(f) / 1000.0);
......
......@@ -154,9 +154,9 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
mpc_demux_get_info(demux, &info);
GError *error = nullptr;
struct audio_format audio_format;
if (!audio_format_init_checked(&audio_format, info.sample_freq,
SAMPLE_FORMAT_S24_P32,
AudioFormat audio_format;
if (!audio_format_init_checked(audio_format, info.sample_freq,
SampleFormat::S24_P32,
info.channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
......@@ -173,7 +173,7 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
decoder_replay_gain(mpd_decoder, &replay_gain_info);
decoder_initialized(mpd_decoder, &audio_format,
decoder_initialized(mpd_decoder, audio_format,
input_stream_is_seekable(is),
mpc_streaminfo_get_length(&info));
......
......@@ -56,7 +56,7 @@ mpd_mpg123_finish(void)
*/
static bool
mpd_mpg123_open(mpg123_handle *handle, const char *path_fs,
struct audio_format *audio_format)
AudioFormat &audio_format)
{
GError *gerror = nullptr;
char *path_dup;
......@@ -90,7 +90,7 @@ mpd_mpg123_open(mpg123_handle *handle, const char *path_fs,
return false;
}
if (!audio_format_init_checked(audio_format, rate, SAMPLE_FORMAT_S16,
if (!audio_format_init_checked(audio_format, rate, SampleFormat::S16,
channels, &gerror)) {
g_warning("%s", gerror->message);
g_error_free(gerror);
......@@ -103,7 +103,6 @@ mpd_mpg123_open(mpg123_handle *handle, const char *path_fs,
static void
mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
{
struct audio_format audio_format;
mpg123_handle *handle;
int error;
off_t num_samples;
......@@ -119,7 +118,8 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
return;
}
if (!mpd_mpg123_open(handle, path_fs, &audio_format)) {
AudioFormat audio_format;
if (!mpd_mpg123_open(handle, path_fs, audio_format)) {
mpg123_delete(handle);
return;
}
......@@ -128,7 +128,7 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
/* tell MPD core we're ready */
decoder_initialized(decoder, &audio_format, true,
decoder_initialized(decoder, audio_format, true,
(float)num_samples /
(float)audio_format.sample_rate);
......@@ -198,7 +198,6 @@ static bool
mpd_mpg123_scan_file(const char *path_fs,
const struct tag_handler *handler, void *handler_ctx)
{
struct audio_format audio_format;
mpg123_handle *handle;
int error;
off_t num_samples;
......@@ -210,7 +209,8 @@ mpd_mpg123_scan_file(const char *path_fs,
return false;
}
if (!mpd_mpg123_open(handle, path_fs, &audio_format)) {
AudioFormat audio_format;
if (!mpd_mpg123_open(handle, path_fs, audio_format)) {
mpg123_delete(handle);
return false;
}
......
......@@ -202,11 +202,10 @@ MPDOpusDecoder::HandleBOS(const ogg_packet &packet)
return DECODE_COMMAND_STOP;
}
struct audio_format audio_format;
audio_format_init(&audio_format, opus_sample_rate,
SAMPLE_FORMAT_S16, channels);
decoder_initialized(decoder, &audio_format, false, -1);
frame_size = audio_format_frame_size(&audio_format);
const AudioFormat audio_format(opus_sample_rate,
SampleFormat::S16, channels);
decoder_initialized(decoder, audio_format, false, -1);
frame_size = audio_format.GetFrameSize();
/* allocate an output buffer for 16 bit PCM samples big enough
to hold a quarter second, larger than 120ms required by
......
......@@ -36,9 +36,9 @@ extern "C" {
static void
pcm_stream_decode(struct decoder *decoder, struct input_stream *is)
{
static constexpr struct audio_format audio_format = {
static constexpr AudioFormat audio_format = {
44100,
SAMPLE_FORMAT_S16,
SampleFormat::S16,
2,
};
......@@ -49,14 +49,14 @@ pcm_stream_decode(struct decoder *decoder, struct input_stream *is)
GError *error = nullptr;
enum decoder_command cmd;
double time_to_size = audio_format_time_to_size(&audio_format);
const double time_to_size = audio_format.GetTimeToSize();
float total_time = -1;
const goffset size = input_stream_get_size(is);
if (size >= 0)
total_time = size / time_to_size;
decoder_initialized(decoder, &audio_format,
decoder_initialized(decoder, audio_format,
input_stream_is_seekable(is), total_time);
do {
......
......@@ -99,7 +99,7 @@ static SF_VIRTUAL_IO vio = {
* Converts a frame number to a timestamp (in seconds).
*/
static float
frame_to_time(sf_count_t frame, const struct audio_format *audio_format)
frame_to_time(sf_count_t frame, const AudioFormat *audio_format)
{
return (float)frame / (float)audio_format->sample_rate;
}
......@@ -108,7 +108,7 @@ frame_to_time(sf_count_t frame, const struct audio_format *audio_format)
* Converts a timestamp (in seconds) to a frame number.
*/
static sf_count_t
time_to_frame(float t, const struct audio_format *audio_format)
time_to_frame(float t, const AudioFormat *audio_format)
{
return (sf_count_t)(t * audio_format->sample_rate);
}
......@@ -119,7 +119,6 @@ sndfile_stream_decode(struct decoder *decoder, struct input_stream *is)
GError *error = nullptr;
SNDFILE *sf;
SF_INFO info;
struct audio_format audio_format;
size_t frame_size;
sf_count_t read_frames, num_frames;
int buffer[4096];
......@@ -136,18 +135,19 @@ sndfile_stream_decode(struct decoder *decoder, struct input_stream *is)
/* for now, always read 32 bit samples. Later, we could lower
MPD's CPU usage by reading 16 bit samples with
sf_readf_short() on low-quality source files. */
if (!audio_format_init_checked(&audio_format, info.samplerate,
SAMPLE_FORMAT_S32,
AudioFormat audio_format;
if (!audio_format_init_checked(audio_format, info.samplerate,
SampleFormat::S32,
info.channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
return;
}
decoder_initialized(decoder, &audio_format, info.seekable,
decoder_initialized(decoder, audio_format, info.seekable,
frame_to_time(info.frames, &audio_format));
frame_size = audio_format_frame_size(&audio_format);
frame_size = audio_format.GetFrameSize();
read_frames = sizeof(buffer) / frame_size;
do {
......
......@@ -202,12 +202,12 @@ vorbis_stream_decode(struct decoder *decoder,
return;
}
struct audio_format audio_format;
if (!audio_format_init_checked(&audio_format, vi->rate,
AudioFormat audio_format;
if (!audio_format_init_checked(audio_format, vi->rate,
#ifdef HAVE_TREMOR
SAMPLE_FORMAT_S16,
SampleFormat::S16,
#else
SAMPLE_FORMAT_FLOAT,
SampleFormat::FLOAT,
#endif
vi->channels, &error)) {
g_warning("%s", error->message);
......@@ -219,7 +219,7 @@ vorbis_stream_decode(struct decoder *decoder,
if (total_time < 0)
total_time = 0;
decoder_initialized(decoder, &audio_format, vis.seekable, total_time);
decoder_initialized(decoder, audio_format, vis.seekable, total_time);
enum decoder_command cmd = decoder_get_command(decoder);
......
......@@ -106,27 +106,27 @@ format_samples_float(G_GNUC_UNUSED int bytes_per_sample, void *buffer,
/**
* Choose a MPD sample format from libwavpacks' number of bits.
*/
static enum sample_format
static SampleFormat
wavpack_bits_to_sample_format(bool is_float, int bytes_per_sample)
{
if (is_float)
return SAMPLE_FORMAT_FLOAT;
return SampleFormat::FLOAT;
switch (bytes_per_sample) {
case 1:
return SAMPLE_FORMAT_S8;
return SampleFormat::S8;
case 2:
return SAMPLE_FORMAT_S16;
return SampleFormat::S16;
case 3:
return SAMPLE_FORMAT_S24_P32;
return SampleFormat::S24_P32;
case 4:
return SAMPLE_FORMAT_S32;
return SampleFormat::S32;
default:
return SAMPLE_FORMAT_UNDEFINED;
return SampleFormat::UNDEFINED;
}
}
......@@ -139,8 +139,8 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
{
GError *error = NULL;
bool is_float;
enum sample_format sample_format;
struct audio_format audio_format;
SampleFormat sample_format;
AudioFormat audio_format;
format_samples_t format_samples;
float total_time;
int bytes_per_sample, output_sample_size;
......@@ -150,7 +150,7 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
wavpack_bits_to_sample_format(is_float,
WavpackGetBytesPerSample(wpc));
if (!audio_format_init_checked(&audio_format,
if (!audio_format_init_checked(audio_format,
WavpackGetSampleRate(wpc),
sample_format,
WavpackGetNumChannels(wpc), &error)) {
......@@ -168,14 +168,14 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
total_time = WavpackGetNumSamples(wpc);
total_time /= audio_format.sample_rate;
bytes_per_sample = WavpackGetBytesPerSample(wpc);
output_sample_size = audio_format_frame_size(&audio_format);
output_sample_size = audio_format.GetFrameSize();
/* wavpack gives us all kind of samples in a 32-bit space */
int32_t chunk[1024];
const uint32_t samples_requested = G_N_ELEMENTS(chunk) /
audio_format.channels;
decoder_initialized(decoder, &audio_format, can_seek, total_time);
decoder_initialized(decoder, audio_format, can_seek, total_time);
enum decoder_command cmd = decoder_get_command(decoder);
while (cmd != DECODE_COMMAND_STOP) {
......
......@@ -60,9 +60,9 @@ wildmidi_finish(void)
static void
wildmidi_file_decode(struct decoder *decoder, const char *path_fs)
{
static const struct audio_format audio_format = {
static constexpr AudioFormat audio_format = {
WILDMIDI_SAMPLE_RATE,
SAMPLE_FORMAT_S16,
SampleFormat::S16,
2,
};
midi *wm;
......@@ -79,7 +79,7 @@ wildmidi_file_decode(struct decoder *decoder, const char *path_fs)
return;
}
decoder_initialized(decoder, &audio_format, true,
decoder_initialized(decoder, audio_format, true,
info->approx_total_samples / WILDMIDI_SAMPLE_RATE);
do {
......
......@@ -285,11 +285,10 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
/* initialize the MPD decoder */
struct audio_format audio_format;
audio_format_init(&audio_format, 48000, SAMPLE_FORMAT_S16, channels);
assert(audio_format_valid(&audio_format));
const AudioFormat audio_format(48000, SampleFormat::S16, channels);
assert(audio_format.IsValid());
decoder_initialized(decoder, &audio_format, true, (float)song_len);
decoder_initialized(decoder, audio_format, true, (float)song_len);
/* .. and play */
......
......@@ -20,7 +20,7 @@
#include "config.h"
#include "FlacEncoderPlugin.hxx"
#include "EncoderAPI.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "pcm/PcmBuffer.hxx"
#include "util/fifo_buffer.h"
......@@ -40,7 +40,7 @@ extern "C" {
struct flac_encoder {
Encoder encoder;
struct audio_format audio_format;
AudioFormat audio_format;
unsigned compression;
FLAC__StreamEncoder *fse;
......@@ -160,31 +160,31 @@ flac_encoder_close(Encoder *_encoder)
}
static bool
flac_encoder_open(Encoder *_encoder, struct audio_format *audio_format,
flac_encoder_open(Encoder *_encoder, AudioFormat &audio_format,
GError **error)
{
struct flac_encoder *encoder = (struct flac_encoder *)_encoder;
unsigned bits_per_sample;
encoder->audio_format = *audio_format;
encoder->audio_format = audio_format;
/* FIXME: flac should support 32bit as well */
switch (audio_format->format) {
case SAMPLE_FORMAT_S8:
switch (audio_format.format) {
case SampleFormat::S8:
bits_per_sample = 8;
break;
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
bits_per_sample = 16;
break;
case SAMPLE_FORMAT_S24_P32:
case SampleFormat::S24_P32:
bits_per_sample = 24;
break;
default:
bits_per_sample = 24;
audio_format->format = SAMPLE_FORMAT_S24_P32;
audio_format.format = SampleFormat::S24_P32;
}
/* allocate the encoder */
......@@ -263,30 +263,33 @@ flac_encoder_write(Encoder *_encoder,
/* format conversion */
num_frames = length / audio_format_frame_size(&encoder->audio_format);
num_frames = length / encoder->audio_format.GetFrameSize();
num_samples = num_frames * encoder->audio_format.channels;
switch (encoder->audio_format.format) {
case SAMPLE_FORMAT_S8:
case SampleFormat::S8:
exbuffer = encoder->expand_buffer.Get(length * 4);
pcm8_to_flac((int32_t *)exbuffer, (const int8_t *)data,
num_samples);
buffer = exbuffer;
break;
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
exbuffer = encoder->expand_buffer.Get(length * 2);
pcm16_to_flac((int32_t *)exbuffer, (const int16_t *)data,
num_samples);
buffer = exbuffer;
break;
case SAMPLE_FORMAT_S24_P32:
case SAMPLE_FORMAT_S32:
case SampleFormat::S24_P32:
case SampleFormat::S32:
/* nothing need to be done; format is the same for
both mpd and libFLAC */
buffer = data;
break;
default:
gcc_unreachable();
}
/* feed samples to encoder */
......
......@@ -20,7 +20,7 @@
#include "config.h"
#include "LameEncoderPlugin.hxx"
#include "EncoderAPI.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include <lame/lame.h>
......@@ -32,7 +32,7 @@
struct LameEncoder final {
Encoder encoder;
struct audio_format audio_format;
AudioFormat audio_format;
float quality;
int bitrate;
......@@ -187,15 +187,15 @@ lame_encoder_setup(LameEncoder *encoder, GError **error)
}
static bool
lame_encoder_open(Encoder *_encoder, struct audio_format *audio_format,
lame_encoder_open(Encoder *_encoder, AudioFormat &audio_format,
GError **error)
{
LameEncoder *encoder = (LameEncoder *)_encoder;
audio_format->format = SAMPLE_FORMAT_S16;
audio_format->channels = 2;
audio_format.format = SampleFormat::S16;
audio_format.channels = 2;
encoder->audio_format = *audio_format;
encoder->audio_format = audio_format;
encoder->gfp = lame_init();
if (encoder->gfp == nullptr) {
......@@ -233,7 +233,7 @@ lame_encoder_write(Encoder *_encoder,
assert(encoder->buffer_length == 0);
const unsigned num_frames =
length / audio_format_frame_size(&encoder->audio_format);
length / encoder->audio_format.GetFrameSize();
float *left = g_new(float, num_frames);
float *right = g_new(float, num_frames);
......
......@@ -66,7 +66,7 @@ null_encoder_close(Encoder *_encoder)
static bool
null_encoder_open(Encoder *_encoder,
gcc_unused struct audio_format *audio_format,
gcc_unused AudioFormat &audio_format,
gcc_unused GError **error)
{
NullEncoder *encoder = (NullEncoder *)_encoder;
......
......@@ -21,7 +21,7 @@
#include "OpusEncoderPlugin.hxx"
#include "OggStream.hxx"
#include "EncoderAPI.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "mpd_error.h"
#include <opus.h>
......@@ -44,7 +44,7 @@ struct opus_encoder {
/* runtime information */
struct audio_format audio_format;
AudioFormat audio_format;
size_t frame_size;
......@@ -144,37 +144,37 @@ opus_encoder_finish(Encoder *_encoder)
static bool
opus_encoder_open(Encoder *_encoder,
struct audio_format *audio_format,
AudioFormat &audio_format,
GError **error_r)
{
struct opus_encoder *encoder = (struct opus_encoder *)_encoder;
/* libopus supports only 48 kHz */
audio_format->sample_rate = 48000;
audio_format.sample_rate = 48000;
if (audio_format->channels > 2)
audio_format->channels = 1;
if (audio_format.channels > 2)
audio_format.channels = 1;
switch ((enum sample_format)audio_format->format) {
case SAMPLE_FORMAT_S16:
case SAMPLE_FORMAT_FLOAT:
switch (audio_format.format) {
case SampleFormat::S16:
case SampleFormat::FLOAT:
break;
case SAMPLE_FORMAT_S8:
audio_format->format = SAMPLE_FORMAT_S16;
case SampleFormat::S8:
audio_format.format = SampleFormat::S16;
break;
default:
audio_format->format = SAMPLE_FORMAT_FLOAT;
audio_format.format = SampleFormat::FLOAT;
break;
}
encoder->audio_format = *audio_format;
encoder->frame_size = audio_format_frame_size(audio_format);
encoder->audio_format = audio_format;
encoder->frame_size = audio_format.GetFrameSize();
int error;
encoder->enc = opus_encoder_create(audio_format->sample_rate,
audio_format->channels,
encoder->enc = opus_encoder_create(audio_format.sample_rate,
audio_format.channels,
OPUS_APPLICATION_AUDIO,
&error);
if (encoder->enc == nullptr) {
......@@ -190,7 +190,7 @@ opus_encoder_open(Encoder *_encoder,
opus_encoder_ctl(encoder->enc, OPUS_GET_LOOKAHEAD(&encoder->lookahead));
encoder->buffer_frames = audio_format->sample_rate / 50;
encoder->buffer_frames = audio_format.sample_rate / 50;
encoder->buffer_size = encoder->frame_size * encoder->buffer_frames;
encoder->buffer_position = 0;
encoder->buffer = (unsigned char *)g_malloc(encoder->buffer_size);
......@@ -218,7 +218,7 @@ opus_encoder_do_encode(struct opus_encoder *encoder, bool eos,
assert(encoder->buffer_position == encoder->buffer_size);
opus_int32 result =
encoder->audio_format.format == SAMPLE_FORMAT_S16
encoder->audio_format.format == SampleFormat::S16
? opus_encode(encoder->enc,
(const opus_int16 *)encoder->buffer,
encoder->buffer_frames,
......
......@@ -20,7 +20,7 @@
#include "config.h"
#include "TwolameEncoderPlugin.hxx"
#include "EncoderAPI.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include <twolame.h>
......@@ -32,7 +32,7 @@
struct TwolameEncoder final {
Encoder encoder;
struct audio_format audio_format;
AudioFormat audio_format;
float quality;
int bitrate;
......@@ -187,15 +187,15 @@ twolame_encoder_setup(TwolameEncoder *encoder, GError **error)
}
static bool
twolame_encoder_open(Encoder *_encoder, struct audio_format *audio_format,
twolame_encoder_open(Encoder *_encoder, AudioFormat &audio_format,
GError **error)
{
TwolameEncoder *encoder = (TwolameEncoder *)_encoder;
audio_format->format = SAMPLE_FORMAT_S16;
audio_format->channels = 2;
audio_format.format = SampleFormat::S16;
audio_format.channels = 2;
encoder->audio_format = *audio_format;
encoder->audio_format = audio_format;
encoder->options = twolame_init();
if (encoder->options == nullptr) {
......@@ -243,7 +243,7 @@ twolame_encoder_write(Encoder *_encoder,
assert(encoder->buffer_length == 0);
const unsigned num_frames =
length / audio_format_frame_size(&encoder->audio_format);
length / encoder->audio_format.GetFrameSize();
int bytes_out = twolame_encode_buffer_interleaved(encoder->options,
src, num_frames,
......
......@@ -22,7 +22,7 @@
#include "OggStream.hxx"
#include "EncoderAPI.hxx"
#include "Tag.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "mpd_error.h"
#include <vorbis/vorbisenc.h>
......@@ -43,7 +43,7 @@ struct vorbis_encoder {
/* runtime information */
struct audio_format audio_format;
AudioFormat audio_format;
vorbis_dsp_state vd;
vorbis_block vb;
......@@ -202,14 +202,14 @@ vorbis_encoder_send_header(struct vorbis_encoder *encoder)
static bool
vorbis_encoder_open(Encoder *_encoder,
struct audio_format *audio_format,
AudioFormat &audio_format,
GError **error)
{
struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder;
audio_format->format = SAMPLE_FORMAT_FLOAT;
audio_format.format = SampleFormat::FLOAT;
encoder->audio_format = *audio_format;
encoder->audio_format = audio_format;
if (!vorbis_encoder_reinit(encoder, error))
return false;
......@@ -328,8 +328,7 @@ vorbis_encoder_write(Encoder *_encoder,
{
struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder;
unsigned num_frames = length
/ audio_format_frame_size(&encoder->audio_format);
unsigned num_frames = length / encoder->audio_format.GetFrameSize();
/* this is for only 16-bit audio */
......
......@@ -100,32 +100,32 @@ wave_encoder_finish(Encoder *_encoder)
static bool
wave_encoder_open(Encoder *_encoder,
gcc_unused struct audio_format *audio_format,
AudioFormat &audio_format,
gcc_unused GError **error)
{
WaveEncoder *encoder = (WaveEncoder *)_encoder;
assert(audio_format_valid(audio_format));
assert(audio_format.IsValid());
switch (audio_format->format) {
case SAMPLE_FORMAT_S8:
switch (audio_format.format) {
case SampleFormat::S8:
encoder->bits = 8;
break;
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
encoder->bits = 16;
break;
case SAMPLE_FORMAT_S24_P32:
case SampleFormat::S24_P32:
encoder->bits = 24;
break;
case SAMPLE_FORMAT_S32:
case SampleFormat::S32:
encoder->bits = 32;
break;
default:
audio_format->format = SAMPLE_FORMAT_S16;
audio_format.format = SampleFormat::S16;
encoder->bits = 16;
break;
}
......@@ -136,10 +136,10 @@ wave_encoder_open(Encoder *_encoder,
/* create PCM wave header in initial buffer */
fill_wave_header(header,
audio_format->channels,
audio_format.channels,
encoder->bits,
audio_format->sample_rate,
(encoder->bits / 8) * audio_format->channels );
audio_format.sample_rate,
(encoder->bits / 8) * audio_format.channels);
fifo_buffer_append(encoder->buffer, sizeof(*header));
return true;
......
......@@ -23,19 +23,12 @@
#include "FilterPlugin.hxx"
#include "FilterInternal.hxx"
#include "FilterRegistry.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include <assert.h>
class AutoConvertFilter final : public Filter {
/**
* The audio format being fed to the underlying filter. This
* plugin actually doesn't need this variable, we have it here
* just so our open() method doesn't return a stack pointer.
*/
audio_format child_audio_format;
/**
* The underlying filter.
*/
Filter *filter;
......@@ -52,46 +45,45 @@ public:
delete filter;
}
virtual const audio_format *Open(audio_format &af, GError **error_r);
virtual AudioFormat Open(AudioFormat &af, GError **error_r);
virtual void Close();
virtual const void *FilterPCM(const void *src, size_t src_size,
size_t *dest_size_r, GError **error_r);
};
const struct audio_format *
AutoConvertFilter::Open(audio_format &in_audio_format, GError **error_r)
AudioFormat
AutoConvertFilter::Open(AudioFormat &in_audio_format, GError **error_r)
{
assert(audio_format_valid(&in_audio_format));
assert(in_audio_format.IsValid());
/* open the "real" filter */
child_audio_format = in_audio_format;
const audio_format *out_audio_format =
filter->Open(child_audio_format, error_r);
if (out_audio_format == nullptr)
return nullptr;
const AudioFormat child_audio_format = in_audio_format;
AudioFormat out_audio_format = filter->Open(in_audio_format, error_r);
if (!out_audio_format.IsDefined())
return out_audio_format;
/* need to convert? */
if (!audio_format_equals(&child_audio_format, &in_audio_format)) {
if (in_audio_format != child_audio_format) {
/* yes - create a convert_filter */
convert = filter_new(&convert_filter_plugin, nullptr, error_r);
if (convert == nullptr) {
filter->Close();
return nullptr;
return AudioFormat::Undefined();
}
audio_format audio_format2 = in_audio_format;
const audio_format *audio_format3 =
AudioFormat audio_format2 = in_audio_format;
AudioFormat audio_format3 =
convert->Open(audio_format2, error_r);
if (audio_format3 == nullptr) {
if (!audio_format3.IsDefined()) {
delete convert;
filter->Close();
return nullptr;
return AudioFormat::Undefined();
}
assert(audio_format_equals(&audio_format2, &in_audio_format));
assert(audio_format2 == in_audio_format);
convert_filter_set(convert, child_audio_format);
} else
......
......@@ -23,7 +23,7 @@
#include "FilterPlugin.hxx"
#include "FilterInternal.hxx"
#include "FilterRegistry.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include <glib.h>
......@@ -53,7 +53,7 @@ public:
children.emplace_back(name, filter);
}
virtual const audio_format *Open(audio_format &af, GError **error_r);
virtual AudioFormat Open(AudioFormat &af, GError **error_r) override;
virtual void Close();
virtual const void *FilterPCM(const void *src, size_t src_size,
size_t *dest_size_r, GError **error_r);
......@@ -96,43 +96,43 @@ ChainFilter::CloseUntil(const Filter *until)
gcc_unreachable();
}
static const struct audio_format *
static AudioFormat
chain_open_child(const char *name, Filter *filter,
const audio_format &prev_audio_format,
const AudioFormat &prev_audio_format,
GError **error_r)
{
audio_format conv_audio_format = prev_audio_format;
const audio_format *next_audio_format =
AudioFormat conv_audio_format = prev_audio_format;
const AudioFormat next_audio_format =
filter->Open(conv_audio_format, error_r);
if (next_audio_format == NULL)
return NULL;
if (!next_audio_format.IsDefined())
return next_audio_format;
if (!audio_format_equals(&conv_audio_format, &prev_audio_format)) {
if (conv_audio_format != prev_audio_format) {
struct audio_format_string s;
filter->Close();
g_set_error(error_r, filter_quark(), 0,
"Audio format not supported by filter '%s': %s",
name,
audio_format_to_string(&prev_audio_format, &s));
return NULL;
audio_format_to_string(prev_audio_format, &s));
return AudioFormat::Undefined();
}
return next_audio_format;
}
const audio_format *
ChainFilter::Open(audio_format &in_audio_format, GError **error_r)
AudioFormat
ChainFilter::Open(AudioFormat &in_audio_format, GError **error_r)
{
const audio_format *audio_format = &in_audio_format;
AudioFormat audio_format = in_audio_format;
for (auto &child : children) {
audio_format = chain_open_child(child.name, child.filter,
*audio_format, error_r);
if (audio_format == NULL) {
audio_format, error_r);
if (!audio_format.IsDefined()) {
/* rollback, close all children */
CloseUntil(child.filter);
return NULL;
break;
}
}
......
......@@ -25,7 +25,7 @@
#include "conf.h"
#include "pcm/PcmConvert.hxx"
#include "util/Manual.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "poison.h"
#include <assert.h>
......@@ -36,27 +36,27 @@ class ConvertFilter final : public Filter {
* The input audio format; PCM data is passed to the filter()
* method in this format.
*/
audio_format in_audio_format;
AudioFormat in_audio_format;
/**
* The output audio format; the consumer of this plugin
* expects PCM data in this format. This defaults to
* #in_audio_format, and can be set with convert_filter_set().
*/
audio_format out_audio_format;
AudioFormat out_audio_format;
Manual<PcmConvert> state;
public:
void Set(const audio_format &_out_audio_format) {
assert(audio_format_valid(&in_audio_format));
assert(audio_format_valid(&out_audio_format));
assert(audio_format_valid(&_out_audio_format));
void Set(const AudioFormat &_out_audio_format) {
assert(in_audio_format.IsValid());
assert(out_audio_format.IsValid());
assert(_out_audio_format.IsValid());
out_audio_format = _out_audio_format;
}
virtual const audio_format *Open(audio_format &af, GError **error_r);
virtual AudioFormat Open(AudioFormat &af, GError **error_r) override;
virtual void Close();
virtual const void *FilterPCM(const void *src, size_t src_size,
size_t *dest_size_r, GError **error_r);
......@@ -69,15 +69,15 @@ convert_filter_init(gcc_unused const struct config_param *param,
return new ConvertFilter();
}
const struct audio_format *
ConvertFilter::Open(audio_format &audio_format, gcc_unused GError **error_r)
AudioFormat
ConvertFilter::Open(AudioFormat &audio_format, gcc_unused GError **error_r)
{
assert(audio_format_valid(&audio_format));
assert(audio_format.IsValid());
in_audio_format = out_audio_format = audio_format;
state.Construct();
return &in_audio_format;
return in_audio_format;
}
void
......@@ -93,15 +93,15 @@ const void *
ConvertFilter::FilterPCM(const void *src, size_t src_size,
size_t *dest_size_r, GError **error_r)
{
if (audio_format_equals(&in_audio_format, &out_audio_format)) {
if (in_audio_format == out_audio_format) {
/* optimized special case: no-op */
*dest_size_r = src_size;
return src;
}
return state->Convert(&in_audio_format,
return state->Convert(in_audio_format,
src, src_size,
&out_audio_format, dest_size_r,
out_audio_format, dest_size_r,
error_r);
}
......@@ -111,7 +111,7 @@ const struct filter_plugin convert_filter_plugin = {
};
void
convert_filter_set(Filter *_filter, const audio_format &out_audio_format)
convert_filter_set(Filter *_filter, const AudioFormat out_audio_format)
{
ConvertFilter *filter = (ConvertFilter *)_filter;
......
......@@ -21,7 +21,7 @@
#define MPD_CONVERT_FILTER_PLUGIN_HXX
class Filter;
struct audio_format;
struct AudioFormat;
/**
* Sets the output audio format for the specified filter. You must
......@@ -30,6 +30,6 @@ struct audio_format;
* the last in a chain.
*/
void
convert_filter_set(Filter *filter, const audio_format &out_audio_format);
convert_filter_set(Filter *filter, AudioFormat out_audio_format);
#endif
......@@ -22,7 +22,7 @@
#include "FilterInternal.hxx"
#include "FilterRegistry.hxx"
#include "pcm/PcmBuffer.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "AudioCompress/compress.h"
#include <assert.h>
......@@ -34,7 +34,7 @@ class NormalizeFilter final : public Filter {
PcmBuffer buffer;
public:
virtual const audio_format *Open(audio_format &af, GError **error_r);
virtual AudioFormat Open(AudioFormat &af, GError **error_r) override;
virtual void Close();
virtual const void *FilterPCM(const void *src, size_t src_size,
size_t *dest_size_r, GError **error_r);
......@@ -47,14 +47,14 @@ normalize_filter_init(gcc_unused const struct config_param *param,
return new NormalizeFilter();
}
const struct audio_format *
NormalizeFilter::Open(audio_format &audio_format, gcc_unused GError **error_r)
AudioFormat
NormalizeFilter::Open(AudioFormat &audio_format, gcc_unused GError **error_r)
{
audio_format.format = SAMPLE_FORMAT_S16;
audio_format.format = SampleFormat::S16;
compressor = Compressor_new(0);
return &audio_format;
return audio_format;
}
void
......
......@@ -28,13 +28,14 @@
#include "FilterPlugin.hxx"
#include "FilterInternal.hxx"
#include "FilterRegistry.hxx"
#include "AudioFormat.hxx"
#include "gcc.h"
class NullFilter final : public Filter {
public:
virtual const audio_format *Open(audio_format &af,
gcc_unused GError **error_r) {
return &af;
virtual AudioFormat Open(AudioFormat &af,
gcc_unused GError **error_r) {
return af;
}
virtual void Close() {}
......
......@@ -22,7 +22,7 @@
#include "FilterPlugin.hxx"
#include "FilterInternal.hxx"
#include "FilterRegistry.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "replay_gain_info.h"
#include "replay_gain_config.h"
#include "MixerControl.hxx"
......@@ -66,7 +66,7 @@ class ReplayGainFilter final : public Filter {
*/
unsigned volume;
struct audio_format format;
AudioFormat format;
PcmBuffer buffer;
......@@ -112,7 +112,7 @@ public:
*/
void Update();
virtual const audio_format *Open(audio_format &af, GError **error_r);
virtual AudioFormat Open(AudioFormat &af, GError **error_r) override;
virtual void Close();
virtual const void *FilterPCM(const void *src, size_t src_size,
size_t *dest_size_r, GError **error_r);
......@@ -159,12 +159,12 @@ replay_gain_filter_init(gcc_unused const struct config_param *param,
return new ReplayGainFilter();
}
const audio_format *
ReplayGainFilter::Open(audio_format &af, gcc_unused GError **error_r)
AudioFormat
ReplayGainFilter::Open(AudioFormat &af, gcc_unused GError **error_r)
{
format = af;
return &format;
return format;
}
void
......@@ -196,7 +196,7 @@ ReplayGainFilter::FilterPCM(const void *src, size_t src_size,
memcpy(dest, src, src_size);
bool success = pcm_volume(dest, src_size,
sample_format(format.format),
format.format,
volume);
if (!success) {
g_set_error(error_r, replay_gain_quark(), 0,
......
......@@ -42,7 +42,7 @@
#include "config.h"
#include "conf.h"
#include "ConfigQuark.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include "CheckAudioFormat.hxx"
#include "FilterPlugin.hxx"
#include "FilterInternal.hxx"
......@@ -79,12 +79,12 @@ class RouteFilter final : public Filter {
/**
* The actual input format of our signal, once opened
*/
struct audio_format input_format;
AudioFormat input_format;
/**
* The decided upon output format, once opened
*/
struct audio_format output_format;
AudioFormat output_format;
/**
* The size, in bytes, of each multichannel frame in the
......@@ -120,7 +120,7 @@ public:
*/
bool Configure(const config_param *param, GError **error_r);
virtual const audio_format *Open(audio_format &af, GError **error_r);
virtual AudioFormat Open(AudioFormat &af, GError **error_r) override;
virtual void Close();
virtual const void *FilterPCM(const void *src, size_t src_size,
size_t *dest_size_r, GError **error_r);
......@@ -241,12 +241,12 @@ route_filter_init(const config_param *param, GError **error_r)
return filter;
}
const struct audio_format *
RouteFilter::Open(audio_format &audio_format, gcc_unused GError **error_r)
AudioFormat
RouteFilter::Open(AudioFormat &audio_format, gcc_unused GError **error_r)
{
// Copy the input format for later reference
input_format = audio_format;
input_frame_size = audio_format_frame_size(&input_format);
input_frame_size = input_format.GetFrameSize();
// Decide on an output format which has enough channels,
// and is otherwise identical
......@@ -254,9 +254,9 @@ RouteFilter::Open(audio_format &audio_format, gcc_unused GError **error_r)
output_format.channels = min_output_channels;
// Precalculate this simple value, to speed up allocation later
output_frame_size = audio_format_frame_size(&output_format);
output_frame_size = output_format.GetFrameSize();
return &output_format;
return output_format;
}
void
......@@ -271,8 +271,7 @@ RouteFilter::FilterPCM(const void *src, size_t src_size,
{
size_t number_of_frames = src_size / input_frame_size;
size_t bytes_per_frame_per_channel =
audio_format_sample_size(&input_format);
const size_t bytes_per_frame_per_channel = input_format.GetSampleSize();
// A moving pointer that always refers to channel 0 in the input, at the currently handled frame
const uint8_t *base_source = (const uint8_t *)src;
......
......@@ -25,7 +25,7 @@
#include "conf.h"
#include "pcm/PcmVolume.hxx"
#include "pcm/PcmBuffer.hxx"
#include "audio_format.h"
#include "AudioFormat.hxx"
#include <assert.h>
#include <string.h>
......@@ -36,7 +36,7 @@ class VolumeFilter final : public Filter {
*/
unsigned volume;
struct audio_format format;
AudioFormat format;
PcmBuffer buffer;
......@@ -56,7 +56,7 @@ public:
volume = _volume;
}
virtual const audio_format *Open(audio_format &af, GError **error_r);
virtual AudioFormat Open(AudioFormat &af, GError **error_r) override;
virtual void Close();
virtual const void *FilterPCM(const void *src, size_t src_size,
size_t *dest_size_r, GError **error_r);
......@@ -75,12 +75,12 @@ volume_filter_init(gcc_unused const struct config_param *param,
return new VolumeFilter();
}
const struct audio_format *
VolumeFilter::Open(audio_format &audio_format, gcc_unused GError **error_r)
AudioFormat
VolumeFilter::Open(AudioFormat &audio_format, gcc_unused GError **error_r)
{
format = audio_format;
return &format;
return format;
}
void
......@@ -112,7 +112,7 @@ VolumeFilter::FilterPCM(const void *src, size_t src_size,
memcpy(dest, src, src_size);
bool success = pcm_volume(dest, src_size,
sample_format(format.format),
format.format,
volume);
if (!success) {
g_set_error(error_r, volume_quark(), 0,
......
......@@ -233,26 +233,26 @@ alsa_test_default_device(void)
}
static snd_pcm_format_t
get_bitformat(enum sample_format sample_format)
get_bitformat(SampleFormat sample_format)
{
switch (sample_format) {
case SAMPLE_FORMAT_UNDEFINED:
case SAMPLE_FORMAT_DSD:
case SampleFormat::UNDEFINED:
case SampleFormat::DSD:
return SND_PCM_FORMAT_UNKNOWN;
case SAMPLE_FORMAT_S8:
case SampleFormat::S8:
return SND_PCM_FORMAT_S8;
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
return SND_PCM_FORMAT_S16;
case SAMPLE_FORMAT_S24_P32:
case SampleFormat::S24_P32:
return SND_PCM_FORMAT_S24;
case SAMPLE_FORMAT_S32:
case SampleFormat::S32:
return SND_PCM_FORMAT_S32;
case SAMPLE_FORMAT_FLOAT:
case SampleFormat::FLOAT:
return SND_PCM_FORMAT_FLOAT;
}
......@@ -324,7 +324,7 @@ alsa_try_format_or_packed(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams,
*/
static int
alsa_output_try_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams,
enum sample_format sample_format,
SampleFormat sample_format,
bool *packed_r, bool *reverse_endian_r)
{
snd_pcm_format_t alsa_format = get_bitformat(sample_format);
......@@ -355,36 +355,36 @@ alsa_output_try_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams,
*/
static int
alsa_output_setup_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams,
struct audio_format *audio_format,
AudioFormat &audio_format,
bool *packed_r, bool *reverse_endian_r)
{
/* try the input format first */
int err = alsa_output_try_format(pcm, hwparams,
sample_format(audio_format->format),
audio_format.format,
packed_r, reverse_endian_r);
/* if unsupported by the hardware, try other formats */
static const enum sample_format probe_formats[] = {
SAMPLE_FORMAT_S24_P32,
SAMPLE_FORMAT_S32,
SAMPLE_FORMAT_S16,
SAMPLE_FORMAT_S8,
SAMPLE_FORMAT_UNDEFINED,
static const SampleFormat probe_formats[] = {
SampleFormat::S24_P32,
SampleFormat::S32,
SampleFormat::S16,
SampleFormat::S8,
SampleFormat::UNDEFINED,
};
for (unsigned i = 0;
err == -EINVAL && probe_formats[i] != SAMPLE_FORMAT_UNDEFINED;
err == -EINVAL && probe_formats[i] != SampleFormat::UNDEFINED;
++i) {
const enum sample_format mpd_format = probe_formats[i];
if (mpd_format == audio_format->format)
const SampleFormat mpd_format = probe_formats[i];
if (mpd_format == audio_format.format)
continue;
err = alsa_output_try_format(pcm, hwparams, mpd_format,
packed_r, reverse_endian_r);
if (err == 0)
audio_format->format = mpd_format;
audio_format.format = mpd_format;
}
return err;
......@@ -395,11 +395,11 @@ alsa_output_setup_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams,
* the configured settings and the audio format.
*/
static bool
alsa_setup(AlsaOutput *ad, struct audio_format *audio_format,
alsa_setup(AlsaOutput *ad, AudioFormat &audio_format,
bool *packed_r, bool *reverse_endian_r, GError **error)
{
unsigned int sample_rate = audio_format->sample_rate;
unsigned int channels = audio_format->channels;
unsigned int sample_rate = audio_format.sample_rate;
unsigned int channels = audio_format.channels;
int err;
const char *cmd = NULL;
int retry = MPD_ALSA_RETRY_NR;
......@@ -443,7 +443,7 @@ configure_hw:
g_set_error(error, alsa_output_quark(), err,
"ALSA device \"%s\" does not support format %s: %s",
alsa_device(ad),
sample_format_to_string(sample_format(audio_format->format)),
sample_format_to_string(audio_format.format),
snd_strerror(-err));
return false;
}
......@@ -458,21 +458,21 @@ configure_hw:
if (err < 0) {
g_set_error(error, alsa_output_quark(), err,
"ALSA device \"%s\" does not support %i channels: %s",
alsa_device(ad), (int)audio_format->channels,
alsa_device(ad), (int)audio_format.channels,
snd_strerror(-err));
return false;
}
audio_format->channels = (int8_t)channels;
audio_format.channels = (int8_t)channels;
err = snd_pcm_hw_params_set_rate_near(ad->pcm, hwparams,
&sample_rate, NULL);
if (err < 0 || sample_rate == 0) {
g_set_error(error, alsa_output_quark(), err,
"ALSA device \"%s\" does not support %u Hz audio",
alsa_device(ad), audio_format->sample_rate);
alsa_device(ad), audio_format.sample_rate);
return false;
}
audio_format->sample_rate = sample_rate;
audio_format.sample_rate = sample_rate;
snd_pcm_uframes_t buffer_size_min, buffer_size_max;
snd_pcm_hw_params_get_buffer_size_min(hwparams, &buffer_size_min);
......@@ -603,22 +603,22 @@ error:
}
static bool
alsa_setup_dsd(AlsaOutput *ad, struct audio_format *audio_format,
alsa_setup_dsd(AlsaOutput *ad, const AudioFormat audio_format,
bool *shift8_r, bool *packed_r, bool *reverse_endian_r,
GError **error_r)
{
assert(ad->dsd_usb);
assert(audio_format->format == SAMPLE_FORMAT_DSD);
assert(audio_format.format == SampleFormat::DSD);
/* pass 24 bit to alsa_setup() */
struct audio_format usb_format = *audio_format;
usb_format.format = SAMPLE_FORMAT_S24_P32;
AudioFormat usb_format = audio_format;
usb_format.format = SampleFormat::S24_P32;
usb_format.sample_rate /= 2;
const struct audio_format check = usb_format;
const AudioFormat check = usb_format;
if (!alsa_setup(ad, &usb_format, packed_r, reverse_endian_r, error_r))
if (!alsa_setup(ad, usb_format, packed_r, reverse_endian_r, error_r))
return false;
/* if the device allows only 32 bit, shift all DSD-over-USB
......@@ -626,11 +626,11 @@ alsa_setup_dsd(AlsaOutput *ad, struct audio_format *audio_format,
the DSD-over-USB documentation does not specify whether
this is legal, but there is anecdotical evidence that this
is possible (and the only option for some devices) */
*shift8_r = usb_format.format == SAMPLE_FORMAT_S32;
if (usb_format.format == SAMPLE_FORMAT_S32)
usb_format.format = SAMPLE_FORMAT_S24_P32;
*shift8_r = usb_format.format == SampleFormat::S32;
if (usb_format.format == SampleFormat::S32)
usb_format.format = SampleFormat::S24_P32;
if (!audio_format_equals(&usb_format, &check)) {
if (usb_format != check) {
/* no bit-perfect playback, which is required
for DSD over USB */
g_set_error(error_r, alsa_output_quark(), 0,
......@@ -644,13 +644,13 @@ alsa_setup_dsd(AlsaOutput *ad, struct audio_format *audio_format,
}
static bool
alsa_setup_or_dsd(AlsaOutput *ad, struct audio_format *audio_format,
alsa_setup_or_dsd(AlsaOutput *ad, AudioFormat &audio_format,
GError **error_r)
{
bool shift8 = false, packed, reverse_endian;
const bool dsd_usb = ad->dsd_usb &&
audio_format->format == SAMPLE_FORMAT_DSD;
audio_format.format == SampleFormat::DSD;
const bool success = dsd_usb
? alsa_setup_dsd(ad, audio_format,
&shift8, &packed, &reverse_endian,
......@@ -660,14 +660,14 @@ alsa_setup_or_dsd(AlsaOutput *ad, struct audio_format *audio_format,
if (!success)
return false;
ad->pcm_export->Open(sample_format(audio_format->format),
audio_format->channels,
ad->pcm_export->Open(audio_format.format,
audio_format.channels,
dsd_usb, shift8, packed, reverse_endian);
return true;
}
static bool
alsa_open(struct audio_output *ao, struct audio_format *audio_format, GError **error)
alsa_open(struct audio_output *ao, AudioFormat &audio_format, GError **error)
{
AlsaOutput *ad = (AlsaOutput *)ao;
......@@ -688,8 +688,8 @@ alsa_open(struct audio_output *ao, struct audio_format *audio_format, GError **e
return false;
}
ad->in_frame_size = audio_format_frame_size(audio_format);
ad->out_frame_size = ad->pcm_export->GetFrameSize(*audio_format);
ad->in_frame_size = audio_format.GetFrameSize();
ad->out_frame_size = ad->pcm_export->GetFrameSize(audio_format);
return true;
}
......
......@@ -200,18 +200,18 @@ ao_output_close(struct audio_output *ao)
}
static bool
ao_output_open(struct audio_output *ao, struct audio_format *audio_format,
ao_output_open(struct audio_output *ao, AudioFormat &audio_format,
GError **error)
{
ao_sample_format format = OUR_AO_FORMAT_INITIALIZER;
AoOutput *ad = (AoOutput *)ao;
switch (audio_format->format) {
case SAMPLE_FORMAT_S8:
switch (audio_format.format) {
case SampleFormat::S8:
format.bits = 8;
break;
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
format.bits = 16;
break;
......@@ -219,14 +219,14 @@ ao_output_open(struct audio_output *ao, struct audio_format *audio_format,
/* support for 24 bit samples in libao is currently
dubious, and until we have sorted that out,
convert everything to 16 bit */
audio_format->format = SAMPLE_FORMAT_S16;
audio_format.format = SampleFormat::S16;
format.bits = 16;
break;
}
format.rate = audio_format->sample_rate;
format.rate = audio_format.sample_rate;
format.byte_format = AO_FMT_NATIVE;
format.channels = audio_format->channels;
format.channels = audio_format.channels;
ad->device = ao_open_live(ad->driver, &format, ad->options);
......
......@@ -227,12 +227,12 @@ fifo_output_finish(struct audio_output *ao)
}
static bool
fifo_output_open(struct audio_output *ao, struct audio_format *audio_format,
fifo_output_open(struct audio_output *ao, AudioFormat &audio_format,
G_GNUC_UNUSED GError **error)
{
FifoOutput *fd = (FifoOutput *)ao;
fd->timer = new Timer(*audio_format);
fd->timer = new Timer(audio_format);
return true;
}
......
......@@ -131,13 +131,13 @@ struct HttpdOutput final : private ServerSocket {
/**
* Caller must lock the mutex.
*/
bool OpenEncoder(struct audio_format *audio_format,
bool OpenEncoder(AudioFormat &audio_format,
GError **error_r);
/**
* Caller must lock the mutex.
*/
bool Open(struct audio_format *audio_format, GError **error_r);
bool Open(AudioFormat &audio_format, GError **error_r);
/**
* Caller must lock the mutex.
......
......@@ -291,7 +291,7 @@ httpd_output_disable(struct audio_output *ao)
}
inline bool
HttpdOutput::OpenEncoder(struct audio_format *audio_format, GError **error)
HttpdOutput::OpenEncoder(AudioFormat &audio_format, GError **error)
{
if (!encoder_open(encoder, audio_format, error))
return false;
......@@ -307,7 +307,7 @@ HttpdOutput::OpenEncoder(struct audio_format *audio_format, GError **error)
}
inline bool
HttpdOutput::Open(struct audio_format *audio_format, GError **error_r)
HttpdOutput::Open(AudioFormat &audio_format, GError **error_r)
{
assert(!open);
assert(clients.empty());
......@@ -320,7 +320,7 @@ HttpdOutput::Open(struct audio_format *audio_format, GError **error_r)
/* initialize other attributes */
clients_cnt = 0;
timer = new Timer(*audio_format);
timer = new Timer(audio_format);
open = true;
......@@ -328,7 +328,7 @@ HttpdOutput::Open(struct audio_format *audio_format, GError **error_r)
}
static bool
httpd_output_open(struct audio_output *ao, struct audio_format *audio_format,
httpd_output_open(struct audio_output *ao, AudioFormat &audio_format,
GError **error)
{
HttpdOutput *httpd = Cast(ao);
......
......@@ -67,7 +67,7 @@ struct JackOutput {
size_t ringbuffer_size;
/* the current audio format */
struct audio_format audio_format;
AudioFormat audio_format;
/* jack library stuff */
jack_port_t *ports[MAX_PORTS];
......@@ -203,18 +203,18 @@ mpd_jack_shutdown(void *arg)
}
static void
set_audioformat(JackOutput *jd, struct audio_format *audio_format)
set_audioformat(JackOutput *jd, AudioFormat &audio_format)
{
audio_format->sample_rate = jack_get_sample_rate(jd->client);
audio_format.sample_rate = jack_get_sample_rate(jd->client);
if (jd->num_source_ports == 1)
audio_format->channels = 1;
else if (audio_format->channels > jd->num_source_ports)
audio_format->channels = 2;
audio_format.channels = 1;
else if (audio_format.channels > jd->num_source_ports)
audio_format.channels = 2;
if (audio_format->format != SAMPLE_FORMAT_S16 &&
audio_format->format != SAMPLE_FORMAT_S24_P32)
audio_format->format = SAMPLE_FORMAT_S24_P32;
if (audio_format.format != SampleFormat::S16 &&
audio_format.format != SampleFormat::S24_P32)
audio_format.format = SampleFormat::S24_P32;
}
static void
......@@ -591,7 +591,7 @@ mpd_jack_start(JackOutput *jd, GError **error_r)
}
static bool
mpd_jack_open(struct audio_output *ao, struct audio_format *audio_format,
mpd_jack_open(struct audio_output *ao, AudioFormat &audio_format,
GError **error_r)
{
JackOutput *jd = (JackOutput *)ao;
......@@ -607,7 +607,7 @@ mpd_jack_open(struct audio_output *ao, struct audio_format *audio_format,
return false;
set_audioformat(jd, audio_format);
jd->audio_format = *audio_format;
jd->audio_format = audio_format;
if (!mpd_jack_start(jd, error_r))
return false;
......@@ -684,12 +684,12 @@ mpd_jack_write_samples(JackOutput *jd, const void *src,
unsigned num_samples)
{
switch (jd->audio_format.format) {
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
mpd_jack_write_samples_16(jd, (const int16_t*)src,
num_samples);
break;
case SAMPLE_FORMAT_S24_P32:
case SampleFormat::S24_P32:
mpd_jack_write_samples_24(jd, (const int32_t*)src,
num_samples);
break;
......@@ -705,7 +705,7 @@ mpd_jack_play(struct audio_output *ao, const void *chunk, size_t size,
GError **error_r)
{
JackOutput *jd = (JackOutput *)ao;
const size_t frame_size = audio_format_frame_size(&jd->audio_format);
const size_t frame_size = jd->audio_format.GetFrameSize();
size_t space = 0, space1;
jd->pause = false;
......
......@@ -66,13 +66,13 @@ null_finish(struct audio_output *ao)
}
static bool
null_open(struct audio_output *ao, struct audio_format *audio_format,
null_open(struct audio_output *ao, AudioFormat &audio_format,
gcc_unused GError **error)
{
NullOutput *nd = (NullOutput *)ao;
if (nd->sync)
nd->timer = new Timer(*audio_format);
nd->timer = new Timer(audio_format);
return true;
}
......
......@@ -316,30 +316,30 @@ osx_output_close(struct audio_output *ao)
}
static bool
osx_output_open(struct audio_output *ao, struct audio_format *audio_format, GError **error)
osx_output_open(struct audio_output *ao, AudioFormat &audio_format, GError **error)
{
OSXOutput *od = (OSXOutput *)ao;
AudioStreamBasicDescription stream_description;
stream_description.mSampleRate = audio_format->sample_rate;
stream_description.mSampleRate = audio_format.sample_rate;
stream_description.mFormatID = kAudioFormatLinearPCM;
stream_description.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
switch (audio_format->format) {
case SAMPLE_FORMAT_S8:
switch (audio_format.format) {
case SampleFormat::S8:
stream_description.mBitsPerChannel = 8;
break;
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
stream_description.mBitsPerChannel = 16;
break;
case SAMPLE_FORMAT_S32:
case SampleFormat::S32:
stream_description.mBitsPerChannel = 32;
break;
default:
audio_format->format = SAMPLE_FORMAT_S32;
audio_format.format = SampleFormat::S32;
stream_description.mBitsPerChannel = 32;
break;
}
......@@ -348,11 +348,10 @@ osx_output_open(struct audio_output *ao, struct audio_format *audio_format, GErr
stream_description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
#endif
stream_description.mBytesPerPacket =
audio_format_frame_size(audio_format);
stream_description.mBytesPerPacket = audio_format.GetFrameSize();
stream_description.mFramesPerPacket = 1;
stream_description.mBytesPerFrame = stream_description.mBytesPerPacket;
stream_description.mChannelsPerFrame = audio_format->channels;
stream_description.mChannelsPerFrame = audio_format.channels;
ComponentResult result =
AudioUnitSetProperty(od->au, kAudioUnitProperty_StreamFormat,
......@@ -374,8 +373,8 @@ osx_output_open(struct audio_output *ao, struct audio_format *audio_format, GErr
}
/* create a buffer of 1s */
od->buffer = fifo_buffer_new(audio_format->sample_rate *
audio_format_frame_size(audio_format));
od->buffer = fifo_buffer_new(audio_format.sample_rate *
audio_format.GetFrameSize());
status = AudioOutputUnitStart(od->au);
if (status != 0) {
......
......@@ -66,26 +66,26 @@ openal_output_quark(void)
}
static ALenum
openal_audio_format(struct audio_format *audio_format)
openal_audio_format(AudioFormat &audio_format)
{
/* note: cannot map SAMPLE_FORMAT_S8 to AL_FORMAT_STEREO8 or
/* note: cannot map SampleFormat::S8 to AL_FORMAT_STEREO8 or
AL_FORMAT_MONO8 since OpenAL expects unsigned 8 bit
samples, while MPD uses signed samples */
switch (audio_format->format) {
case SAMPLE_FORMAT_S16:
if (audio_format->channels == 2)
switch (audio_format.format) {
case SampleFormat::S16:
if (audio_format.channels == 2)
return AL_FORMAT_STEREO16;
if (audio_format->channels == 1)
if (audio_format.channels == 1)
return AL_FORMAT_MONO16;
/* fall back to mono */
audio_format->channels = 1;
audio_format.channels = 1;
return openal_audio_format(audio_format);
default:
/* fall back to 16 bit */
audio_format->format = SAMPLE_FORMAT_S16;
audio_format.format = SampleFormat::S16;
return openal_audio_format(audio_format);
}
}
......@@ -169,7 +169,7 @@ openal_finish(struct audio_output *ao)
}
static bool
openal_open(struct audio_output *ao, struct audio_format *audio_format,
openal_open(struct audio_output *ao, AudioFormat &audio_format,
GError **error)
{
OpenALOutput *od = (OpenALOutput *)ao;
......@@ -199,7 +199,7 @@ openal_open(struct audio_output *ao, struct audio_format *audio_format,
}
od->filled = 0;
od->frequency = audio_format->sample_rate;
od->frequency = audio_format.sample_rate;
return true;
}
......
......@@ -70,7 +70,7 @@ struct OssOutput {
* The current input audio format. This is needed to reopen
* the device after cancel().
*/
struct audio_format audio_format;
AudioFormat audio_format;
/**
* The current OSS audio format. This is needed to reopen the
......@@ -308,10 +308,10 @@ oss_try_ioctl(int fd, unsigned long request, int value,
* specified number is not supported.
*/
static bool
oss_setup_channels(int fd, struct audio_format *audio_format, GError **error_r)
oss_setup_channels(int fd, AudioFormat &audio_format, GError **error_r)
{
const char *const msg = "Failed to set channel count";
int channels = audio_format->channels;
int channels = audio_format.channels;
enum oss_setup_result result =
oss_try_ioctl_r(fd, SNDCTL_DSP_CHANNELS, &channels, msg, error_r);
switch (result) {
......@@ -319,7 +319,7 @@ oss_setup_channels(int fd, struct audio_format *audio_format, GError **error_r)
if (!audio_valid_channel_count(channels))
break;
audio_format->channels = channels;
audio_format.channels = channels;
return true;
case ERROR:
......@@ -330,7 +330,7 @@ oss_setup_channels(int fd, struct audio_format *audio_format, GError **error_r)
}
for (unsigned i = 1; i < 2; ++i) {
if (i == audio_format->channels)
if (i == audio_format.channels)
/* don't try that again */
continue;
......@@ -342,7 +342,7 @@ oss_setup_channels(int fd, struct audio_format *audio_format, GError **error_r)
if (!audio_valid_channel_count(channels))
break;
audio_format->channels = channels;
audio_format.channels = channels;
return true;
case ERROR:
......@@ -362,11 +362,11 @@ oss_setup_channels(int fd, struct audio_format *audio_format, GError **error_r)
* specified sample rate is not supported.
*/
static bool
oss_setup_sample_rate(int fd, struct audio_format *audio_format,
oss_setup_sample_rate(int fd, AudioFormat &audio_format,
GError **error_r)
{
const char *const msg = "Failed to set sample rate";
int sample_rate = audio_format->sample_rate;
int sample_rate = audio_format.sample_rate;
enum oss_setup_result result =
oss_try_ioctl_r(fd, SNDCTL_DSP_SPEED, &sample_rate,
msg, error_r);
......@@ -375,7 +375,7 @@ oss_setup_sample_rate(int fd, struct audio_format *audio_format,
if (!audio_valid_sample_rate(sample_rate))
break;
audio_format->sample_rate = sample_rate;
audio_format.sample_rate = sample_rate;
return true;
case ERROR:
......@@ -388,7 +388,7 @@ oss_setup_sample_rate(int fd, struct audio_format *audio_format,
static const int sample_rates[] = { 48000, 44100, 0 };
for (unsigned i = 0; sample_rates[i] != 0; ++i) {
sample_rate = sample_rates[i];
if (sample_rate == (int)audio_format->sample_rate)
if (sample_rate == (int)audio_format.sample_rate)
continue;
result = oss_try_ioctl_r(fd, SNDCTL_DSP_SPEED, &sample_rate,
......@@ -398,7 +398,7 @@ oss_setup_sample_rate(int fd, struct audio_format *audio_format,
if (!audio_valid_sample_rate(sample_rate))
break;
audio_format->sample_rate = sample_rate;
audio_format.sample_rate = sample_rate;
return true;
case ERROR:
......@@ -418,28 +418,28 @@ oss_setup_sample_rate(int fd, struct audio_format *audio_format,
* AFMT_QUERY if there is no direct counterpart.
*/
static int
sample_format_to_oss(enum sample_format format)
sample_format_to_oss(SampleFormat format)
{
switch (format) {
case SAMPLE_FORMAT_UNDEFINED:
case SAMPLE_FORMAT_FLOAT:
case SAMPLE_FORMAT_DSD:
case SampleFormat::UNDEFINED:
case SampleFormat::FLOAT:
case SampleFormat::DSD:
return AFMT_QUERY;
case SAMPLE_FORMAT_S8:
case SampleFormat::S8:
return AFMT_S8;
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
return AFMT_S16_NE;
case SAMPLE_FORMAT_S24_P32:
case SampleFormat::S24_P32:
#ifdef AFMT_S24_NE
return AFMT_S24_NE;
#else
return AFMT_QUERY;
#endif
case SAMPLE_FORMAT_S32:
case SampleFormat::S32:
#ifdef AFMT_S32_NE
return AFMT_S32_NE;
#else
......@@ -452,47 +452,47 @@ sample_format_to_oss(enum sample_format format)
/**
* Convert an OSS sample format to its MPD counterpart. Returns
* SAMPLE_FORMAT_UNDEFINED if there is no direct counterpart.
* SampleFormat::UNDEFINED if there is no direct counterpart.
*/
static enum sample_format
static SampleFormat
sample_format_from_oss(int format)
{
switch (format) {
case AFMT_S8:
return SAMPLE_FORMAT_S8;
return SampleFormat::S8;
case AFMT_S16_NE:
return SAMPLE_FORMAT_S16;
return SampleFormat::S16;
#ifdef AFMT_S24_PACKED
case AFMT_S24_PACKED:
return SAMPLE_FORMAT_S24_P32;
return SampleFormat::S24_P32;
#endif
#ifdef AFMT_S24_NE
case AFMT_S24_NE:
return SAMPLE_FORMAT_S24_P32;
return SampleFormat::S24_P32;
#endif
#ifdef AFMT_S32_NE
case AFMT_S32_NE:
return SAMPLE_FORMAT_S32;
return SampleFormat::S32;
#endif
default:
return SAMPLE_FORMAT_UNDEFINED;
return SampleFormat::UNDEFINED;
}
}
/**
* Probe one sample format.
*
* @return the selected sample format or SAMPLE_FORMAT_UNDEFINED on
* @return the selected sample format or SampleFormat::UNDEFINED on
* error
*/
static enum oss_setup_result
oss_probe_sample_format(int fd, enum sample_format sample_format,
enum sample_format *sample_format_r,
oss_probe_sample_format(int fd, SampleFormat sample_format,
SampleFormat *sample_format_r,
int *oss_format_r,
#ifdef AFMT_S24_PACKED
PcmExport &pcm_export,
......@@ -509,7 +509,7 @@ oss_probe_sample_format(int fd, enum sample_format sample_format,
"Failed to set sample format", error_r);
#ifdef AFMT_S24_PACKED
if (result == UNSUPPORTED && sample_format == SAMPLE_FORMAT_S24_P32) {
if (result == UNSUPPORTED && sample_format == SampleFormat::S24_P32) {
/* if the driver doesn't support padded 24 bit, try
packed 24 bit */
oss_format = AFMT_S24_PACKED;
......@@ -523,7 +523,7 @@ oss_probe_sample_format(int fd, enum sample_format sample_format,
return result;
sample_format = sample_format_from_oss(oss_format);
if (sample_format == SAMPLE_FORMAT_UNDEFINED)
if (sample_format == SampleFormat::UNDEFINED)
return UNSUPPORTED;
*sample_format_r = sample_format;
......@@ -544,16 +544,16 @@ oss_probe_sample_format(int fd, enum sample_format sample_format,
* specified format is not supported.
*/
static bool
oss_setup_sample_format(int fd, struct audio_format *audio_format,
oss_setup_sample_format(int fd, AudioFormat &audio_format,
int *oss_format_r,
#ifdef AFMT_S24_PACKED
PcmExport &pcm_export,
#endif
GError **error_r)
{
enum sample_format mpd_format;
SampleFormat mpd_format;
enum oss_setup_result result =
oss_probe_sample_format(fd, sample_format(audio_format->format),
oss_probe_sample_format(fd, audio_format.format,
&mpd_format, oss_format_r,
#ifdef AFMT_S24_PACKED
pcm_export,
......@@ -561,7 +561,7 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format,
error_r);
switch (result) {
case SUCCESS:
audio_format->format = mpd_format;
audio_format.format = mpd_format;
return true;
case ERROR:
......@@ -577,17 +577,17 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format,
/* the requested sample format is not available - probe for
other formats supported by MPD */
static const enum sample_format sample_formats[] = {
SAMPLE_FORMAT_S24_P32,
SAMPLE_FORMAT_S32,
SAMPLE_FORMAT_S16,
SAMPLE_FORMAT_S8,
SAMPLE_FORMAT_UNDEFINED /* sentinel */
static const SampleFormat sample_formats[] = {
SampleFormat::S24_P32,
SampleFormat::S32,
SampleFormat::S16,
SampleFormat::S8,
SampleFormat::UNDEFINED /* sentinel */
};
for (unsigned i = 0; sample_formats[i] != SAMPLE_FORMAT_UNDEFINED; ++i) {
for (unsigned i = 0; sample_formats[i] != SampleFormat::UNDEFINED; ++i) {
mpd_format = sample_formats[i];
if (mpd_format == audio_format->format)
if (mpd_format == audio_format.format)
/* don't try that again */
continue;
......@@ -599,7 +599,7 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format,
error_r);
switch (result) {
case SUCCESS:
audio_format->format = mpd_format;
audio_format.format = mpd_format;
return true;
case ERROR:
......@@ -619,7 +619,7 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format,
* Sets up the OSS device which was opened before.
*/
static bool
oss_setup(OssOutput *od, struct audio_format *audio_format,
oss_setup(OssOutput *od, AudioFormat &audio_format,
GError **error_r)
{
return oss_setup_channels(od->fd, audio_format, error_r) &&
......@@ -687,7 +687,7 @@ oss_reopen(OssOutput *od, GError **error_r)
}
static bool
oss_output_open(struct audio_output *ao, struct audio_format *audio_format,
oss_output_open(struct audio_output *ao, AudioFormat &audio_format,
GError **error)
{
OssOutput *od = (OssOutput *)ao;
......@@ -705,7 +705,7 @@ oss_output_open(struct audio_output *ao, struct audio_format *audio_format,
return false;
}
od->audio_format = *audio_format;
od->audio_format = audio_format;
return true;
}
......
......@@ -95,7 +95,7 @@ pipe_output_finish(struct audio_output *ao)
static bool
pipe_output_open(struct audio_output *ao,
G_GNUC_UNUSED struct audio_format *audio_format,
G_GNUC_UNUSED AudioFormat &audio_format,
G_GNUC_UNUSED GError **error)
{
PipeOutput *pd = (PipeOutput *)ao;
......
......@@ -578,7 +578,7 @@ pulse_output_setup_stream(PulseOutput *po, const pa_sample_spec *ss,
}
static bool
pulse_output_open(struct audio_output *ao, struct audio_format *audio_format,
pulse_output_open(struct audio_output *ao, AudioFormat &audio_format,
GError **error_r)
{
PulseOutput *po = (PulseOutput *)ao;
......@@ -615,11 +615,11 @@ pulse_output_open(struct audio_output *ao, struct audio_format *audio_format,
/* MPD doesn't support the other pulseaudio sample formats, so
we just force MPD to send us everything as 16 bit */
audio_format->format = SAMPLE_FORMAT_S16;
audio_format.format = SampleFormat::S16;
ss.format = PA_SAMPLE_S16NE;
ss.rate = audio_format->sample_rate;
ss.channels = audio_format->channels;
ss.rate = audio_format.sample_rate;
ss.channels = audio_format.channels;
/* create a stream .. */
......
......@@ -192,7 +192,7 @@ RecorderOutput::EncoderToFile(GError **error_r)
static bool
recorder_output_open(struct audio_output *ao,
struct audio_format *audio_format,
AudioFormat &audio_format,
GError **error_r)
{
RecorderOutput *recorder = (RecorderOutput *)ao;
......
......@@ -144,39 +144,41 @@ roar_finish(struct audio_output *ao)
static void
roar_use_audio_format(struct roar_audio_info *info,
struct audio_format *audio_format)
AudioFormat &audio_format)
{
info->rate = audio_format->sample_rate;
info->channels = audio_format->channels;
info->rate = audio_format.sample_rate;
info->channels = audio_format.channels;
info->codec = ROAR_CODEC_PCM_S;
switch (audio_format->format) {
case SAMPLE_FORMAT_UNDEFINED:
switch (audio_format.format) {
case SampleFormat::UNDEFINED:
case SampleFormat::FLOAT:
case SampleFormat::DSD:
info->bits = 16;
audio_format->format = SAMPLE_FORMAT_S16;
audio_format.format = SampleFormat::S16;
break;
case SAMPLE_FORMAT_S8:
case SampleFormat::S8:
info->bits = 8;
break;
case SAMPLE_FORMAT_S16:
case SampleFormat::S16:
info->bits = 16;
break;
case SAMPLE_FORMAT_S24_P32:
case SampleFormat::S24_P32:
info->bits = 32;
audio_format->format = SAMPLE_FORMAT_S32;
audio_format.format = SampleFormat::S32;
break;
case SAMPLE_FORMAT_S32:
case SampleFormat::S32:
info->bits = 32;
break;
}
}
static bool
roar_open(struct audio_output *ao, struct audio_format *audio_format, GError **error)
roar_open(struct audio_output *ao, AudioFormat &audio_format, GError **error)
{
RoarOutput *self = (RoarOutput *)ao;
const ScopeLock protect(self->mutex);
......
......@@ -116,9 +116,8 @@ inline bool
ShoutOutput::Configure(const config_param *param, GError **error_r)
{
const struct audio_format *audio_format =
&base.config_audio_format;
if (!audio_format_fully_defined(audio_format)) {
const AudioFormat audio_format = base.config_audio_format;
if (!audio_format.IsFullyDefined()) {
g_set_error(error_r, shout_output_quark(), 0,
"Need full audio format specification");
return nullptr;
......@@ -269,10 +268,10 @@ ShoutOutput::Configure(const config_param *param, GError **error_r)
char temp[11];
memset(temp, 0, sizeof(temp));
snprintf(temp, sizeof(temp), "%u", audio_format->channels);
snprintf(temp, sizeof(temp), "%u", audio_format.channels);
shout_set_audio_info(shout_conn, SHOUT_AI_CHANNELS, temp);
snprintf(temp, sizeof(temp), "%u", audio_format->sample_rate);
snprintf(temp, sizeof(temp), "%u", audio_format.sample_rate);
shout_set_audio_info(shout_conn, SHOUT_AI_SAMPLERATE, temp);
......@@ -428,7 +427,7 @@ shout_connect(ShoutOutput *sd, GError **error)
}
static bool
my_shout_open_device(struct audio_output *ao, struct audio_format *audio_format,
my_shout_open_device(struct audio_output *ao, AudioFormat &audio_format,
GError **error)
{
ShoutOutput *sd = (ShoutOutput *)ao;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment