diff options
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); +} |