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