summaryrefslogtreecommitdiff
path: root/transcode.c
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 /transcode.c
parent18399d8f41e0154af266f43fd4a05420cb335aa7 (diff)
Resample files when transcoding to mp3 using libsamplerate.
Diffstat (limited to 'transcode.c')
-rw-r--r--transcode.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/transcode.c b/transcode.c
index 9bef8e7..20f91b5 100644
--- a/transcode.c
+++ b/transcode.c
@@ -1,4 +1,5 @@
#include "transcode.h"
+#include "resample.h"
#include <glib.h>
@@ -17,6 +18,8 @@ void transcode(GInputStream *input, const struct decoder_plugin *_decoder,
/* holds decoded audio passed to encoder */
GInputStream *decoded_in = g_memory_input_stream_new();
+ SRC_STATE *state = NULL;
+
while(decode_done == FALSE || encode_done == FALSE) {
/* holds decoded audio from decoder */
GOutputStream *decoded_out = g_memory_output_stream_new(NULL, 0, g_realloc, g_free);
@@ -38,7 +41,30 @@ void transcode(GInputStream *input, const struct decoder_plugin *_decoder,
gsize size = g_memory_output_stream_get_data_size((GMemoryOutputStream*)decoded_out);
if(size > 0) {
- data = g_memdup(data, size);
+ /* TODO: allow custom sample rate */
+ if(decoder->rate != 44100) {
+ if(state == NULL) {
+ state = resample_init(decoder->channels, &error);
+ /* state should be NULL in case of errors */
+ if(error) {
+ g_warning(error->message);
+ break;
+ }
+ }
+ gpointer out_data;
+ gsize out_size;
+ resample(state, decoder->rate, 44100, decoder->channels, data, size, &out_data, &out_size, decode_done, &error);
+ if(error) {
+ g_warning(error->message);
+ g_error_free(error);
+ error = NULL;
+ }
+ /* data is owned by decoded_out, don't free */
+ data = out_data;
+ size = out_size;
+ } else {
+ data = g_memdup(data, size);
+ }
g_memory_input_stream_add_data((GMemoryInputStream*)decoded_in, data, size, g_free);
}
@@ -61,6 +87,16 @@ void transcode(GInputStream *input, const struct decoder_plugin *_decoder,
g_debug("transcoding done");
+ /* error cleanup */
+ if(error) {
+ g_error_free(error);
+ }
+
+ /* resample cleanup */
+ if(state) {
+ resample_free(state);
+ }
+
g_object_unref(decoded_in);
decoder_close(decoder);