1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 *
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <math.h>
11
12 #include "uvoice_os.h"
13 #include "uvoice_audio.h"
14 #include "uvoice_common.h"
15 #include "audio_common.h"
16 #include "audio_stream.h"
17
18 #include "opensource/speexdsp/include/speex/speex_resampler.h"
19
20
21 #define SPEEX_RESAMPLE_ENABLE
22
23
24 typedef struct {
25 int sbits;
26 int channels;
27 int src_rate;
28 int dst_rate;
29 uint8_t *out_buffer;
30 float *fin;
31 float *fout;
32 int out_buffer_size;
33 int fin_samples;
34 int fout_samples;
35 int out_coeff;
36 int sample_bytes;
37 int quality;
38 SpeexResamplerState *speex_state;
39 os_mutex_t lock;
40 } resampler_inst_t;
41
42
float_to_short_interleave(short * output,float * input,int samples_per_channel,int channels)43 static void float_to_short_interleave(short *output, float *input,
44 int samples_per_channel, int channels)
45 {
46 int channel_index;
47 int sample_index;
48
49 for (channel_index = 0; channel_index < channels; channel_index++) {
50 input += samples_per_channel * channel_index;
51 for (sample_index = 0; sample_index < samples_per_channel; sample_index++)
52 output[channels * sample_index + channel_index] = (short)input[sample_index];
53 //floor(.5 + input[sample_index]);
54 }
55 }
56
short_to_float_deinterleave(float * output,short * input,int samples_per_channel,int channels,int channel_gap)57 static void short_to_float_deinterleave(float *output, short *input,
58 int samples_per_channel, int channels, int channel_gap)
59 {
60 int channel_index;
61 int sample_index;
62
63 for (channel_index = 0; channel_index < channels; channel_index++) {
64 for (sample_index = 0; sample_index < samples_per_channel; sample_index++)
65 output[sample_index] =
66 (float)input[channels * sample_index + channel_index];
67 output += channel_gap;
68 }
69 }
70
uvoice_resampler_process(void * resampler,uint8_t * input,int input_len,uint8_t ** output,int * output_len)71 int uvoice_resampler_process(void *resampler, uint8_t *input, int input_len,
72 uint8_t **output, int *output_len)
73 {
74 resampler_inst_t *inst = (resampler_inst_t *)resampler;
75 spx_uint32_t ilen;
76 spx_uint32_t olen;
77 int input_samples;
78 int fin_samples;
79 int fout_samples;
80 int out_buffer_size;
81 spx_uint32_t output_samples;
82 int channels;
83 int temp;
84 int ret;
85 int i;
86
87 if (!inst) {
88 *output = input;
89 *output_len = input_len;
90 return 0;
91 }
92
93 os_mutex_lock(inst->lock, OS_WAIT_FOREVER);
94
95 if (inst->src_rate == inst->dst_rate) {
96 *output = input;
97 *output_len = input_len;
98 os_mutex_unlock(inst->lock);
99 return 0;
100 }
101
102 channels = inst->channels;
103 input_samples = (input_len / inst->sample_bytes) / channels;
104 fin_samples = (input_samples / 100 + 1) * 100;
105 fout_samples = fin_samples * inst->out_coeff;
106
107 #ifdef SPEEX_RESAMPLE_ENABLE
108 if (fin_samples != inst->fin_samples) {
109 if (inst->fin) {
110 snd_free(inst->fin);
111 inst->fin = NULL;
112 inst->fin_samples = 0;
113 }
114 inst->fin = snd_zalloc(
115 fin_samples * sizeof(float) * inst->channels,
116 AFM_EXTN);
117 if (!inst->fin) {
118 M_LOGE("alloc fin buffer fail !\n");
119 os_mutex_unlock(inst->lock);
120 return -1;
121 }
122 inst->fin_samples = fin_samples;
123 }
124
125 if (fout_samples != inst->fout_samples) {
126 if (inst->fout) {
127 snd_free(inst->fout);
128 inst->fout = NULL;
129 inst->fout_samples = 0;
130 }
131 inst->fout = snd_zalloc(
132 fout_samples * sizeof(float) * inst->channels,
133 AFM_EXTN);
134 if (!inst->fout) {
135 M_LOGE("alloc fout buffer fail !\n");
136 os_mutex_unlock(inst->lock);
137 return -1;
138 }
139 inst->fout_samples = fout_samples;
140 }
141 #endif
142
143 out_buffer_size = fout_samples * channels * inst->sample_bytes;
144 if (inst->out_buffer_size != out_buffer_size) {
145 if (inst->out_buffer)
146 snd_free(inst->out_buffer);
147
148 inst->out_buffer = snd_zalloc(out_buffer_size, AFM_MAIN);
149 if (!inst->out_buffer) {
150 M_LOGE("alloc out buffer fail !\n");
151 os_mutex_unlock(inst->lock);
152 return -1;
153 }
154 inst->out_buffer_size = out_buffer_size;
155 }
156
157 #ifdef SPEEX_RESAMPLE_ENABLE
158 short_to_float_deinterleave(inst->fin,
159 (short *)input, input_samples, channels, inst->fin_samples);
160
161 output_samples = 0;
162
163 for (i = 0; i < channels; i++) {
164 ilen = (spx_uint32_t)input_samples;
165 olen = (spx_uint32_t)inst->fout_samples;
166 ret = speex_resampler_process_float(inst->speex_state, i,
167 (const float *)(inst->fin + inst->fin_samples * i),
168 &ilen,
169 inst->fout + output_samples, &olen);
170 if (ret != RESAMPLER_ERR_SUCCESS) {
171 M_LOGE("resampler error %d\n", ret);
172 }
173
174 if (ilen < input_samples) {
175 M_LOGW("input %d samples, consum %u samples\n",
176 input_samples, ilen);
177 }
178
179 output_samples += olen;
180 }
181
182 float_to_short_interleave((short *)inst->out_buffer, inst->fout,
183 output_samples / channels, channels);
184
185 *output = inst->out_buffer;
186 *output_len = output_samples * inst->sample_bytes;
187
188 #else
189 short *input_ptr = (short *)input;
190 short *output_ptr = (short *)inst->out_buffer;
191 int sample_value;
192 for (i = 0; i < input_samples; i++) {
193 output_ptr[i * 2] = input_ptr[i];
194 if (i == input_samples - 1)
195 sample_value = input_ptr[i];
196 else
197 sample_value = (input_ptr[i] + input_ptr[i + 1]) / 2;
198 output_ptr[i * 2 + 1] = (short)sample_value;
199 }
200 *output = inst->out_buffer;
201 *output_len = input_samples * 2 * inst->sample_bytes;
202 #endif
203
204 os_mutex_unlock(inst->lock);
205 return 0;
206 }
207
uvoice_resampler_update(void * resampler,int src_rate,int dst_rate,int channels,int sbits)208 int uvoice_resampler_update(void *resampler, int src_rate, int dst_rate, int channels,
209 int sbits)
210 {
211 resampler_inst_t *inst = (resampler_inst_t *)resampler;
212 int out_coeff;
213 int i;
214
215 if (!inst) {
216 M_LOGE("no resampler !\n");
217 return -1;
218 }
219
220 os_mutex_lock(inst->lock, OS_WAIT_FOREVER);
221
222 if (inst->channels == channels && inst->sbits == sbits &&
223 inst->src_rate == src_rate && inst->dst_rate == dst_rate) {
224 os_mutex_unlock(inst->lock);
225 return 0;
226 }
227
228 if (inst->channels != channels)
229 inst->channels = channels;
230
231 if (inst->sbits != sbits) {
232 inst->sbits = sbits;
233 inst->sample_bytes = sbits >> 3;
234 }
235
236 if (inst->src_rate != src_rate ||
237 inst->dst_rate != dst_rate) {
238 inst->src_rate = src_rate;
239 inst->dst_rate = dst_rate;
240 out_coeff = (inst->dst_rate / inst->src_rate) + 1;
241 if (inst->out_coeff != out_coeff) {
242 inst->out_coeff = out_coeff;
243 M_LOGD("update coeff %d\n", inst->out_coeff);
244 }
245 #ifdef SPEEX_RESAMPLE_ENABLE
246 M_LOGI("speex resampler update, %d->%d\n",
247 inst->src_rate, inst->dst_rate);
248 speex_resampler_set_rate(inst->speex_state,
249 (spx_uint32_t)inst->src_rate,
250 (spx_uint32_t)inst->dst_rate);
251 #endif
252 }
253
254 os_mutex_unlock(inst->lock);
255 return 0;
256 }
257
uvoice_resampler_create(void ** resampler,int src_rate,int dst_rate,int channels,int sbits)258 int uvoice_resampler_create(void **resampler, int src_rate, int dst_rate,
259 int channels, int sbits)
260 {
261 resampler_inst_t *inst;
262 int err = 0;
263 int ret;
264
265 if (!resampler)
266 return -1;
267
268 inst = snd_zalloc(sizeof(resampler_inst_t), AFM_EXTN);
269 if (!inst) {
270 M_LOGE("alloc resampler inst fail !\n");
271 return -1;
272 }
273
274 inst->lock = os_mutex_new();
275
276 inst->src_rate = src_rate;
277 inst->dst_rate = dst_rate;
278 inst->sbits = sbits;
279 inst->channels = channels;
280 inst->quality = 0;
281
282 inst->out_coeff = (dst_rate / src_rate) + 1;
283 inst->sample_bytes = sbits >> 3;
284
285 #ifdef SPEEX_RESAMPLE_ENABLE
286 inst->speex_state = speex_resampler_init((spx_uint32_t)channels,
287 (spx_uint32_t)src_rate,
288 (spx_uint32_t)dst_rate,
289 inst->quality, &err);
290 if (!inst->speex_state) {
291 M_LOGE("init speex resampler fail %d!\n", err);
292 os_mutex_free(inst->lock);
293 snd_free(inst);
294 return -1;
295 }
296
297 speex_resampler_skip_zeros(inst->speex_state);
298 #endif
299
300 *resampler = inst;
301 M_LOGI("speex resampler create, %d->%d\n", inst->src_rate, inst->dst_rate);
302 return 0;
303 }
304
uvoice_resampler_release(void * resampler)305 int uvoice_resampler_release(void *resampler)
306 {
307 resampler_inst_t *inst = (resampler_inst_t *)resampler;
308
309 if (!inst) {
310 M_LOGI("no resampler\n");
311 return 0;
312 }
313
314 if (inst->fout)
315 snd_free(inst->fout);
316
317 if (inst->fin)
318 snd_free(inst->fin);
319
320 if (inst->out_buffer)
321 snd_free(inst->out_buffer);
322
323 #ifdef SPEEX_RESAMPLE_ENABLE
324 speex_resampler_destroy(inst->speex_state);
325 #endif
326
327 os_mutex_free(inst->lock);
328 snd_free(inst);
329
330 M_LOGI("speex resampler release\n");
331 return 0;
332 }
333
334