blob: f124ed1f761f7965f257b57f532449acea3dc330
1 | |
2 | |
3 | #include <stdio.h> |
4 | #include <unistd.h> |
5 | #include <stdlib.h> |
6 | #include <fcntl.h> |
7 | #include <string.h> |
8 | #include <errno.h> |
9 | #include <linux/fb.h> |
10 | #include <sys/system_properties.h> |
11 | #include <log-print.h> |
12 | #include <cutils/properties.h> |
13 | #include "aml_resample.h" |
14 | #include "Amsysfsutils.h" |
15 | #include "amconfigutils.h" |
16 | |
17 | |
18 | af_resampe_ctl_t af_resampler_ctx = {0}; |
19 | static int pcmfd = -1; |
20 | static int get_sysfs_int(const char *path) |
21 | { |
22 | int fd; |
23 | int val = 0; |
24 | char bcmd[16] = {0};; |
25 | fd = open(path, O_RDONLY); |
26 | if (fd >= 0) { |
27 | read(fd, bcmd, 16); |
28 | if (bcmd[0] == 'O' && bcmd[1] == 'N') { |
29 | val = 1; |
30 | } |
31 | |
32 | else if (bcmd[0] == 'O' && bcmd[1] == 'F') { |
33 | val = 0; |
34 | } |
35 | |
36 | else if (bcmd[0] == 'N' && bcmd[1] == 'O') { |
37 | val = 0; |
38 | } |
39 | |
40 | else if (bcmd[0] == 'D' && bcmd[1] == 'W') { |
41 | val = 1; |
42 | } |
43 | |
44 | else if (bcmd[0] == 'U' && bcmd[1] == 'P') { |
45 | val = 2; |
46 | } |
47 | |
48 | //adec_print("value=%s coresponding val=%d\n",bcmd,val); |
49 | |
50 | close(fd); |
51 | } else { |
52 | //adec_print("open %s failed\n",path); |
53 | } |
54 | return val; |
55 | } |
56 | |
57 | static int get_sysfs_str(const char *path, char *valstr, int size) |
58 | { |
59 | return amsysfs_get_sysfs_str(path, valstr, size); |
60 | } |
61 | |
62 | |
63 | int af_get_resample_enable_flag() |
64 | { |
65 | //return get_sysfs_int("sys/class/amaudio/enable_resample"); |
66 | return af_resampler_ctx.enable_resample; |
67 | } |
68 | |
69 | int af_get_resample_type() |
70 | { |
71 | //return get_sysfs_int("sys/class/amaudio/resample_type"); |
72 | return af_resampler_ctx.resample_type; |
73 | } |
74 | |
75 | int af_set_resample_type(int val) |
76 | { |
77 | //return amsysfs_set_sysfs_int("sys/class/amaudio/resample_type", val); |
78 | af_resampler_ctx.resample_type = val; |
79 | return 1; |
80 | } |
81 | |
82 | |
83 | void af_resample_linear_init(struct aml_audio_dec *audec) |
84 | { |
85 | char value[1028] = {0}; |
86 | af_resampe_ctl_t *paf_resampe_ctl; |
87 | paf_resampe_ctl = &af_resampler_ctx; |
88 | memset(paf_resampe_ctl, 0, sizeof(af_resampe_ctl_t)); |
89 | adec_print("af_resample_linear_init 140821-1407"); |
90 | audec->pcrtsync_enable = 1; |
91 | if (property_get("media.libplayer.pcrtsync_enable", value, NULL) > 0) { |
92 | if (!strcmp(value, "0") || !strcmp(value, "false")) { |
93 | audec->pcrtsync_enable = 0; |
94 | } |
95 | } |
96 | if (audec->tsync_mode == TSYNC_MODE_PCRMASTER && audec->pcrtsync_enable) { |
97 | paf_resampe_ctl->enable_resample = 1; |
98 | if (property_get("media.libplayer.enable_resample", value, NULL) > 0) { |
99 | paf_resampe_ctl->enable_resample = atoi(value); |
100 | } |
101 | amsysfs_set_sysfs_int("sys/class/amaudio/enable_resample", paf_resampe_ctl->enable_resample); |
102 | //property_set("media.libplayer.resampledelta", "1"); |
103 | audec->fill_trackzero_thrsh = TIME_UNIT90K / 2; |
104 | if (property_get("media.libplayer.fillzerothrsh", value, NULL) > 0) { |
105 | audec->fill_trackzero_thrsh = atoi(value); |
106 | } |
107 | // add for dolby av sync test |
108 | if (property_get("media.libplayer.dolby_test", value, NULL) > 0) { |
109 | audec->fill_trackzero_thrsh = 27000; |
110 | } |
111 | audec->pcrmaster_droppcm_thsh = TIME_UNIT90K / 2; |
112 | if (property_get("media.libplayer.pcrdroppcmthsh", value, NULL) > 0) { |
113 | audec->pcrmaster_droppcm_thsh = atoi(value); |
114 | } |
115 | if (pcmfd == -1) { |
116 | pcmfd = open("/data/tmp/pcmdump.dat", O_CREAT | O_RDWR, 0666); |
117 | if (pcmfd < 0) { |
118 | adec_print("creat pcmdump failed!fd=%d\n", pcmfd); |
119 | } |
120 | } |
121 | adec_print("## pcrmaster enable resample,tsync_enable:%d, fill_trackzero_thrsh:%d, ! --\n", audec->pcrtsync_enable, audec->fill_trackzero_thrsh); |
122 | } |
123 | } |
124 | |
125 | void af_resample_linear_stop(struct aml_audio_dec *audec) |
126 | { |
127 | adec_print("[%s:%d]", __FUNCTION__, __LINE__); |
128 | if (audec->tsync_mode == TSYNC_MODE_PCRMASTER) { |
129 | amsysfs_set_sysfs_int("sys/class/amaudio/enable_resample", 0); |
130 | if (pcmfd >= 0) { |
131 | close(pcmfd); |
132 | pcmfd = -1; |
133 | } |
134 | adec_print("## pcrmaster recovery enable_resample! --\n"); |
135 | } |
136 | } |
137 | |
138 | static int dsp_pcm_read(aml_audio_dec_t*audec, char *data_in, int len) |
139 | { |
140 | int pcm_ret = 0, pcm_cnt_bytes = 0; |
141 | int wait_times = 0; |
142 | while (pcm_cnt_bytes < len) { |
143 | pcm_ret = audec->adsp_ops.dsp_read(&audec->adsp_ops, data_in + pcm_cnt_bytes, len - pcm_cnt_bytes); |
144 | if (pcm_ret <= 0) { //indicate there is no data in dsp_buf,still try to read more data: |
145 | #if 0 |
146 | wait_times++; |
147 | adec_print("wait dsp times: %d\n", wait_times); |
148 | //usleep(20); |
149 | if (wait_times > 1) { |
150 | adec_print("NOTE:dsp no enough data!"); |
151 | break; |
152 | } |
153 | #else |
154 | //adec_print("can not read out PCM : %d\n", pcm_ret); |
155 | break; |
156 | #endif |
157 | } |
158 | pcm_cnt_bytes += pcm_ret; |
159 | } |
160 | audec->pcm_bytes_readed += pcm_cnt_bytes; |
161 | return pcm_cnt_bytes / sizeof(short); |
162 | } |
163 | |
164 | static int pcrmaster_dsp_pcm_read(aml_audio_dec_t*audec, char *data_in, int len) |
165 | { |
166 | int pcm_ret = 0, pcm_cnt_bytes = 0; |
167 | int wait_times = 0; |
168 | while (pcm_cnt_bytes < len) { |
169 | pcm_ret = audec->adsp_ops.dsp_read(&audec->adsp_ops, data_in + pcm_cnt_bytes, len - pcm_cnt_bytes); |
170 | if (pcm_ret <= 0) { //indicate there is no data in dsp_buf,still try to read more data: |
171 | #if 0 |
172 | wait_times++; |
173 | adec_print("wait dsp times: %d\n", wait_times); |
174 | //usleep(20); |
175 | if (wait_times > 1) { |
176 | adec_print("NOTE:dsp no enough data!"); |
177 | break; |
178 | } |
179 | #else |
180 | //adec_print("can not read out PCM : %d\n", pcm_ret); |
181 | break; |
182 | #endif |
183 | } |
184 | pcm_cnt_bytes += pcm_ret; |
185 | } |
186 | audec->pcm_bytes_readed += pcm_cnt_bytes; |
187 | return pcm_cnt_bytes; |
188 | } |
189 | |
190 | |
191 | void af_resample_api(char* buffer, unsigned int * size, int Chnum, aml_audio_dec_t* audec, int enable, int delta); |
192 | |
193 | void af_pcrmaster_resample_api(char *buffer, unsigned int *size, int Chnum, aml_audio_dec_t *audec/*, int enable, int delta*/) |
194 | { |
195 | int resample_delta = 0; |
196 | char value[1028] = {0}; |
197 | |
198 | int resample_enable = af_resampler_ctx.enable_resample;//enable; |
199 | |
200 | if (af_resampler_ctx.resample_type == RESAMPLE_TYPE_DOWN) { |
201 | resample_delta = 1; |
202 | if (property_get("media.libplayer.resampledelta", value, NULL) > 0) { |
203 | resample_delta = atoi(value); |
204 | } |
205 | } else if (af_resampler_ctx.resample_type == RESAMPLE_TYPE_UP) { |
206 | resample_delta = -1; |
207 | if (property_get("media.libplayer.resampledelta", value, NULL) > 0) { |
208 | resample_delta = -atoi(value); |
209 | } |
210 | } else if (af_resampler_ctx.resample_type == RESAMPLE_TYPE_NONE) { |
211 | resample_enable = 0; |
212 | resample_delta = 0; |
213 | } |
214 | //call normal resample api |
215 | af_resample_api(buffer, size, Chnum, audec, resample_enable, resample_delta); |
216 | } |
217 | |
218 | #if 1 |
219 | af_resampe_ctl_t* af_resampler_ctx_get() |
220 | { |
221 | return &af_resampler_ctx; |
222 | } |
223 | |
224 | static void af_resample_linear_coef_get(af_resampe_ctl_t *paf_resampe_ctl) |
225 | { |
226 | int SampNumIn = paf_resampe_ctl->SampNumIn; |
227 | int SampNumOut = paf_resampe_ctl->SampNumOut; |
228 | int *pCoefArray = paf_resampe_ctl->InterpolateCoefArray; |
229 | short *pindex = paf_resampe_ctl->InterpolateIndexArray; |
230 | int i; |
231 | int step_i = (((SampNumIn - 1)) << 14) / (SampNumOut - 1); |
232 | int step_forward = 0; |
233 | int insert_pos_int = 0; |
234 | |
235 | if (SampNumIn == SampNumOut) { |
236 | for (i = 0; i < SampNumOut; i++) { |
237 | pindex[i] = i; |
238 | pCoefArray[i] = 0; |
239 | } |
240 | return; |
241 | } |
242 | |
243 | step_forward = 0; |
244 | for (i = 1; i <= SampNumOut - 2; i++) { |
245 | step_forward += step_i; |
246 | insert_pos_int += Q14_INT_GET(step_forward); |
247 | pindex[i] = insert_pos_int; |
248 | pCoefArray[i] = Q14_FRA_GET(step_forward); |
249 | step_forward = Q14_FRA_GET(step_forward); |
250 | } |
251 | pindex[0] = 0; |
252 | pCoefArray[0] = 0; |
253 | pindex[SampNumOut - 1] = SampNumOut - 1; |
254 | pCoefArray[SampNumOut - 1] = 0; |
255 | } |
256 | |
257 | |
258 | static int audiodsp_set_pcm_resample_delta(int resample_num_delta) |
259 | { |
260 | int utils_fd, ret; |
261 | |
262 | utils_fd = open("/dev/amaudio_utils", O_RDWR); |
263 | if (utils_fd >= 0) { |
264 | ret = ioctl(utils_fd, AMAUDIO_IOC_SET_RESAMPLE_DELTA, resample_num_delta); |
265 | if (ret < 0) { |
266 | adec_print(" AMAUDIO_IOC_SET_RESAMPLE_DELTA failed\n"); |
267 | close(utils_fd); |
268 | return -1; |
269 | } |
270 | //adec_print("Notify kernel: <resample_num_delta=%d>\n",resample_num_delta); |
271 | close(utils_fd); |
272 | return 0; |
273 | } |
274 | return -1; |
275 | } |
276 | void af_resample_set_SampsNumRatio(af_resampe_ctl_t *paf_resampe_ctl) |
277 | { |
278 | char value[1028] = {0}; |
279 | int resample_type = af_get_resample_type(); |
280 | int default_DELTA_NUMSAMPS = RESAMPLE_DELTA_NUMSAMPS; |
281 | if (property_get("media.libplayer.resampledelta", value, NULL) > 0) { |
282 | default_DELTA_NUMSAMPS = atoi(value); |
283 | } |
284 | if (am_getconfig_bool("media.libplayer.wfd")) { |
285 | default_DELTA_NUMSAMPS = 2; |
286 | } |
287 | audiodsp_set_pcm_resample_delta(default_DELTA_NUMSAMPS); |
288 | paf_resampe_ctl->LastResamType = resample_type; |
289 | //adec_print("ReSample Coef Init: type/%d DELTA_NUMSAMPS/%d ",resample_type,default_DELTA_NUMSAMPS); |
290 | //memset(paf_resampe_ctl,0,sizeof(af_resampe_ctl_t)); |
291 | if (resample_type == RESAMPLE_TYPE_NONE) { |
292 | paf_resampe_ctl->SampNumIn = DEFALT_NUMSAMPS_PERCH; |
293 | paf_resampe_ctl->SampNumOut = DEFALT_NUMSAMPS_PERCH; |
294 | } else if (resample_type == RESAMPLE_TYPE_DOWN) { |
295 | paf_resampe_ctl->SampNumIn = DEFALT_NUMSAMPS_PERCH + default_DELTA_NUMSAMPS; |
296 | paf_resampe_ctl->SampNumOut = DEFALT_NUMSAMPS_PERCH ; |
297 | } else if (resample_type == RESAMPLE_TYPE_UP) { |
298 | paf_resampe_ctl->SampNumIn = DEFALT_NUMSAMPS_PERCH - default_DELTA_NUMSAMPS; |
299 | paf_resampe_ctl->SampNumOut = DEFALT_NUMSAMPS_PERCH; |
300 | } |
301 | af_resample_linear_coef_get(paf_resampe_ctl); |
302 | paf_resampe_ctl->ResevedSampsValid = 0; |
303 | paf_resampe_ctl->OutSampReserveLen = 0; |
304 | paf_resampe_ctl->InitFlag = 1; |
305 | |
306 | } |
307 | |
308 | |
309 | int af_get_delta_inputsampnum(af_resampe_ctl_t *paf_resampe_ctl, int Nch) |
310 | { |
311 | return paf_resampe_ctl->SampNumIn * Nch - paf_resampe_ctl->ResevedSampsValid; |
312 | |
313 | } |
314 | |
315 | void af_get_unpro_inputsampnum(af_resampe_ctl_t *paf_resampe_ctl, short *buf, int *num) |
316 | { |
317 | if (*num >= paf_resampe_ctl->ResevedSampsValid) { |
318 | memcpy(buf, paf_resampe_ctl->ResevedBuf, paf_resampe_ctl->ResevedSampsValid * sizeof(short)); |
319 | *num = paf_resampe_ctl->ResevedSampsValid; |
320 | paf_resampe_ctl->ResevedSampsValid = 0; |
321 | |
322 | } else { //*num < paf_resampe_ctl->ResevedSampsValid |
323 | memcpy(buf, paf_resampe_ctl->ResevedBuf, (*num)*sizeof(short)); |
324 | memmove(paf_resampe_ctl->ResevedBuf, |
325 | paf_resampe_ctl->ResevedBuf + (*num), |
326 | (paf_resampe_ctl->ResevedSampsValid - (*num))*sizeof(short) |
327 | ); |
328 | paf_resampe_ctl->ResevedSampsValid -= (*num); |
329 | } |
330 | |
331 | } |
332 | |
333 | |
334 | |
335 | void af_get_pcm_in_resampler(af_resampe_ctl_t *paf_resampe_ctl, short*buf, int *len) |
336 | { |
337 | int NumSamp_out = *len; |
338 | int rest_pcm_nums = 0; |
339 | if ((NumSamp_out >= 0) && (NumSamp_out < paf_resampe_ctl->OutSampReserveLen)) { |
340 | rest_pcm_nums = paf_resampe_ctl->OutSampReserveLen - NumSamp_out; |
341 | memcpy(buf, paf_resampe_ctl->OutSampReserveBuf, NumSamp_out * sizeof(short)); |
342 | memmove(paf_resampe_ctl->OutSampReserveBuf, |
343 | paf_resampe_ctl->OutSampReserveBuf + NumSamp_out, |
344 | rest_pcm_nums * sizeof(short)); |
345 | |
346 | } else if (NumSamp_out >= paf_resampe_ctl->OutSampReserveLen) { |
347 | memcpy(buf, paf_resampe_ctl->OutSampReserveBuf, |
348 | paf_resampe_ctl->OutSampReserveLen * sizeof(short)); |
349 | NumSamp_out = paf_resampe_ctl->OutSampReserveLen; |
350 | rest_pcm_nums = 0; |
351 | } |
352 | *len = NumSamp_out; |
353 | paf_resampe_ctl->OutSampReserveLen = rest_pcm_nums; |
354 | } |
355 | |
356 | void af_resample_process_linear_inner(af_resampe_ctl_t *paf_resampe_ctl, short *data_in, int *NumSamp_in, short* data_out, int* NumSamp_out, int NumCh) |
357 | { |
358 | |
359 | int index, ChId; |
360 | int NumSampsPerCh_in = (*NumSamp_in) / NumCh; |
361 | int NumSampsPerCh_Pre = paf_resampe_ctl->ResevedSampsValid / NumCh; |
362 | |
363 | int NumSampsPerCh_out; |
364 | short buf16_in[MAX_NUMSAMPS_PERCH]; |
365 | short buf16_in_valid; |
366 | short *pPreSamps = paf_resampe_ctl->ResevedBuf; |
367 | short *pindex = paf_resampe_ctl->InterpolateIndexArray; |
368 | int *pcoef = paf_resampe_ctl->InterpolateCoefArray; |
369 | int input_offset = 0, output_offset = 0; |
370 | int cur_out_samp_reserve_num = 0; |
371 | |
372 | if (!paf_resampe_ctl->InitFlag) { |
373 | af_resample_set_SampsNumRatio(paf_resampe_ctl); |
374 | } |
375 | //indecate at the end of pcm stream |
376 | if (NumSampsPerCh_Pre + NumSampsPerCh_in < paf_resampe_ctl->SampNumIn) { |
377 | memcpy(pPreSamps + paf_resampe_ctl->ResevedSampsValid, data_in, (*NumSamp_in)*sizeof(short)); |
378 | paf_resampe_ctl->ResevedSampsValid += (*NumSamp_in); |
379 | //memcpy(data_out,paf_resampe_ctl->ResevedBuf,paf_resampe_ctl->ResevedSampsValid); |
380 | //*NumSamp_out=paf_resampe_ctl->ResevedSampsValid; |
381 | *NumSamp_out = 0; |
382 | } else { |
383 | int NumSampsPerCh_Rest = NumSampsPerCh_Pre + NumSampsPerCh_in - paf_resampe_ctl->SampNumIn; |
384 | input_offset += (paf_resampe_ctl->SampNumIn - NumSampsPerCh_Pre) * NumCh; |
385 | output_offset += paf_resampe_ctl->OutSampReserveLen; |
386 | memcpy(pPreSamps + paf_resampe_ctl->ResevedSampsValid, data_in, sizeof(short)*input_offset); |
387 | memcpy(data_out, paf_resampe_ctl->OutSampReserveBuf, sizeof(short)*paf_resampe_ctl->OutSampReserveLen); |
388 | buf16_in_valid = paf_resampe_ctl->SampNumIn; |
389 | for (ChId = 0; ChId < NumCh; ChId++) { |
390 | for (index = 0; index < buf16_in_valid; index++) { |
391 | buf16_in[index] = pPreSamps[NumCh * index + ChId]; |
392 | } |
393 | for (index = 0; index < paf_resampe_ctl->SampNumOut - 1; index++) { |
394 | int pos = pindex[index]; |
395 | short t16; |
396 | t16 = buf16_in[pos] + Q14_INT_GET((pcoef[index] * (buf16_in[pos + 1] - buf16_in[pos]))); |
397 | data_out[output_offset + NumCh * index + ChId] = t16; |
398 | } |
399 | data_out[output_offset + NumCh * (paf_resampe_ctl->SampNumOut - 1) + ChId] = buf16_in[buf16_in_valid - 1]; |
400 | } |
401 | output_offset += paf_resampe_ctl->SampNumOut * NumCh; |
402 | paf_resampe_ctl->ResevedSampsValid = 0; |
403 | |
404 | while (NumSampsPerCh_Rest > paf_resampe_ctl->SampNumIn) { |
405 | buf16_in_valid = paf_resampe_ctl->SampNumIn; |
406 | for (ChId = 0; ChId < NumCh; ChId++) { |
407 | for (index = 0; index < buf16_in_valid; index++) { |
408 | buf16_in[index] = data_in[input_offset + NumCh * index + ChId]; |
409 | } |
410 | for (index = 0; index < paf_resampe_ctl->SampNumOut - 1; index++) { |
411 | int pos = pindex[index]; |
412 | short t16; |
413 | t16 = buf16_in[pos] + Q14_INT_GET(((int64_t)pcoef[index] * (buf16_in[pos + 1] - buf16_in[pos]))); |
414 | data_out[output_offset + NumCh * index + ChId] = t16; |
415 | } |
416 | data_out[output_offset + NumCh * (paf_resampe_ctl->SampNumOut - 1) + ChId] = buf16_in[buf16_in_valid - 1]; |
417 | } |
418 | NumSampsPerCh_Rest -= paf_resampe_ctl->SampNumIn; |
419 | input_offset += paf_resampe_ctl->SampNumIn * NumCh; |
420 | output_offset += paf_resampe_ctl->SampNumOut * NumCh; |
421 | } |
422 | cur_out_samp_reserve_num = output_offset % (DEFALT_NUMSAMPS_PERCH * NumCh) ; |
423 | paf_resampe_ctl->OutSampReserveLen = cur_out_samp_reserve_num; |
424 | |
425 | memcpy(paf_resampe_ctl->OutSampReserveBuf, |
426 | data_out + output_offset - cur_out_samp_reserve_num, |
427 | sizeof(short)*cur_out_samp_reserve_num); |
428 | *NumSamp_out = output_offset - cur_out_samp_reserve_num; |
429 | |
430 | if (input_offset < (*NumSamp_in)) { |
431 | memcpy(pPreSamps, data_in + input_offset, sizeof(short)*NumSampsPerCh_Rest * NumCh); |
432 | paf_resampe_ctl->ResevedSampsValid = NumSampsPerCh_Rest * NumCh; |
433 | } else { |
434 | paf_resampe_ctl->ResevedSampsValid = 0; |
435 | } |
436 | } |
437 | } |
438 | |
439 | void af_resample_stop_process(af_resampe_ctl_t *paf_resampe_ctl) |
440 | { |
441 | //memcpy(pPreservedSamps,paf_resampe_ctl->OutSampReserveBuf,sizeof(short)*paf_resampe_ctl->OutSampReserveLen); |
442 | //memcpy(pPreservedSamps+paf_resampe_ctl->OutSampReserveLen,paf_resampe_ctl->ResevedBuf,sizeof(short)*paf_resampe_ctl->ResevedSampsValid); |
443 | //*SampNum=paf_resampe_ctl->OutSampReserveLen + paf_resampe_ctl->ResevedSampsValid; |
444 | // paf_resampe_ctl->ResevedSampsValid=0; |
445 | //paf_resampe_ctl->OutSampReserveLen=0; |
446 | if (paf_resampe_ctl->InitFlag != 0) { |
447 | audiodsp_set_pcm_resample_delta(0); |
448 | } |
449 | paf_resampe_ctl->InitFlag = 0; |
450 | paf_resampe_ctl->LastResamType = 0; |
451 | // adec_print("resample stop INIT_FLAG=%d\n",paf_resampe_ctl->InitFlag); |
452 | } |
453 | |
454 | #define MAXCH_NUMBER 8 |
455 | #define MAXFRAMESIZE 8192 |
456 | short date_temp[MAXCH_NUMBER*MAXFRAMESIZE]; |
457 | extern int android_reset_track(struct aml_audio_dec* audec); |
458 | /** |
459 | * try to read as much data as len from dsp buffer |
460 | */ |
461 | |
462 | static void dump_pcm_bin(char *path, char *buf, int size) |
463 | { |
464 | FILE *fp = fopen(path, "ab+"); |
465 | if (fp != NULL) { |
466 | fwrite(buf, 1, size, fp); |
467 | fclose(fp); |
468 | } |
469 | } |
470 | |
471 | #define RESAMPLE_FRAMES 128 |
472 | void af_resample_api(char* buffer, unsigned int * size, int Chnum, aml_audio_dec_t* audec, int enable, int delta) |
473 | { |
474 | short data_in[RESAMPLE_FRAMES * 2]; |
475 | short *pbuf; |
476 | int resample_enable; |
477 | int resample_type; |
478 | int resample_delta; |
479 | int sample_read; |
480 | int num_sample = 0; |
481 | int i, j, k, h; |
482 | int request = *size; |
483 | int dsp_read = 0; |
484 | static int last_resample_enable = 0; |
485 | static int last_delta = 0; |
486 | pbuf = (short*)date_temp; |
487 | unsigned index = 0; |
488 | float mPhaseFraction; |
489 | float phaseIncrement ; |
490 | float mPhaseFraction1; |
491 | unsigned in_sr; |
492 | unsigned out_sr; |
493 | short *input; |
494 | short *output; |
495 | unsigned frames = 0; |
496 | in_sr = (RESAMPLE_FRAMES - 1); |
497 | out_sr = (RESAMPLE_FRAMES - delta - 1); |
498 | phaseIncrement = (float)in_sr / out_sr; |
499 | resample_enable = enable; |
500 | //resample_delta = 0;i |
501 | resample_delta = delta; |
502 | |
503 | if (last_resample_enable != resample_enable || last_delta != delta) { |
504 | adec_print("resample changed: %s,delta %d\n", resample_enable ? "Enabled" : "Disabled", delta); |
505 | last_resample_enable = resample_enable; |
506 | last_delta = delta; |
507 | } |
508 | |
509 | if (resample_enable && resample_delta && *size >= RESAMPLE_FRAMES * sizeof(short)*Chnum) { |
510 | //adec_print("resample start ... %d, step=%d\n", *size, resample_delta); |
511 | if (resample_delta < 0) { |
512 | *size = *size * RESAMPLE_FRAMES / (RESAMPLE_FRAMES - resample_delta); |
513 | *size &= ~(2 * Chnum - 1); |
514 | } |
515 | sample_read = dsp_pcm_read(audec, pbuf, *size); // return mono sample number |
516 | dsp_read += sample_read; |
517 | //adec_print("dsp read %d\n", sample_read); |
518 | k = 0; |
519 | while (sample_read >= RESAMPLE_FRAMES * Chnum) { |
520 | mPhaseFraction = 0; |
521 | mPhaseFraction1 = 0; |
522 | index = 0; |
523 | input = (short*)pbuf + frames * Chnum; |
524 | output = (short*)buffer + k * Chnum; |
525 | for (j = 0; j < RESAMPLE_FRAMES - resample_delta; j++) { |
526 | if (Chnum == 2) { |
527 | output[2 * j] = input[index * 2] + (short)((input[(index + 1) * 2] - input[index * 2]) * mPhaseFraction1); |
528 | output[2 * j + 1] = input[index * 2 + 1] + (short)((input[(index + 1) * 2 + 1] - input[index * 2 + 1]) * mPhaseFraction1); |
529 | } else if (Chnum == 1) { |
530 | output[j] = input[index] + (short)((input[(index + 1)] - input[index]) * mPhaseFraction1); |
531 | } else { |
532 | adec_print("fatal error,only support 1 ch ,2ch audio sample \n"); |
533 | return ; |
534 | } |
535 | mPhaseFraction += phaseIncrement; |
536 | index = mPhaseFraction; |
537 | mPhaseFraction1 = mPhaseFraction - index; |
538 | k++; |
539 | } |
540 | frames += RESAMPLE_FRAMES; |
541 | sample_read -= RESAMPLE_FRAMES * Chnum; |
542 | } |
543 | if (sample_read > 0) { |
544 | memcpy((short*)buffer + k * Chnum, (short*)pbuf + frames * Chnum, sample_read * sizeof(short)); |
545 | k += sample_read / Chnum; |
546 | } |
547 | |
548 | |
549 | num_sample = k * sizeof(short) * Chnum; |
550 | if (num_sample < *size) { |
551 | sample_read = dsp_pcm_read(audec, pbuf, *size - num_sample); |
552 | dsp_read += sample_read; |
553 | if (sample_read > 0) { |
554 | memcpy((short*)buffer + k * Chnum, pbuf, sample_read * sizeof(short)); |
555 | k += sample_read / Chnum; |
556 | } |
557 | } |
558 | *size = k * sizeof(short) * Chnum; |
559 | //adec_print("resample end ... %d\n", *size); |
560 | } else { |
561 | sample_read = dsp_pcm_read(audec, pbuf, *size - num_sample); |
562 | memcpy(buffer, pbuf, sample_read * sizeof(short)); |
563 | *size = sample_read * sizeof(short); |
564 | } |
565 | //adec_print("resample size from %d to %d, original %d\n", request, *size, dsp_read); |
566 | } |
567 | |
568 | void af_resample_api_normal(char *buffer, unsigned int *size, int Chnum, aml_audio_dec_t *audec) |
569 | { |
570 | int len; |
571 | int resample_enable; |
572 | af_resampe_ctl_t *paf_resampe_ctl; |
573 | short data_in[MAX_NUMSAMPS_PERCH * DEFALT_NUMCH], *data_out; |
574 | short outbuftmp16[MAX_NUMSAMPS_PERCH * DEFALT_NUMCH]; |
575 | int NumSamp_in, NumSamp_out, NumCh, NumSampRequir = 0; |
576 | static int print_flag = 0; |
577 | int outbuf_offset = 0; |
578 | int dsp_format_changed_flag = 0; |
579 | static int pcm_left_len = -1; |
580 | //------------------------------------------ |
581 | NumCh = Chnum; //buffer->channelCount; |
582 | resample_enable = af_get_resample_enable_flag(); |
583 | paf_resampe_ctl = af_resampler_ctx_get(); |
584 | data_out = date_temp; //buffer->i16 |
585 | NumSamp_out = *size / sizeof(short); //buffer->size/sizeof(short); |
586 | if (NumSamp_out > MAXCH_NUMBER * MAXFRAMESIZE) { |
587 | NumSamp_out = MAXCH_NUMBER * MAXFRAMESIZE; |
588 | } |
589 | NumSampRequir = NumSamp_out; |
590 | int resample_type = af_get_resample_type(); |
591 | |
592 | //adec_print("REQURE_NUM-----------------------------%d\n",NumSamp_out); |
593 | |
594 | //------------------------------- |
595 | //add this part for support rapid Resample_Type covet: |
596 | if (resample_enable) { |
597 | if (paf_resampe_ctl->LastResamType != resample_type) { |
598 | //adec_print("ReSample Type Changed: FromTYpe/%d ToType/%d \n", |
599 | // paf_resampe_ctl->LastResamType,resample_type); |
600 | amsysfs_set_sysfs_int("sys/class/amaudio/resample_type", resample_type); |
601 | if ((paf_resampe_ctl->OutSampReserveLen == 0) // to ensure phase continue: |
602 | && (paf_resampe_ctl->ResevedSampsValid == 0)) { |
603 | //adec_print("ReSample Type Changed: ENABLE"); |
604 | af_resample_stop_process(paf_resampe_ctl); |
605 | } else { |
606 | //adec_print("ReSample Type Changed DISABLE:"); |
607 | // adec_print(" OutSampSaved/%d InSampSaved/%d in Resampler!", |
608 | // paf_resampe_ctl->OutSampReserveLen,paf_resampe_ctl->ResevedSampsValid); |
609 | resample_enable = 0; |
610 | } |
611 | |
612 | } |
613 | } |
614 | //------------------------------- |
615 | if (resample_enable) { |
616 | int pcm_cnt = 0; |
617 | if (!paf_resampe_ctl->InitFlag) { |
618 | af_resample_set_SampsNumRatio(paf_resampe_ctl); |
619 | } |
620 | af_get_pcm_in_resampler(paf_resampe_ctl, data_out + outbuf_offset, &NumSampRequir); |
621 | |
622 | //adec_print("RETURN_SIZE_1:%d OutSampReserve=%d \n",NumSampRequir,paf_resampe_ctl->OutSampReserveLen); |
623 | |
624 | outbuf_offset += NumSampRequir; |
625 | NumSamp_out -= NumSampRequir; |
626 | while (NumSamp_out >= DEFALT_NUMSAMPS_PERCH * NumCh) { |
627 | int delta_input_sampsnum = af_get_delta_inputsampnum(paf_resampe_ctl, NumCh); |
628 | NumSamp_in = dsp_pcm_read(audec, (char*)data_in, delta_input_sampsnum * sizeof(short)); |
629 | af_resample_process_linear_inner(paf_resampe_ctl, data_in, &NumSamp_in, data_out + outbuf_offset, &pcm_cnt, NumCh); |
630 | |
631 | //adec_print("RETURN_SIZE_2:%d OutSampReserve=%d \n",pcm_cnt,paf_resampe_ctl->OutSampReserveLen); |
632 | |
633 | if (pcm_cnt == 0) { |
634 | goto resample_out; |
635 | } |
636 | outbuf_offset += pcm_cnt; |
637 | NumSamp_out -= pcm_cnt; |
638 | } |
639 | |
640 | if (NumSamp_out > 0) { |
641 | int delta_input_sampsnum = af_get_delta_inputsampnum(paf_resampe_ctl, NumCh); |
642 | NumSamp_in = dsp_pcm_read(audec, (char*)data_in, delta_input_sampsnum * sizeof(short)); |
643 | af_resample_process_linear_inner(paf_resampe_ctl, data_in, &NumSamp_in, outbuftmp16, &pcm_cnt, NumCh); |
644 | if (pcm_cnt == 0) { |
645 | goto resample_out; |
646 | } |
647 | |
648 | //adec_print("RETURN_SIZE_3:%d OutSampReserve=%d \n",NumSamp_out,pcm_cnt-NumSamp_out); |
649 | |
650 | memcpy(data_out + outbuf_offset, outbuftmp16, NumSamp_out * sizeof(short)); |
651 | outbuf_offset += NumSamp_out; |
652 | memcpy(paf_resampe_ctl->OutSampReserveBuf, outbuftmp16 + NumSamp_out, (pcm_cnt - NumSamp_out)*sizeof(short)); |
653 | paf_resampe_ctl->OutSampReserveLen = (pcm_cnt - NumSamp_out); |
654 | } |
655 | |
656 | } else { |
657 | if (paf_resampe_ctl->OutSampReserveLen > 0) { |
658 | af_get_pcm_in_resampler(paf_resampe_ctl, data_out + outbuf_offset, &NumSampRequir); |
659 | //adec_print("RETURN_SIZE_4:%d OutSampReserve=%d \n",NumSampRequir,paf_resampe_ctl->OutSampReserveLen); |
660 | outbuf_offset += NumSampRequir; |
661 | NumSamp_out -= NumSampRequir; |
662 | NumSampRequir = NumSamp_out; |
663 | } |
664 | |
665 | if (paf_resampe_ctl->ResevedSampsValid > 0) { |
666 | af_get_unpro_inputsampnum(paf_resampe_ctl, data_out + outbuf_offset, &NumSampRequir); |
667 | //adec_print("RETURN_SIZE_5:%d OutSampReserve=%d \n",NumSampRequir,paf_resampe_ctl->ResevedSampsValid); |
668 | outbuf_offset += NumSampRequir; |
669 | NumSamp_out -= NumSampRequir; |
670 | } |
671 | |
672 | if ((paf_resampe_ctl->OutSampReserveLen == 0) && (paf_resampe_ctl->ResevedSampsValid == 0)) { |
673 | af_resample_stop_process(paf_resampe_ctl); |
674 | } |
675 | |
676 | if (NumSamp_out > 0) { |
677 | len = audec->adsp_ops.dsp_read(&audec->adsp_ops, (char*)(data_out + outbuf_offset), NumSamp_out * sizeof(short)); |
678 | outbuf_offset += len / sizeof(short); |
679 | audec->pcm_bytes_readed += len; |
680 | } |
681 | } |
682 | resample_out: |
683 | |
684 | *size = outbuf_offset * sizeof(short); |
685 | memcpy(buffer, data_out, *size); |
686 | if (pcmfd >= 0) { |
687 | write(pcmfd, buffer, *size); |
688 | } |
689 | //------------------------------------ |
690 | dsp_format_changed_flag = audiodsp_format_update(audec); |
691 | if (dsp_format_changed_flag > 0) { |
692 | pcm_left_len = audiodsp_get_pcm_left_len(); |
693 | } |
694 | if (pcm_left_len >= 0) { |
695 | if (pcm_left_len > (*size)) { |
696 | pcm_left_len -= (*size); |
697 | memset((char*)(data_out), 0, *size); |
698 | } else if (pcm_left_len <= (*size)) { |
699 | memset((char*)(data_out), 0, pcm_left_len); |
700 | pcm_left_len = -1; |
701 | |
702 | } |
703 | } |
704 | //dump_pcm_bin("/data/post1.pcm",(char*)(buffer->i16),buffer->size); |
705 | //--------------------------------------------- |
706 | |
707 | } |
708 | #endif |
709 |