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