aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-11-10 17:11:34 +0100
committerMax Kellermann <max@duempel.org>2009-12-02 22:29:50 +0100
commitc412d6251e9cd3abe735b7622af4003502e54f72 (patch)
tree7344c13f62e4cc788c830c05d21bb7b5b47f5866 /src/decoder
parent68c2cfbb4067b2292e1ff1d4e7716ff370903f84 (diff)
downloadmpd-c412d6251e9cd3abe735b7622af4003502e54f72.tar.gz
mpd-c412d6251e9cd3abe735b7622af4003502e54f72.tar.xz
mpd-c412d6251e9cd3abe735b7622af4003502e54f72.zip
audio_format: changed "bits" to "enum sample_format"
This patch prepares support for floating point samples (and probably other formats). It changes the meaning of the "bits" attribute from a bit count to a symbolic value.
Diffstat (limited to 'src/decoder')
-rw-r--r--src/decoder/_flac_common.c27
-rw-r--r--src/decoder/_flac_common.h2
-rw-r--r--src/decoder/audiofile_plugin.c26
-rw-r--r--src/decoder/faad_plugin.c2
-rw-r--r--src/decoder/ffmpeg_plugin.c30
-rw-r--r--src/decoder/flac_pcm.c16
-rw-r--r--src/decoder/flac_pcm.h4
-rw-r--r--src/decoder/fluidsynth_plugin.c2
-rw-r--r--src/decoder/mad_plugin.c3
-rw-r--r--src/decoder/mikmod_plugin.c2
-rw-r--r--src/decoder/modplug_plugin.c2
-rw-r--r--src/decoder/mp4ff_plugin.c3
-rw-r--r--src/decoder/mpcdec_plugin.c3
-rw-r--r--src/decoder/mpg123_decoder_plugin.c2
-rw-r--r--src/decoder/sidplay_plugin.cxx2
-rw-r--r--src/decoder/sndfile_decoder_plugin.c3
-rwxr-xr-xsrc/decoder/vorbis_plugin.c3
-rw-r--r--src/decoder/wavpack_plugin.c47
-rw-r--r--src/decoder/wildmidi_plugin.c2
19 files changed, 138 insertions, 43 deletions
diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c
index f12b8bff0..70b2c0202 100644
--- a/src/decoder/_flac_common.c
+++ b/src/decoder/_flac_common.c
@@ -60,6 +60,27 @@ flac_data_deinit(struct flac_data *data)
tag_free(data->tag);
}
+static enum sample_format
+flac_sample_format(const FLAC__StreamMetadata_StreamInfo *si)
+{
+ switch (si->bits_per_sample) {
+ case 8:
+ return SAMPLE_FORMAT_S8;
+
+ case 16:
+ return SAMPLE_FORMAT_S16;
+
+ case 24:
+ return SAMPLE_FORMAT_S24_P32;
+
+ case 32:
+ return SAMPLE_FORMAT_S32;
+
+ default:
+ return SAMPLE_FORMAT_UNDEFINED;
+ }
+}
+
bool
flac_data_get_audio_format(struct flac_data *data,
struct audio_format *audio_format)
@@ -71,9 +92,11 @@ flac_data_get_audio_format(struct flac_data *data,
return false;
}
+ data->sample_format = flac_sample_format(&data->stream_info);
+
if (!audio_format_init_checked(audio_format,
data->stream_info.sample_rate,
- data->stream_info.bits_per_sample,
+ data->sample_format,
data->stream_info.channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
@@ -144,7 +167,7 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
buffer = pcm_buffer_get(&data->buffer, buffer_size);
flac_convert(buffer, frame->header.channels,
- frame->header.bits_per_sample, buf,
+ data->sample_format, buf,
0, frame->header.blocksize);
if (data->next_frame >= data->first_frame)
diff --git a/src/decoder/_flac_common.h b/src/decoder/_flac_common.h
index 1d211fcfb..2f328afa6 100644
--- a/src/decoder/_flac_common.h
+++ b/src/decoder/_flac_common.h
@@ -38,6 +38,8 @@
struct flac_data {
struct pcm_buffer buffer;
+ enum sample_format sample_format;
+
/**
* The size of one frame in the output buffer.
*/
diff --git a/src/decoder/audiofile_plugin.c b/src/decoder/audiofile_plugin.c
index 5a2096d00..fcb431db7 100644
--- a/src/decoder/audiofile_plugin.c
+++ b/src/decoder/audiofile_plugin.c
@@ -101,13 +101,33 @@ setup_virtual_fops(struct input_stream *stream)
return vf;
}
-static uint8_t
+static enum sample_format
+audiofile_bits_to_sample_format(int bits)
+{
+ switch (bits) {
+ case 8:
+ return SAMPLE_FORMAT_S8;
+
+ case 16:
+ return SAMPLE_FORMAT_S16;
+
+ case 24:
+ return SAMPLE_FORMAT_S24_P32;
+
+ case 32:
+ return SAMPLE_FORMAT_S32;
+ }
+
+ return SAMPLE_FORMAT_UNDEFINED;
+}
+
+static enum sample_format
audiofile_setup_sample_format(AFfilehandle af_fp)
{
int fs, bits;
afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
- if (!audio_valid_sample_format(bits)) {
+ if (!audio_valid_sample_format(audiofile_bits_to_sample_format(bits))) {
g_debug("input file has %d bit samples, converting to 16",
bits);
bits = 16;
@@ -117,7 +137,7 @@ audiofile_setup_sample_format(AFfilehandle af_fp)
AF_SAMPFMT_TWOSCOMP, bits);
afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
- return bits;
+ return audiofile_bits_to_sample_format(bits);
}
static void
diff --git a/src/decoder/faad_plugin.c b/src/decoder/faad_plugin.c
index 55df15555..2a05e33e8 100644
--- a/src/decoder/faad_plugin.c
+++ b/src/decoder/faad_plugin.c
@@ -283,7 +283,7 @@ faad_decoder_init(faacDecHandle decoder, struct decoder_buffer *buffer,
decoder_buffer_consume(buffer, nbytes);
return audio_format_init_checked(audio_format, sample_rate,
- 16, channels, error_r);
+ SAMPLE_FORMAT_S16, channels, error_r);
}
/**
diff --git a/src/decoder/ffmpeg_plugin.c b/src/decoder/ffmpeg_plugin.c
index 9b025153b..af9320322 100644
--- a/src/decoder/ffmpeg_plugin.c
+++ b/src/decoder/ffmpeg_plugin.c
@@ -277,6 +277,26 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
return cmd;
}
+static enum sample_format
+ffmpeg_sample_format(G_GNUC_UNUSED const AVCodecContext *codec_context)
+{
+#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(41<<8)+0)
+ int bits = (uint8_t) av_get_bits_per_sample_format(codec_context->sample_fmt);
+
+ /* XXX implement & test other sample formats */
+
+ switch (bits) {
+ case 16:
+ return SAMPLE_FORMAT_S16;
+ }
+
+ return SAMPLE_FORMAT_UNDEFINED;
+#else
+ /* XXX fixme 16-bit for older ffmpeg (13 Aug 2007) */
+ return SAMPLE_FORMAT_S16;
+#endif
+}
+
static bool
ffmpeg_decode_internal(struct ffmpeg_context *ctx)
{
@@ -288,7 +308,6 @@ ffmpeg_decode_internal(struct ffmpeg_context *ctx)
struct audio_format audio_format;
enum decoder_command cmd;
int total_time;
- uint8_t bits;
total_time = 0;
@@ -296,14 +315,9 @@ ffmpeg_decode_internal(struct ffmpeg_context *ctx)
codec_context->channels = 2;
}
-#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(41<<8)+0)
- bits = (uint8_t) av_get_bits_per_sample_format(codec_context->sample_fmt);
-#else
- /* XXX fixme 16-bit for older ffmpeg (13 Aug 2007) */
- bits = (uint8_t) 16;
-#endif
if (!audio_format_init_checked(&audio_format,
- codec_context->sample_rate, bits,
+ codec_context->sample_rate,
+ ffmpeg_sample_format(codec_context),
codec_context->channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
diff --git a/src/decoder/flac_pcm.c b/src/decoder/flac_pcm.c
index 737d5b043..a8bf6f293 100644
--- a/src/decoder/flac_pcm.c
+++ b/src/decoder/flac_pcm.c
@@ -20,6 +20,8 @@
#include "config.h"
#include "flac_pcm.h"
+#include <assert.h>
+
static void flac_convert_stereo16(int16_t *dest,
const FLAC__int32 * const buf[],
unsigned int position, unsigned int end)
@@ -74,12 +76,12 @@ flac_convert_8(int8_t *dest,
void
flac_convert(void *dest,
- unsigned int num_channels, unsigned sample_format,
+ unsigned int num_channels, enum sample_format sample_format,
const FLAC__int32 *const buf[],
unsigned int position, unsigned int end)
{
switch (sample_format) {
- case 16:
+ case SAMPLE_FORMAT_S16:
if (num_channels == 2)
flac_convert_stereo16((int16_t*)dest, buf,
position, end);
@@ -88,15 +90,19 @@ flac_convert(void *dest,
position, end);
break;
- case 24:
- case 32:
+ case SAMPLE_FORMAT_S24_P32:
+ case SAMPLE_FORMAT_S32:
flac_convert_32((int32_t*)dest, num_channels, buf,
position, end);
break;
- case 8:
+ case SAMPLE_FORMAT_S8:
flac_convert_8((int8_t*)dest, num_channels, buf,
position, end);
break;
+
+ case SAMPLE_FORMAT_UNDEFINED:
+ /* unreachable */
+ assert(false);
}
}
diff --git a/src/decoder/flac_pcm.h b/src/decoder/flac_pcm.h
index dca9d6824..4d7a51c4d 100644
--- a/src/decoder/flac_pcm.h
+++ b/src/decoder/flac_pcm.h
@@ -20,11 +20,13 @@
#ifndef MPD_FLAC_PCM_H
#define MPD_FLAC_PCM_H
+#include "audio_format.h"
+
#include <FLAC/ordinals.h>
void
flac_convert(void *dest,
- unsigned int num_channels, unsigned sample_format,
+ unsigned int num_channels, enum sample_format sample_format,
const FLAC__int32 *const buf[],
unsigned int position, unsigned int end);
diff --git a/src/decoder/fluidsynth_plugin.c b/src/decoder/fluidsynth_plugin.c
index 3e8a4edc4..1b1e6a531 100644
--- a/src/decoder/fluidsynth_plugin.c
+++ b/src/decoder/fluidsynth_plugin.c
@@ -88,7 +88,7 @@ fluidsynth_file_decode(struct decoder *decoder, const char *path_fs)
{
static const struct audio_format audio_format = {
.sample_rate = 48000,
- .bits = 16,
+ .format = SAMPLE_FORMAT_S16,
.channels = 2,
};
char setting_sample_rate[] = "synth.sample-rate";
diff --git a/src/decoder/mad_plugin.c b/src/decoder/mad_plugin.c
index da93fe45b..cba40aea0 100644
--- a/src/decoder/mad_plugin.c
+++ b/src/decoder/mad_plugin.c
@@ -1188,7 +1188,8 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
}
if (!audio_format_init_checked(&audio_format,
- data.frame.header.samplerate, 24,
+ data.frame.header.samplerate,
+ SAMPLE_FORMAT_S24_P32,
MAD_NCHANNELS(&data.frame.header),
&error)) {
g_warning("%s", error->message);
diff --git a/src/decoder/mikmod_plugin.c b/src/decoder/mikmod_plugin.c
index 204dd5ce0..1e64aeffd 100644
--- a/src/decoder/mikmod_plugin.c
+++ b/src/decoder/mikmod_plugin.c
@@ -163,7 +163,7 @@ 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, 16, 2);
+ audio_format_init(&audio_format, mikmod_sample_rate, SAMPLE_FORMAT_S16, 2);
assert(audio_format_valid(&audio_format));
decoder_initialized(decoder, &audio_format, false, 0);
diff --git a/src/decoder/modplug_plugin.c b/src/decoder/modplug_plugin.c
index 6c08c2199..02292992d 100644
--- a/src/decoder/modplug_plugin.c
+++ b/src/decoder/modplug_plugin.c
@@ -122,7 +122,7 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
return;
}
- audio_format_init(&audio_format, 44100, 16, 2);
+ audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2);
assert(audio_format_valid(&audio_format));
decoder_initialized(decoder, &audio_format,
diff --git a/src/decoder/mp4ff_plugin.c b/src/decoder/mp4ff_plugin.c
index 70ca4bdc3..8d3a4b9e9 100644
--- a/src/decoder/mp4ff_plugin.c
+++ b/src/decoder/mp4ff_plugin.c
@@ -132,7 +132,8 @@ mp4_faad_new(mp4ff_t *mp4fh, int *track_r, struct audio_format *audio_format)
return NULL;
}
- if (!audio_format_init_checked(audio_format, sample_rate, 16, channels,
+ if (!audio_format_init_checked(audio_format, sample_rate,
+ SAMPLE_FORMAT_S16, channels,
&error)) {
g_warning("%s", error->message);
g_error_free(error);
diff --git a/src/decoder/mpcdec_plugin.c b/src/decoder/mpcdec_plugin.c
index d985f8459..2f1936e55 100644
--- a/src/decoder/mpcdec_plugin.c
+++ b/src/decoder/mpcdec_plugin.c
@@ -196,7 +196,8 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
mpc_demux_get_info(demux, &info);
#endif
- if (!audio_format_init_checked(&audio_format, info.sample_freq, 24,
+ if (!audio_format_init_checked(&audio_format, info.sample_freq,
+ SAMPLE_FORMAT_S24_P32,
info.channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
diff --git a/src/decoder/mpg123_decoder_plugin.c b/src/decoder/mpg123_decoder_plugin.c
index 922e56484..62e6b00b0 100644
--- a/src/decoder/mpg123_decoder_plugin.c
+++ b/src/decoder/mpg123_decoder_plugin.c
@@ -87,7 +87,7 @@ mpd_mpg123_open(mpg123_handle *handle, const char *path_fs,
return false;
}
- if (!audio_format_init_checked(audio_format, rate, 16,
+ if (!audio_format_init_checked(audio_format, rate, SAMPLE_FORMAT_S16,
channels, &gerror)) {
g_warning("%s", gerror->message);
g_error_free(gerror);
diff --git a/src/decoder/sidplay_plugin.cxx b/src/decoder/sidplay_plugin.cxx
index b6e557e08..63e46a285 100644
--- a/src/decoder/sidplay_plugin.cxx
+++ b/src/decoder/sidplay_plugin.cxx
@@ -277,7 +277,7 @@ 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, 16, 2);
+ audio_format_init(&audio_format, 48000, SAMPLE_FORMAT_S16, 2);
assert(audio_format_valid(&audio_format));
decoder_initialized(decoder, &audio_format, true, (float)song_len);
diff --git a/src/decoder/sndfile_decoder_plugin.c b/src/decoder/sndfile_decoder_plugin.c
index 84835c449..fee0f8292 100644
--- a/src/decoder/sndfile_decoder_plugin.c
+++ b/src/decoder/sndfile_decoder_plugin.c
@@ -130,7 +130,8 @@ 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, 32,
+ if (!audio_format_init_checked(&audio_format, info.samplerate,
+ SAMPLE_FORMAT_S32,
info.channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
diff --git a/src/decoder/vorbis_plugin.c b/src/decoder/vorbis_plugin.c
index 3a41869a0..cb61e5999 100755
--- a/src/decoder/vorbis_plugin.c
+++ b/src/decoder/vorbis_plugin.c
@@ -311,7 +311,8 @@ vorbis_stream_decode(struct decoder *decoder,
return;
}
- if (!audio_format_init_checked(&audio_format, vi->rate, 16,
+ if (!audio_format_init_checked(&audio_format, vi->rate,
+ SAMPLE_FORMAT_S16,
vi->channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
diff --git a/src/decoder/wavpack_plugin.c b/src/decoder/wavpack_plugin.c
index 9b32a79f2..dffa078f9 100644
--- a/src/decoder/wavpack_plugin.c
+++ b/src/decoder/wavpack_plugin.c
@@ -123,6 +123,33 @@ 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
+wavpack_bits_to_sample_format(bool is_float, int bytes_per_sample)
+{
+ if (is_float)
+ return SAMPLE_FORMAT_S24_P32;
+
+ switch (bytes_per_sample) {
+ case 1:
+ return SAMPLE_FORMAT_S8;
+
+ case 2:
+ return SAMPLE_FORMAT_S16;
+
+ case 3:
+ return SAMPLE_FORMAT_S24_P32;
+
+ case 4:
+ return SAMPLE_FORMAT_S32;
+
+ default:
+ return SAMPLE_FORMAT_UNDEFINED;
+ }
+}
+
/*
* This does the main decoding thing.
* Requires an already opened WavpackContext.
@@ -132,7 +159,8 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
struct replay_gain_info *replay_gain_info)
{
GError *error = NULL;
- unsigned bits;
+ bool is_float;
+ enum sample_format sample_format;
struct audio_format audio_format;
format_samples_t format_samples;
char chunk[CHUNK_SIZE];
@@ -141,19 +169,14 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
int bytes_per_sample, output_sample_size;
int position;
- bits = WavpackGetBitsPerSample(wpc);
-
- /* round bitwidth to 8-bit units */
- bits = (bits + 7) & (~7);
- /* MPD handles max 32-bit samples */
- if (bits > 32)
- bits = 32;
-
- if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT)
- bits = 24;
+ is_float = (WavpackGetMode(wpc) & MODE_FLOAT) != 0;
+ sample_format =
+ wavpack_bits_to_sample_format(is_float,
+ WavpackGetBytesPerSample(wpc));
if (!audio_format_init_checked(&audio_format,
- WavpackGetSampleRate(wpc), bits,
+ WavpackGetSampleRate(wpc),
+ sample_format,
WavpackGetNumChannels(wpc), &error)) {
g_warning("%s", error->message);
g_error_free(error);
diff --git a/src/decoder/wildmidi_plugin.c b/src/decoder/wildmidi_plugin.c
index 718f24c2e..70b4d5ef9 100644
--- a/src/decoder/wildmidi_plugin.c
+++ b/src/decoder/wildmidi_plugin.c
@@ -59,7 +59,7 @@ wildmidi_file_decode(struct decoder *decoder, const char *path_fs)
{
static const struct audio_format audio_format = {
.sample_rate = WILDMIDI_SAMPLE_RATE,
- .bits = 16,
+ .format = SAMPLE_FORMAT_S16,
.channels = 2,
};
midi *wm;