diff options
author | Jon Bergli Heier <snakebite@jvnv.net> | 2010-10-13 19:04:46 +0200 |
---|---|---|
committer | Jon Bergli Heier <snakebite@jvnv.net> | 2010-10-13 19:04:46 +0200 |
commit | af96e1ce92c751f92cdb862985d1abe7362a6e59 (patch) | |
tree | becd9199f426f2b53cca4f40eba443e8a6e94196 /resample.c | |
parent | 18399d8f41e0154af266f43fd4a05420cb335aa7 (diff) |
Resample files when transcoding to mp3 using libsamplerate.
Diffstat (limited to 'resample.c')
-rw-r--r-- | resample.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/resample.c b/resample.c new file mode 100644 index 0000000..c77367e --- /dev/null +++ b/resample.c @@ -0,0 +1,54 @@ +#include "resample.h" + +#include <stdint.h> + +static GQuark resample_quark() { + return g_quark_from_string("resample"); +} + +SRC_STATE *resample_init(int channels, GError **error) { + int err; + SRC_STATE *state = src_new(SRC_LINEAR, channels, &err); + if(!state) { + *error = g_error_new(resample_quark(), 0, g_strdup(src_strerror(err))); + } + + return state; +} + +void resample(SRC_STATE *state, unsigned int from_rate, unsigned int to_rate, int channels, + gpointer in_data, gsize in_size, gpointer *out_data, gsize *out_size, gboolean done, GError **error) { + int len = in_size / 2; + int frames = in_size / 2 / channels; + float *temp_in = g_new(float, len); + float *temp_out = g_new(float, len); + + src_short_to_float_array(in_data, temp_in, len); + + SRC_DATA data = { + .data_in = temp_in, + .data_out = temp_out, + .input_frames = frames, + .output_frames = frames, + .src_ratio = (double)to_rate / (double)from_rate, + .end_of_input = done ? 1 : 0 + }; + + int err = src_process(state, &data); + if(err) { + *error = g_error_new(resample_quark(), 0, g_strdup(src_strerror(err))); + goto resample_free; + } + + *out_data = g_new(int16_t, data.output_frames_gen * channels); + src_float_to_short_array(temp_out, *out_data, data.output_frames_gen * channels); + *out_size = sizeof(int16_t) * data.output_frames_gen * channels; + +resample_free: + g_free(temp_in); + g_free(temp_out); +} + +void resample_free(SRC_STATE *state) { + src_delete(state); +} |