1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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);
}
|