From af96e1ce92c751f92cdb862985d1abe7362a6e59 Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Wed, 13 Oct 2010 19:04:46 +0200 Subject: Resample files when transcoding to mp3 using libsamplerate. --- decoders/decoder_flac.c | 32 +++++++++++++++++++++++--------- decoders/decoder_mpg123.c | 24 ++++++++++++++++++------ 2 files changed, 41 insertions(+), 15 deletions(-) (limited to 'decoders') diff --git a/decoders/decoder_flac.c b/decoders/decoder_flac.c index 805ab78..fd85f48 100644 --- a/decoders/decoder_flac.c +++ b/decoders/decoder_flac.c @@ -13,7 +13,8 @@ struct flac_decoder_data { }; static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) { - struct flac_decoder_data *decoder_data = client_data; + struct decoder *_decoder = client_data; + struct flac_decoder_data *decoder_data = _decoder->data; *bytes = g_input_stream_read(decoder_data->input, buffer, *bytes, NULL, NULL); @@ -29,7 +30,8 @@ static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *de static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { - struct flac_decoder_data *decoder_data = client_data; + struct decoder *_decoder = client_data; + struct flac_decoder_data *decoder_data = _decoder->data; unsigned channels = frame->header.channels; //unsigned sample_rate = frame->header.sample_rate; @@ -57,16 +59,28 @@ static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder * } } +static void metadata_callback(const FLAC__StreamDecoder *_decoder, const FLAC__StreamMetadata *metadata, void *client_data) { + struct decoder *decoder = client_data; + decoder->rate = metadata->data.stream_info.sample_rate; + switch(metadata->data.stream_info.bits_per_sample) { + case 16: + decoder->format = AUDIO_FORMAT_S16LE; + break; + } + decoder->channels = metadata->data.stream_info.channels; + g_debug("flac: %d Hz, %dch, %d bps", decoder->rate, decoder->channels, metadata->data.stream_info.bits_per_sample); +} + static void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { g_warning(FLAC__StreamDecoderErrorStatusString[status]); } -static gboolean flac_decoder_init(gpointer *data) { +static gboolean flac_decoder_init(struct decoder *decoder) { struct flac_decoder_data *decoder_data = g_new0(struct flac_decoder_data, 1); decoder_data->decoder = FLAC__stream_decoder_new(); FLAC__StreamDecoderInitStatus status = FLAC__stream_decoder_init_stream(decoder_data->decoder, - read_callback, NULL, NULL, NULL, NULL, write_callback, NULL, error_callback, decoder_data); - *data = decoder_data; + read_callback, NULL, NULL, NULL, NULL, write_callback, metadata_callback, error_callback, decoder); + decoder->data = decoder_data; if(status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { g_warning(FLAC__StreamDecoderInitStatusString[status]); @@ -78,9 +92,9 @@ static gboolean flac_decoder_init(gpointer *data) { return TRUE; } -static gssize flac_decoder_decode(gpointer data, GInputStream *input, +static gssize flac_decoder_decode(struct decoder *decoder, GInputStream *input, GOutputStream *output, GError **error) { - struct flac_decoder_data *decoder_data = data; + struct flac_decoder_data *decoder_data = decoder->data; decoder_data->input = input; decoder_data->output = output; decoder_data->output_written = 0; @@ -105,8 +119,8 @@ static gssize flac_decoder_decode(gpointer data, GInputStream *input, return decoder_data->output_written; } -static void flac_decoder_close(gpointer data) { - struct flac_decoder_data *decoder_data = data; +static void flac_decoder_close(struct decoder *decoder) { + struct flac_decoder_data *decoder_data = decoder->data; FLAC__stream_decoder_finish(decoder_data->decoder); FLAC__stream_decoder_delete(decoder_data->decoder); g_free(decoder_data); diff --git a/decoders/decoder_mpg123.c b/decoders/decoder_mpg123.c index 50391f4..41d25c1 100644 --- a/decoders/decoder_mpg123.c +++ b/decoders/decoder_mpg123.c @@ -3,7 +3,7 @@ #include #include -static gboolean mpg123_decoder_init(gpointer *data) { +static gboolean mpg123_decoder_init(struct decoder *decoder) { mpg123_handle *handle; int error; @@ -24,14 +24,14 @@ static gboolean mpg123_decoder_init(gpointer *data) { mpg123_format_none(handle); mpg123_format(handle, 44100, 2, MPG123_ENC_SIGNED_16); - *data = handle; + decoder->data = handle; return TRUE; } -static gssize mpg123_decoder_decode(gpointer data, GInputStream *input, +static gssize mpg123_decoder_decode(struct decoder *decoder, GInputStream *input, GOutputStream *output, GError **error) { - mpg123_handle *handle = data; + mpg123_handle *handle = decoder->data; gssize size; int ret; const int inbuf_size = 0x400*8; @@ -55,6 +55,18 @@ static gssize mpg123_decoder_decode(gpointer data, GInputStream *input, mpg123_getformat(handle, &rate, &channels, &enc); g_debug("New format: %li Hz, %i channels, encoding value %i", rate, channels, enc); ret = mpg123_read(handle, outbuf, outbuf_size, (size_t*)&size); + decoder->rate = rate; + /* TODO: mpg123 uses native byte order, add endian check here */ + /* assuming little endian for now... */ + switch(enc) { + case MPG123_ENC_SIGNED_16: + decoder->format = AUDIO_FORMAT_S16LE; + break; + default: + *error = g_error_new(decoder_quark(), DECODER_CODE_ERROR, g_strdup("unknown audio format")); + return -1; + } + decoder->channels = channels; } if(ret != MPG123_OK && ret != MPG123_DONE && ret != MPG123_NEW_FORMAT @@ -68,8 +80,8 @@ static gssize mpg123_decoder_decode(gpointer data, GInputStream *input, return size; } -static void mpg123_decoder_close(gpointer data) { - mpg123_handle *handle = data; +static void mpg123_decoder_close(struct decoder *decoder) { + mpg123_handle *handle = decoder->data; mpg123_close(handle); mpg123_delete(handle); } -- cgit v1.2.3