summaryrefslogtreecommitdiff
path: root/decoders
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2010-10-13 19:04:46 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2010-10-13 19:04:46 +0200
commitaf96e1ce92c751f92cdb862985d1abe7362a6e59 (patch)
treebecd9199f426f2b53cca4f40eba443e8a6e94196 /decoders
parent18399d8f41e0154af266f43fd4a05420cb335aa7 (diff)
Resample files when transcoding to mp3 using libsamplerate.
Diffstat (limited to 'decoders')
-rw-r--r--decoders/decoder_flac.c32
-rw-r--r--decoders/decoder_mpg123.c24
2 files changed, 41 insertions, 15 deletions
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 <mpg123.h>
#include <stdio.h>
-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);
}