summaryrefslogtreecommitdiff
path: root/tvapi/libtv/audio/audio_android.cpp (plain)
blob: dc973b48f4b3693cd82fe7901b34df3a4bb50063
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <fcntl.h>
5#include <malloc.h>
6#include <unistd.h>
7#include <pthread.h>
8#include <sys/stat.h>
9#include <media/mediarecorder.h>
10#include <system/audio.h>
11#include <android/log.h>
12#include <cutils/properties.h>
13#include <media/AudioSystem.h>
14#include <sys/prctl.h>
15#include <math.h>
16
17#include "audio_cfg.h"
18#include "audio_api.h"
19#include "audio_android.h"
20#include "audio_android_effect.h"
21
22#define msleep(x) usleep(x*1000)
23
24#define LOG_TAG "AndroidAudio"
25#include "CTvLog.h"
26
27#define SOFTWARE_RESAMPLE
28
29#define HDMI_PERIOD_SIZE 1024
30#define PERIOD_SIZE 512
31
32#define debug 0
33//temp buffer between record thread and playback thread
34#define temp_buffer_size 1024*14
35#define mid_buffer_size 1024*7 //reset distance for HDMI
36#define reset_distance 1024*2 //reset distance for atv
37
38
39#ifdef SOFTWARE_RESAMPLE
40#define Upresample_distance 1024*10
41#define Downresample_distance 1024*4
42
43#define period_size 2 //1024*periodsize
44#define resample_ratio 16 // unit:one in a thousand
45#define fraction_bit 16 //16.16 type
46#define upsample_framecount (1024 + resample_ratio)
47#define upsample_ratio (unsigned int)((float)downsample_framecount*65536.0f/(float)1024)
48#define downsample_framecount (1024 - resample_ratio)
49#define downsample_ratio (unsigned int)((float)upsample_framecount*65536.0f/(float)1024)
50#define resample_counter (1024/resample_ratio)
51
52short *resample_temp_buffer = NULL;
53
54const unsigned int FractionStep_up = upsample_ratio;
55const unsigned int FractionStep_down = downsample_ratio;
56unsigned int Upsample_Fraction = 0;
57unsigned int Downsample_Fraction = 0;
58#endif
59
60#if debug == 1
61int record_counter = 0;
62int playback_counter = 0;
63#endif
64
65
66#define HISTORY_BASE (12)
67#define HISTORY_NUM (1<<12)
68static signed history[2][HISTORY_NUM];
69
70//showbo
71static const int CC_AUDIO_SOURCE_IN_HDMI = 0;//just test,not true value
72
73CAndroidAudio::CAndroidAudio(CAudioAlsa *p): mpAudioAlsa(p)
74{
75 int mDumpDataFlag = 0;
76 int mDumpDataFd = -1;
77 mlpRecorder = NULL;
78 mlpTracker = NULL;
79 temp_buffer = NULL;
80 end_temp_buffer = NULL;
81 record_write_pointer = NULL;
82 playback_read_pointer = NULL;
83 gEnableNoiseGate = false;
84 gUserSetEnableNoiseGate = false;
85 zero_count_left = 2000;
86 zero_count_right = 2000;
87 NOISE_HIS = 48000 * 5;
88 gNoiseGateThresh = 0;
89}
90CAndroidAudio::~CAndroidAudio()
91{
92}
93
94void CAndroidAudio::noise_filter_init()
95{
96 memset(history, 0, sizeof(history));
97 zero_count_left = 2000;
98 zero_count_right = 2000;
99}
100
101signed CAndroidAudio::noise_filter_left(signed sample)
102{
103 //if(!enable_noise_filter ||hdmi_src_in)
104 // return sample;
105 signed sum_left = 0;
106 signed sum_right = 0;
107 unsigned left_pos = 0;
108 unsigned right_pos = 0;
109 signed y = 0;
110 int i = 0;
111 signed sum = 0;
112 signed ret_sample;
113 signed zero = 0;
114 sample <<= 16;
115 sample >>= 16;
116#if 0
117 if(hdmi_src_in) { //for hdmi src,not use filter and -6db for prevent clip of SRS/other post process.
118 ret_sample = Mul28(sample, M3DB);
119 return ret_sample;
120 } else {
121 ret_sample = Mul28(sample, M3DB);
122 sample = ret_sample;
123 }
124#endif
125 sum_left -= history[0][left_pos];
126 sum_left += history[0][(left_pos + HISTORY_NUM - 1)
127 & ((1 << HISTORY_BASE) - 1)];
128 sum = sum_left >> HISTORY_BASE;
129 left_pos = (left_pos + 1) & ((1 << HISTORY_BASE) - 1);
130 history[0][(left_pos + HISTORY_NUM - 1) & ((1 << HISTORY_BASE) - 1)] =
131 sample;
132
133 zero = abs(sample - sum);
134 if (zero < gNoiseGateThresh) {
135 zero_count_left++;
136 if (zero_count_left > NOISE_HIS) {
137 zero_count_left = NOISE_HIS;
138 y = 0;
139 } else {
140 y = sample;
141 }
142 } else {
143 y = sample;
144 zero_count_left = 0;
145 }
146 return y;
147}
148
149signed CAndroidAudio::noise_filter_right(signed sample)
150{
151 //if(!enable_noise_filter ||hdmi_src_in)
152 // return sample;
153 signed y = 0;
154 int i = 0;
155 signed ret_sample;
156 signed sum = 0;
157 sample <<= 16;
158 sample >>= 16;
159#if 0
160 if(hdmi_src_in) { //for hdmi src,not use filter and -6db for prevent clip of SRS/other post process.
161 ret_sample = Mul28(sample, M3DB);
162 return ret_sample;
163 } else {
164 ret_sample = Mul28(sample, M3DB);
165 sample = ret_sample;
166 }
167#endif
168 sum_right -= history[1][right_pos];
169 sum_right += history[1][(right_pos + HISTORY_NUM - 1)
170 & ((1 << HISTORY_BASE) - 1)];
171 sum = sum_right >> HISTORY_BASE;
172 right_pos = (right_pos + 1) & ((1 << HISTORY_BASE) - 1);
173 history[1][(right_pos + HISTORY_NUM - 1) & ((1 << HISTORY_BASE) - 1)] =
174 sample;
175
176 if (abs(sample - sum) < gNoiseGateThresh) {
177 zero_count_right++;
178 if (zero_count_right > NOISE_HIS) {
179 zero_count_right = NOISE_HIS;
180 y = 0;
181 } else {
182 y = sample;
183 }
184 } else {
185 y = sample;
186 zero_count_right = 0;
187 }
188 return y;
189}
190
191void CAndroidAudio::DeleteAudioRecorder(void)
192{
193#if ANDROID_PLATFORM_SDK_VERSION < 19
194 if (mlpRecorder != NULL) {
195 delete mlpRecorder;
196 mlpRecorder = NULL;
197 }
198#else
199 if (mlpRecorder != NULL ) {
200 mlpRecorder = NULL;
201 }
202
203 if (mmpAudioRecorder != NULL ) {
204 mmpAudioRecorder.clear();
205 }
206#endif
207}
208
209void CAndroidAudio::FreeAudioRecorder(void)
210{
211 if (mlpRecorder != NULL) {
212 mlpRecorder->stop();
213 }
214
215 DeleteAudioRecorder();
216}
217
218void CAndroidAudio::DeleteAudioTracker(void)
219{
220#if ANDROID_PLATFORM_SDK_VERSION < 19
221 if (mlpTracker != NULL) {
222 delete mlpTracker;
223 mlpTracker = NULL;
224 }
225#else
226 if (mlpTracker != NULL ) {
227 mlpTracker = NULL;
228 }
229
230 if (mmpAudioTracker != NULL ) {
231 mmpAudioTracker.clear();
232 }
233#endif
234}
235
236void CAndroidAudio::FreeAudioTracker(void)
237{
238 if (mlpTracker != NULL) {
239 mlpTracker->stop();
240 }
241
242 DeleteAudioTracker();
243}
244
245int CAndroidAudio::InitTempBuffer()
246{
247 int tmp_size = 0;
248
249 if (NULL == temp_buffer) {
250 tmp_size = temp_buffer_size;
251 temp_buffer = new short[tmp_size];
252 if (NULL == temp_buffer) {
253 return -1;
254 }
255 memset(temp_buffer, 0, tmp_size * sizeof(short));
256 end_temp_buffer = temp_buffer + tmp_size;
257 record_write_pointer = temp_buffer;
258 playback_read_pointer = temp_buffer;
259 }
260#ifdef SOFTWARE_RESAMPLE
261 if (NULL == resample_temp_buffer) {
262 tmp_size = upsample_framecount * 2 * period_size + 10;
263 resample_temp_buffer = new short[tmp_size];
264 if (NULL == resample_temp_buffer) {
265 return -1;
266 }
267 memset(temp_buffer, 0, tmp_size * sizeof(short));
268 }
269#endif
270 return 0;
271}
272
273static void MuteTempBuffer()
274{
275 if ((NULL != temp_buffer) && (NULL != mlpTracker)) {
276 playback_read_pointer = record_write_pointer;
277 memset(temp_buffer, 0, temp_buffer_size * sizeof(short));
278 for (int i = 0; i < 10; i++) {
279 mlpTracker->write(temp_buffer, temp_buffer_size);
280 }
281 }
282}
283
284void CAndroidAudio::FreeTempBuffer()
285{
286 if (temp_buffer != NULL) {
287 delete[] temp_buffer;
288 temp_buffer = NULL;
289 end_temp_buffer = NULL;
290 record_write_pointer = NULL;
291 playback_read_pointer = NULL;
292 }
293#ifdef SOFTWARE_RESAMPLE
294 if (resample_temp_buffer != NULL) {
295 delete[] resample_temp_buffer;
296 resample_temp_buffer = NULL;
297 }
298#endif
299}
300
301void CAndroidAudio::ResetRecordWritePointer()
302{
303 record_write_pointer = playback_read_pointer;
304}
305
306void CAndroidAudio::ResetPlaybackReadPointer()
307{
308 record_write_pointer = playback_read_pointer;
309}
310
311void CAndroidAudio::ResetPointer()
312{
313 if (mpAudioAlsa->GetAudioInSource() == CC_AUDIO_SOURCE_IN_HDMI) {
314 playback_read_pointer = record_write_pointer - mid_buffer_size;
315 if (playback_read_pointer < temp_buffer) {
316 playback_read_pointer += temp_buffer_size;
317 }
318 } else {
319 playback_read_pointer = record_write_pointer - reset_distance;
320 if (playback_read_pointer < temp_buffer) {
321 playback_read_pointer += temp_buffer_size;
322 }
323 }
324}
325
326// 0: LINEIN 1: HDMI
327void CAndroidAudio::reset_system_framesize(int input_sample_rate, int output_sample_rate)
328{
329 int frame_size = 0;
330
331 audio_io_handle_t handle = -1;
332
333 if (mpAudioAlsa->GetAudioInSource() == CC_AUDIO_SOURCE_IN_HDMI) {
334 frame_size = HDMI_PERIOD_SIZE * 4;
335 LOGE("Source In:HDMI, Android system audio out framecount: %d \n",
336 frame_size);
337 } else {
338 //msleep(500);
339 frame_size = PERIOD_SIZE * 4;
340 LOGE("Source In:LIENIN, Android system audio out framecount: %d \n",
341 frame_size);
342 }
343
344 handle = AudioSystem::getInput(AUDIO_SOURCE_MIC, input_sample_rate,
345 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 0);
346
347 if (handle > 0) {
348 char str[64];
349 memset(str, 0, sizeof(str));
350 sprintf(str, "frame_count=%d", frame_size);
351 LOGE("input handle number: %d \n", handle);
352 AudioSystem::setParameters(handle, String8(str));
353 } else {
354 LOGE("Can't get input handle! \n");
355 }
356
357 handle = -1;
358
359 handle = AudioSystem::getOutput(AUDIO_STREAM_MUSIC, output_sample_rate,
360 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
361 AUDIO_OUTPUT_FLAG_NONE);
362
363 if (handle > 0) {
364 char str[64];
365 memset(str, 0, sizeof(str));
366 sprintf(str, "frame_count=%d", frame_size);
367 LOGE("output handle number: %d \n", handle);
368 AudioSystem::setParameters(handle, String8(str));
369 } else {
370 LOGE("Can't get output handle! \n");
371 }
372}
373
374inline short CAndroidAudio::clip(int x) //Clip from 16.16 fixed-point to 0.15 fixed-point.
375{
376 if (x < -32768)
377 return -32768;
378 else if (x > 32767)
379 return 32767;
380 else
381 return x;
382}
383
384int CAndroidAudio::upsample(short *input, short *output, unsigned int FractionStep,
385 unsigned int input_frame_size, unsigned int frac)
386{
387 unsigned int inputIndex = 1;
388 unsigned int outputIndex = 0;
389
390 while (inputIndex < input_frame_size) {
391 *output++ = clip(
392 input[2 * inputIndex - 2]
393 + (((input[2 * inputIndex] - input[2 * inputIndex - 2])
394 * (int32_t) frac) >> 16));
395 *output++ = clip(
396 input[2 * inputIndex - 1]
397 + (((input[2 * inputIndex + 1]
398 - input[2 * inputIndex - 1]) * (int32_t) frac)
399 >> 16));
400
401 frac += FractionStep;
402 inputIndex += (frac >> 16);
403 frac = (frac & 0xffff);
404 outputIndex++;
405 }
406
407 return outputIndex;
408}
409
410int CAndroidAudio::downsample(short *input, short *output, unsigned int FractionStep,
411 unsigned int input_frame_size, unsigned int frac)
412{
413 unsigned int inputIndex = 1;
414 unsigned int outputIndex = 0;
415
416 while (inputIndex < input_frame_size) {
417 *output++ = clip(
418 input[2 * inputIndex - 2]
419 + (((input[2 * inputIndex] - input[2 * inputIndex - 2])
420 * (int32_t) frac) >> 16));
421 *output++ = clip(
422 input[2 * inputIndex - 1]
423 + (((input[2 * inputIndex + 1]
424 - input[2 * inputIndex - 1]) * (int32_t) frac)
425 >> 16));
426
427 frac += FractionStep;
428 inputIndex += (frac >> 16);
429 frac = (frac & 0xffff);
430 outputIndex++;
431 }
432
433 return outputIndex;
434}
435
436int CAndroidAudio::GetWriteSpace(short volatile *WritePoint,
437 short volatile *ReadPoint)
438{
439 unsigned int space;
440
441 if (WritePoint >= ReadPoint)
442 space = temp_buffer_size - (WritePoint - ReadPoint);
443 else
444 space = ReadPoint - WritePoint;
445
446 return space;
447}
448int CAndroidAudio::GetReadSpace(short volatile *WritePoint, short volatile *ReadPoint)
449{
450 unsigned int space;
451
452 if (WritePoint >= ReadPoint)
453 space = WritePoint - ReadPoint;
454 else
455 space = temp_buffer_size - (ReadPoint - WritePoint);
456
457 return space;
458}
459
460void CAndroidAudio::recorderCallback(int event, void *user, void *info)
461{
462 if (AudioRecord::EVENT_MORE_DATA == event) {
463 AudioRecord::Buffer *pbuf = (AudioRecord::Buffer *) info;
464
465 if (NULL == mlpRecorder)
466 return;
467
468 unsigned int offset_bytes = 2
469 * (end_temp_buffer - record_write_pointer);
470 unsigned int copy_bytes;
471 unsigned int output_bytes;
472
473 int available_write_space;
474 available_write_space = GetWriteSpace(record_write_pointer,
475 playback_read_pointer);
476
477 //LOGE("~~~~~available_write_space = %d \n", available_write_space);
478
479 if (available_write_space < pbuf->size / 2) {
480 LOGE(
481 "[%s]: ***** FULL! *****\n\trd=0x%x, wr=0x%x, wr_lvl = 0x%x, wr_req = 0x%x\n",
482 __FUNCTION__, playback_read_pointer, record_write_pointer,
483 available_write_space, pbuf->size / 2);
484
485 if (mpAudioAlsa->GetAudioInSource() == CC_AUDIO_SOURCE_IN_HDMI) {
486 playback_read_pointer += mid_buffer_size;
487 if (playback_read_pointer >= end_temp_buffer) {
488 playback_read_pointer -= temp_buffer_size;
489 }
490 } else {
491 playback_read_pointer += (temp_buffer_size - reset_distance);
492 if (playback_read_pointer >= end_temp_buffer) {
493 playback_read_pointer -= temp_buffer_size;
494 }
495 }
496 return;
497 }
498#if debug == 1
499 if(record_counter > 500) {
500 LOGE("~~~~~RecordCallback, pbuf->size:%d, pbuf->frameCount:%d", pbuf->size, pbuf->frameCount);
501 record_counter = 0;
502 } else {
503 record_counter++;
504 }
505#endif
506
507#ifdef SOFTWARE_RESAMPLE
508 if (mpAudioAlsa->GetAudioInSource() == CC_AUDIO_SOURCE_IN_HDMI) {
509 if (available_write_space <= Downresample_distance) {
510 output_bytes = 4
511 * downsample((short *) pbuf->raw, resample_temp_buffer,
512 FractionStep_down, pbuf->frameCount,
513 Downsample_Fraction);
514
515 LOGE(
516 "downsample: output_framecount = %d, input_frameCount = %d\n",
517 output_bytes / 4, pbuf->frameCount);
518
519 if (offset_bytes >= output_bytes) {
520 memcpy((short *) record_write_pointer, resample_temp_buffer,
521 output_bytes);
522 record_write_pointer += output_bytes / 2;
523
524 if (record_write_pointer == end_temp_buffer)
525 record_write_pointer = temp_buffer;
526 } else {
527 memcpy((short *) record_write_pointer, resample_temp_buffer,
528 offset_bytes);
529 copy_bytes = offset_bytes;
530 offset_bytes = output_bytes - copy_bytes;
531 record_write_pointer = temp_buffer;
532 memcpy((short *) record_write_pointer,
533 resample_temp_buffer + (copy_bytes / 2),
534 offset_bytes);
535 record_write_pointer += offset_bytes / 2;
536 }
537 return;
538 } else if (available_write_space >= Upresample_distance) {
539 output_bytes = 4
540 * upsample((short *) pbuf->raw, resample_temp_buffer,
541 FractionStep_up, pbuf->frameCount,
542 Upsample_Fraction);
543
544 LOGE(
545 "upsample: output_framecount = %d, input_frameCount = %d\n",
546 output_bytes / 4, pbuf->frameCount);
547
548 if (offset_bytes >= output_bytes) {
549 memcpy((short *) record_write_pointer, resample_temp_buffer,
550 output_bytes);
551 record_write_pointer += output_bytes / 2;
552
553 if (record_write_pointer == end_temp_buffer)
554 record_write_pointer = temp_buffer;
555 } else {
556 memcpy((short *) record_write_pointer, resample_temp_buffer,
557 offset_bytes);
558 copy_bytes = offset_bytes;
559 offset_bytes = output_bytes - copy_bytes;
560 record_write_pointer = temp_buffer;
561 memcpy((short *) record_write_pointer,
562 resample_temp_buffer + (copy_bytes / 2),
563 offset_bytes);
564 record_write_pointer += offset_bytes / 2;
565 }
566 return;
567 }
568
569 Upsample_Fraction = 0;
570 Downsample_Fraction = 0;
571 }
572#endif
573
574 if (offset_bytes >= pbuf->size) {
575 memcpy((short *) record_write_pointer, pbuf->raw, pbuf->size);
576 record_write_pointer += pbuf->size / 2;
577
578 if (record_write_pointer == end_temp_buffer)
579 record_write_pointer = temp_buffer;
580 } else {
581 memcpy((short *) record_write_pointer, pbuf->raw, offset_bytes);
582 copy_bytes = offset_bytes;
583 offset_bytes = pbuf->size - copy_bytes;
584 record_write_pointer = temp_buffer;
585 memcpy((short *) record_write_pointer,
586 (short *) pbuf->raw + (copy_bytes / 2), offset_bytes);
587 record_write_pointer += offset_bytes / 2;
588 }
589
590 //LOGD("--------RecordCallback, pbuf->size:%d, pbuf->frameCount:%d\n", pbuf->size, pbuf->frameCount);
591 //LOGD("--------Record----offset_bytes:%d\n", 2*(record_write_pointer-temp_buffer));
592
593 } else if (AudioRecord::EVENT_OVERRUN == event) {
594 LOGE("[%s]: AudioRecord::EVENT_OVERRUN\n", __FUNCTION__);
595 } else if (AudioRecord::EVENT_MARKER == event) {
596 LOGD("[%s]: AudioRecord::EVENT_MARKER\n", __FUNCTION__);
597 } else if (AudioRecord::EVENT_NEW_POS == event) {
598 LOGD("[%s]: AudioRecord::EVENT_NEW_POS\n", __FUNCTION__);
599 }
600}
601
602void CAndroidAudio::trackerCallback(int event, void *user, void *info)
603{
604 if (AudioTrack::EVENT_MORE_DATA == event) {
605 AudioTrack::Buffer *pbuf = (AudioTrack::Buffer *) info;
606
607 if (NULL == mlpTracker)
608 return;
609
610 int available_read_space;
611 available_read_space = GetReadSpace(record_write_pointer,
612 playback_read_pointer);
613
614 //LOGE("~~~~~available_read_space = %d input_bytes = %d \n", available_read_space,input_bytes);
615
616 if (available_read_space < pbuf->size / 2) {
617 LOGE(
618 "[%s]: ***** EMPTY *****\n\trd=0x%x, wr=0x%x, rd_lvl=0x%x, rd_req=0x%x*****\n",
619 __FUNCTION__, playback_read_pointer, record_write_pointer,
620 available_read_space, pbuf->size / 2);
621
622 if (mpAudioAlsa->GetAudioInSource() == CC_AUDIO_SOURCE_IN_HDMI) {
623 playback_read_pointer -= mid_buffer_size;
624 if (playback_read_pointer < temp_buffer)
625 playback_read_pointer += temp_buffer_size;
626 } else {
627 playback_read_pointer -= reset_distance;
628 if (playback_read_pointer < temp_buffer)
629 playback_read_pointer += temp_buffer_size;
630 }
631
632 } else {
633 unsigned int offset_bytes = 2
634 * (end_temp_buffer - playback_read_pointer);
635 unsigned int copy_bytes;
636 int sampNum;
637
638 if (offset_bytes >= pbuf->size) {
639 if (gEnableNoiseGate) {
640 sampNum = pbuf->size / 2;
641 for (int i = 0; i < sampNum; i++) {
642 pbuf->i16[i] = (short) noise_filter_left(
643 (signed) (playback_read_pointer[i]));
644 i++;
645 pbuf->i16[i] = (short) noise_filter_left(
646 (signed) (playback_read_pointer[i]));
647 }
648 } else {
649 memcpy(pbuf->raw, (short *) playback_read_pointer,
650 pbuf->size);
651 }
652
653 memset((void *) playback_read_pointer, 0, pbuf->size);
654 playback_read_pointer += pbuf->size / 2;
655
656 if (playback_read_pointer == end_temp_buffer)
657 playback_read_pointer = temp_buffer;
658 } else {
659 if (gEnableNoiseGate) {
660 sampNum = offset_bytes / 2;
661 for (int i = 0; i < sampNum; i++) {
662 pbuf->i16[i] = (short) noise_filter_left(
663 (signed) (playback_read_pointer[i]));
664 i++;
665 pbuf->i16[i] = (short) noise_filter_left(
666 (signed) (playback_read_pointer[i]));
667 }
668 } else {
669 memcpy(pbuf->raw, (short *) playback_read_pointer,
670 offset_bytes);
671 }
672
673 memset((void *) playback_read_pointer, 0, offset_bytes);
674 copy_bytes = offset_bytes;
675 offset_bytes = pbuf->size - copy_bytes;
676 playback_read_pointer = temp_buffer;
677
678 if (gEnableNoiseGate) {
679 short *pSrcPtr = &(pbuf->i16[copy_bytes / 2]);
680 sampNum = offset_bytes / 2;
681 for (int i = 0; i < sampNum; i++) {
682 pSrcPtr[i] = (short) noise_filter_left(
683 (signed) (playback_read_pointer[i]));
684 i++;
685 pSrcPtr[i] = (short) noise_filter_left(
686 (signed) (playback_read_pointer[i]));
687 }
688 } else {
689 memcpy((short *) pbuf->raw + (copy_bytes / 2),
690 (short *) playback_read_pointer, offset_bytes);
691 }
692 memset((void *) playback_read_pointer, 0, offset_bytes);
693 playback_read_pointer += offset_bytes / 2;
694 }
695 DoDumpData(pbuf->raw, pbuf->size);
696
697#if debug == 1
698 if(playback_counter > 500) {
699 LOGE("----PlaybackCallback, pbuf->size:%d, pbuf->frameCount:%d", pbuf->size, pbuf->frameCount);
700 playback_counter = 0;
701 } else {
702 playback_counter++;
703 }
704#endif
705
706 }
707 //LOGE("---Playback---offset_bytes:%d\n", 2*(playback_read_pointer-temp_buffer));
708 } else if (AudioTrack::EVENT_UNDERRUN == event) {
709 LOGE("[%s]: AudioTrack::EVENT_UNDERRUN\n", __FUNCTION__);
710 } else if (AudioTrack::EVENT_LOOP_END == event) {
711 LOGD("[%s]: AudioTrack::EVENT_LOOP_END\n", __FUNCTION__);
712 } else if (AudioTrack::EVENT_MARKER == event) {
713 LOGD("[%s]: AudioTrack::EVENT_MARKER\n", __FUNCTION__);
714 } else if (AudioTrack::EVENT_NEW_POS == event) {
715 LOGD("[%s]: AudioTrack::EVENT_NEW_POS\n", __FUNCTION__);
716 } else if (AudioTrack::EVENT_BUFFER_END == event) {
717 LOGD("[%s]: AudioTrack::EVENT_BUFFER_END\n", __FUNCTION__);
718 }
719}
720
721int CAndroidAudio::initAudioTracker(int sr)
722{
723 status_t ret;
724 int tmp_session_id = 0;
725
726 if (NULL != mlpTracker) {
727 LOGE("[%s:%d] Trying to new AudioTrack while it's still not NULL.\n",
728 __FUNCTION__, __LINE__);
729 goto err_exit;
730 }
731
732#if ANDROID_PLATFORM_SDK_VERSION < 19
733 mlpTracker = new AudioTrack();
734 if (NULL == mlpTracker) {
735 LOGE("[%s:%d] Failed to new AudioTrack.\n", __FUNCTION__, __LINE__);
736 goto err_exit;
737 }
738#else
739 mmpAudioTracker = new AudioTrack();
740 mlpTracker = mmpAudioTracker.get();
741#endif
742
743 tmp_session_id = amAndroidGetAudioSessionId();
744 ret = mlpTracker->set(AUDIO_STREAM_DEFAULT, //inputSource
745 sr, //sampleRate
746 AUDIO_FORMAT_PCM_16_BIT, //format
747 AUDIO_CHANNEL_IN_STEREO, //channelMask
748 0, //frameCount
749 AUDIO_OUTPUT_FLAG_NONE, //flags
750 trackerCallback, //trackerCallback,
751 NULL, //user when callback
752 0, //notificationFrames
753 NULL, //shared buffer
754 false, //threadCanCallJava
755 tmp_session_id //sessionId
756 );
757
758 if (NO_ERROR != ret) {
759 LOGE("[%s:%d] Failed to set AudioTrack parameters. status=%d\n",
760 __FUNCTION__, __LINE__, ret);
761 goto err_exit;
762 }
763
764 ret = mlpTracker->initCheck();
765 if (NO_ERROR != ret) {
766 LOGE("[%s:%d] Failed to init AudioTrack. status=%d\n", __FUNCTION__,
767 __LINE__, ret);
768 goto err_exit;
769 }
770
771 mlpTracker->start();
772 ResetPointer();
773
774#if debug == 1
775 uint32_t frame_count;
776 frame_count = mlpTracker->frameCount();
777 LOGE("~~~~~~[%s:%d] frame_count = %u\n", __FUNCTION__, __LINE__, frame_count);
778#endif
779
780 return 0;
781
782err_exit: //
783 DeleteAudioTracker();
784
785 return -1;
786}
787
788int CAndroidAudio::initAudioRecorder(int sr)
789{
790 status_t ret;
791
792 if (NULL != mlpRecorder) {
793 LOGE("[%s:%d] Trying to new AudioRecord while it's still not NULL.\n",
794 __FUNCTION__, __LINE__);
795 goto err_exit;
796 }
797
798#if ANDROID_PLATFORM_SDK_VERSION < 19
799 mlpRecorder = new AudioRecord();
800 if (NULL == mlpRecorder) {
801 LOGE("[%s:%d] Failed to new AudioRecord.\n", __FUNCTION__, __LINE__);
802 goto err_exit;
803 }
804#else
805 mmpAudioRecorder = new AudioRecord();
806 mlpRecorder = mmpAudioRecorder.get();
807#endif
808
809 ret = mlpRecorder->set(AUDIO_SOURCE_DEFAULT, //inputSource
810 sr, //sampleRate
811 AUDIO_FORMAT_PCM_16_BIT, //format
812 AUDIO_CHANNEL_IN_STEREO, //channelMask
813 0, //frameCount
814 recorderCallback, //callback_t
815 NULL, //void* user
816 0, //notificationFrames,
817 false, //threadCanCallJava
818 0 //sessionId
819 );
820
821 if (NO_ERROR != ret) {
822 LOGE("[%s:%d] Failed to set AudioRecord parameters. status=%d\n",
823 __FUNCTION__, __LINE__, ret);
824 goto err_exit;
825 }
826
827 ret = mlpRecorder->initCheck();
828 if (NO_ERROR != ret) {
829 LOGE("[%s:%d] Failed to init AudioRecord. status=%d\n", __FUNCTION__,
830 __LINE__, ret);
831 goto err_exit;
832 }
833
834 ret = mlpRecorder->start();
835 if (NO_ERROR != ret) {
836 LOGE("[%s:%d] Failed to start AudioRecord. status=%d\n", __FUNCTION__,
837 __LINE__, ret);
838 goto err_exit;
839 }
840#if debug == 1
841 uint32_t frame_count;
842 frame_count = mlpRecorder->frameCount();
843 LOGE("~~~~~~[%s:%d] frame_count = %u\n", __FUNCTION__, __LINE__, frame_count);
844#endif
845
846 return 0;
847err_exit: //
848 DeleteAudioRecorder();
849 return -1;
850}
851
852int CAndroidAudio::amAndroidInit(int tm_sleep, int init_flag, int recordSr, int trackSr,
853 bool enable_noise_gate)
854{
855 int tmp_ret;
856 LOGD("Enter amAndroidInit function.\n");
857
858 amAndroidUninit(0);
859
860 // Init the noise gate filter
861 gUserSetEnableNoiseGate = enable_noise_gate;
862 if (enable_noise_gate && (gNoiseGateThresh > 0)
863 && GetAudioNoiseGateEnableCFG()) {
864 gEnableNoiseGate = true;
865 noise_filter_init();
866 } else {
867 gEnableNoiseGate = false;
868 }
869 LOGE("[%s:%d] noise gate enabled:%d!\n", __FUNCTION__, __LINE__,
870 gEnableNoiseGate);
871
872 if (InitTempBuffer() != 0) {
873 LOGE("[%s:%d] Failed to create temp_buffer!\n", __FUNCTION__, __LINE__);
874 return 0;
875 }
876
877 if (init_flag & CC_FLAG_CREATE_RECORD) {
878 //LOGD("Start to create Recorder. RecordSr:%d\n", recordSr);
879 if (0 != initAudioRecorder(recordSr)) {
880 LOGE(" [%s:%d] Created AudioRecorder disable !\n", __FUNCTION__,
881 __LINE__);
882 return -1;
883 }
884 //LOGD("[%s:%d] End to create recorder.\n", __FUNCTION__, __LINE__);
885 }
886
887 if (init_flag & CC_FLAG_CREATE_TRACK) {
888 //LOGD("Start to create Tracker. TrackSr:%d\n", trackSr);
889 if (0 != initAudioTracker(trackSr)) {
890 //FreeAudioRecorder();
891 //FreeAudioTracker();
892 LOGE(" [%s:%d] Created AudioTrack disable !\n", __FUNCTION__,
893 __LINE__);
894 return -1;
895 }
896 //LOGD("[%s:%d] End to create recorder.\n", __FUNCTION__, __LINE__);
897 }
898
899 if (tm_sleep > 0)
900 sleep(tm_sleep);
901
902 LOGD("Exit amAndroidInit function sucess.\n");
903
904 return 0;
905}
906
907int CAndroidAudio::amAndroidUninit(int tm_sleep)
908{
909 LOGD("Enter amAndroidUninit function.\n");
910
911 FreeAudioRecorder();
912 // MuteTempBuffer();
913 FreeAudioTracker();
914 FreeTempBuffer();
915
916 if (tm_sleep > 0)
917 sleep(tm_sleep);
918
919 LOGD("Exit amAndroidUninit function sucess.\n");
920
921 return 0;
922}
923
924int CAndroidAudio::amAndroidSetRecorderSr(int sr)
925{
926 int ret;
927 FreeAudioRecorder();
928 ResetRecordWritePointer();
929 return initAudioRecorder(sr);
930}
931
932int CAndroidAudio::amAndroidSetTrackerSr(int sr)
933{
934 FreeAudioTracker();
935 ResetPlaybackReadPointer();
936 return initAudioTracker(sr);
937}
938
939//
940// Set the noise gate threshold.
941// If it's set to 0, the noise gate filter is disabled.
942// Theoretically, this variable should be protected by mutex. But this API
943// is designed to be called once on system boot, or for debug purpose, and it's
944// set only through this API. To improve the performance of the filters, we
945// don't utilize any mutex here.
946void CAndroidAudio::amAndroidSetNoiseGateThreshold(int thresh)
947{
948 int upperBound = GetAudioNoiseGateUpperBoundCFG();
949 int forcedThresh = GetAudioNoiseGateThresholdCFG();
950 if (forcedThresh >= 0) {
951 LOGE("Force noise gate threshold from %d to %d\n", thresh,
952 forcedThresh);
953 thresh = forcedThresh;
954 }
955
956 if ((thresh >= 0) && (thresh <= upperBound)) {
957 gNoiseGateThresh = thresh;
958 } else {
959 gNoiseGateThresh = 0;
960 }
961
962 if (gUserSetEnableNoiseGate && (gNoiseGateThresh > 0)
963 && GetAudioNoiseGateEnableCFG()) {
964 gEnableNoiseGate = true;
965 } else {
966 gEnableNoiseGate = false;
967 }
968 LOGE(
969 "[%s:%d] thresh:%d, upperBound:%d, gNoiseGateThresh:%d, gEnableNoiseGate:%d\n",
970 __FUNCTION__, __LINE__, thresh, upperBound, gNoiseGateThresh,
971 gEnableNoiseGate);
972}
973
974int CAndroidAudio::amAndroidSetDumpDataFlag(int tmp_flag)
975{
976 mDumpDataFlag = tmp_flag;
977 return mDumpDataFlag;
978}
979
980int CAndroidAudio::amAndroidGetDumpDataFlag()
981{
982 return mDumpDataFlag;
983}
984
985void CAndroidAudio::DoDumpData(void *data_buf, int size)
986{
987 int tmp_flag = 0;
988 char prop_value[PROPERTY_VALUE_MAX];
989
990 if (amAndroidGetDumpDataFlag() == 0) {
991 return;
992 }
993
994 memset(prop_value, '\0', PROPERTY_VALUE_MAX);
995
996 property_get("audio.dumpdata.en", prop_value, "null");
997 if (strcasecmp(prop_value, "null") == 0
998 || strcasecmp(prop_value, "0") == 0) {
999 if (mDumpDataFd >= 0) {
1000 close(mDumpDataFd);
1001 mDumpDataFd = -1;
1002 }
1003
1004 return;
1005 }
1006
1007 memset(prop_value, '\0', PROPERTY_VALUE_MAX);
1008
1009 property_get("audio.dumpdata.path", prop_value, "null");
1010 if (strcasecmp(prop_value, "null") == 0) {
1011 return;
1012 }
1013
1014 if (mDumpDataFd < 0) {
1015 if (access(prop_value, 0) == 0) {
1016 mDumpDataFd = open(prop_value, O_RDWR | O_SYNC);
1017 if (mDumpDataFd < 0) {
1018 LOGE("%s, Open device file \"%s\" error: %s.\n", __FUNCTION__,
1019 prop_value, strerror(errno));
1020 return;
1021 }
1022 } else {
1023 mDumpDataFd = open(prop_value, O_WRONLY | O_CREAT | O_EXCL,
1024 S_IRUSR | S_IWUSR);
1025 if (mDumpDataFd < 0) {
1026 LOGE("%s, Create device file \"%s\" error: %s.\n", __FUNCTION__,
1027 prop_value, strerror(errno));
1028 return;
1029 }
1030 }
1031 }
1032
1033 write(mDumpDataFd, data_buf, size);
1034}
1035
1036