summaryrefslogtreecommitdiff
path: root/libTVaudio/audio/aml_audio.c (plain)
blob: a034bb84d99ae77fd9e4c25bdc943992acc66070
1/*
2 ** aml_audio.c
3 **
4 ** This program is designed for TV application.
5 ** author: Wang Zhe
6 ** Email: Zhe.Wang@amlogic.com
7 **
8 */
9
10#define LOG_TAG "aml_audio"
11
12#include <stdbool.h>
13#include <stdio.h>
14#include <string.h>
15#include <stdlib.h>
16#include <stdint.h>
17#include <signal.h>
18#include <pthread.h>
19#include <unistd.h>
20#include <math.h>
21#include <fcntl.h>
22#include <errno.h>
23#include <sys/mman.h>
24#include <sys/ioctl.h>
25#include <sys/stat.h>
26#include <sys/prctl.h>
27#include <cutils/log.h>
28#include <cutils/properties.h>
29#include "tinyalsa/asoundlib.h"
30
31#include "aml_shelf.h"
32#include "android_out.h"
33#include "aml_audio.h"
34
35#define ANDROID_OUT_BUFFER_SIZE (2048*8*2) //in byte
36#define DDP_OUT_BUFFER_SIZE (2048*8*2*2*2) //in byte
37#define DD_61937_BUFFER_SIZE (2048*8*2*2*2)
38#define DEFAULT_OUT_SAMPLE_RATE (48000)
39#define DEFAULT_IN_SAMPLE_RATE (48000)
40#define PLAYBACK_PERIOD_SIZE (512)
41#define CAPTURE_PERIOD_SIZE (512)
42#define PLAYBACK_PERIOD_COUNT (4)
43#define CAPTURE_PERIOD_COUNT (4)
44#define TEMP_BUFFER_SIZE (PLAYBACK_PERIOD_SIZE * 4 * 3)
45//output device ID from audio.h
46#define AUDIO_DEVICE_OUT_SPEAKER (0x2)
47#define AUDIO_DEVICE_OUT_REMOTE_SUBMIX (0x8000)
48
49static const struct pcm_config pcm_config_out = {
50 .channels = 2,
51 .rate = DEFAULT_OUT_SAMPLE_RATE,
52 .period_size = PLAYBACK_PERIOD_SIZE,
53 .period_count = PLAYBACK_PERIOD_COUNT,
54 .format = PCM_FORMAT_S16_LE,
55 .stop_threshold = PLAYBACK_PERIOD_SIZE*PLAYBACK_PERIOD_COUNT,
56};
57
58static const struct pcm_config pcm_config_in = {
59 .channels = 2,
60 .rate = DEFAULT_IN_SAMPLE_RATE,
61 .period_size = CAPTURE_PERIOD_SIZE,
62 .period_count = CAPTURE_PERIOD_COUNT,
63 .format = PCM_FORMAT_S16_LE,
64 .stop_threshold = CAPTURE_PERIOD_SIZE*CAPTURE_PERIOD_COUNT*10,
65};
66
67struct buffer_status {
68 unsigned char *start_add;
69 size_t size;
70 size_t level;
71 unsigned int rd;
72 unsigned int wr;
73};
74
75struct resample_para {
76 unsigned int FractionStep;
77 unsigned int SampleFraction;
78 short lastsample_left;
79 short lastsample_right;
80};
81
82struct aml_stream_in {
83 pthread_mutex_t lock;
84 struct pcm_config config;
85 struct pcm *pcm;
86 int card;
87 int device;
88 int standby;
89 int resample_request;
90 void *resample_temp_buffer;
91 struct resample_para resample;
92 int max_bytes;
93 void *temp_buffer;
94 void *write_buffer;
95 int delay_time;
96 int last_delay_time;
97 struct circle_buffer delay_buf;
98 float pre_gain;
99 uint pre_mute;
100};
101
102struct aml_stream_out {
103 pthread_mutex_t lock;
104 struct pcm_config config;
105 struct pcm *pcm;
106 int card;
107 int device;
108 int standby;
109 void *temp_buffer;
110 void *read_buffer;
111 int output_device;
112 int amAudio_OutHandle;
113 struct buffer_status playback_buf;
114 int user_set_device;
115 int is_tv_platform;
116 int32_t *tmp_buffer_8ch;
117 void *audioeffect_tmp_buffer;
118};
119
120struct aml_dev {
121 struct aml_stream_in in;
122 struct aml_stream_out out;
123 pthread_t aml_Audio_ThreadID;
124 int aml_Audio_ThreadTurnOnFlag;
125 int aml_Audio_ThreadExecFlag;
126 int has_EQ_lib;
127 int has_SRS_lib;
128 int has_aml_IIR_lib;
129 int output_mode;
130 pthread_t android_check_ThreadID;
131};
132
133static struct aml_dev gmAmlDevice = {
134 .in = {
135 .lock = PTHREAD_MUTEX_INITIALIZER,
136 .config = {
137 .channels = 2,
138 .rate = DEFAULT_IN_SAMPLE_RATE,
139 .period_size = CAPTURE_PERIOD_SIZE,
140 .period_count = CAPTURE_PERIOD_COUNT,
141 .format = PCM_FORMAT_S16_LE,
142 .stop_threshold = CAPTURE_PERIOD_SIZE*CAPTURE_PERIOD_COUNT*10,
143 },
144 .pcm = NULL,
145 .card = 0,
146 .device = 0,
147 .standby = 0,
148 .resample_request = 0,
149 .resample_temp_buffer = NULL,
150 .resample = {
151 .FractionStep = 0,
152 .SampleFraction = 0,
153 .lastsample_left = 0,
154 .lastsample_right = 0,
155 },
156 .max_bytes = 0,
157 .temp_buffer = NULL,
158 .write_buffer = NULL,
159 .delay_time = 0,
160 .last_delay_time = 0,
161 .delay_buf = {
162 .lock = PTHREAD_MUTEX_INITIALIZER,
163 .start_add = NULL,
164 .rd = NULL,
165 .wr = NULL,
166 .size = 0,
167 },
168 .pre_gain = 1.0,
169 },
170
171 .out = {
172 .lock = PTHREAD_MUTEX_INITIALIZER,
173 .config = {
174 .channels = 2,
175 .rate = DEFAULT_OUT_SAMPLE_RATE,
176 .period_size = PLAYBACK_PERIOD_SIZE,
177 .period_count = PLAYBACK_PERIOD_COUNT,
178 .format = PCM_FORMAT_S16_LE,
179 .stop_threshold = PLAYBACK_PERIOD_SIZE*PLAYBACK_PERIOD_COUNT,
180 },
181 .pcm = NULL,
182 .card = 0,
183 .device = 0,
184 .standby = 0,
185 .temp_buffer = NULL,
186 .read_buffer = NULL,
187 .output_device = 0,
188 .amAudio_OutHandle = 0,
189 .playback_buf = {
190 .start_add = NULL,
191 .size = 0,
192 .level = 0,
193 .rd = 0,
194 .wr = 0,
195 },
196 .user_set_device = 0,
197 .is_tv_platform = 0,
198 .tmp_buffer_8ch = NULL,
199 .audioeffect_tmp_buffer = NULL,
200 },
201
202 .aml_Audio_ThreadID = 0,
203 .aml_Audio_ThreadTurnOnFlag = 0,
204 .aml_Audio_ThreadExecFlag = 0,
205 .has_EQ_lib = 0,
206 .has_SRS_lib = 0,
207 .has_aml_IIR_lib = 0,
208 .output_mode = MODEAMAUDIO,
209 .android_check_ThreadID = 0,
210};
211
212struct circle_buffer android_out_buffer = {
213 .lock = PTHREAD_MUTEX_INITIALIZER,
214 .start_add = NULL,
215 .rd = NULL,
216 .wr = NULL,
217 .size = 0,
218};
219
220struct circle_buffer DDP_out_buffer = {
221 .lock = PTHREAD_MUTEX_INITIALIZER,
222 .start_add = NULL,
223 .rd = NULL,
224 .wr = NULL,
225 .size = 0,
226};
227
228struct circle_buffer DD_out_buffer = {
229 .lock = PTHREAD_MUTEX_INITIALIZER,
230 .start_add = NULL,
231 .rd = NULL,
232 .wr = NULL,
233 .size = 0,
234};
235
236static void *start_temp_buffer = NULL;
237static struct aml_dev *gpAmlDevice = NULL;
238static pthread_mutex_t amaudio_dev_op_mutex = PTHREAD_MUTEX_INITIALIZER;
239static unsigned int gUSBCheckLastFlag = 0;
240static unsigned int gUSBCheckFlag = 0;
241
242extern int omx_codec_init(void);
243extern int omx_codec_dts_init(void);
244extern void omx_codec_close(void);
245extern void omx_codec_dts_close(void);
246
247extern int I2S_state;
248
249#define I2S_IN_AUDIO_TYPE "I2SIN Audio Type"
250#define SPDIF_IN_AUDIO_TYPE "SPDIFIN Audio Type"
251#define Audio_In_Source_TYPE "Audio In Source"
252#define HW_RESAMPLE_ENABLE "Hardware resample enable"
253#define AMAUDIO_IN "/dev/amaudio2_in"
254#define AMAUDIO_OUT "/dev/amaudio2_out"
255#define AMAUDIO2_PREENABLE "/sys/class/amaudio2/aml_amaudio2_enable"
256#define AMAUDIO2_INPUTDEVICE "/sys/class/amaudio2/aml_input_device"
257
258#define AMAUDIO_IOC_MAGIC 'A'
259#define AMAUDIO_IOC_GET_SIZE _IOW(AMAUDIO_IOC_MAGIC, 0x00, int)
260#define AMAUDIO_IOC_GET_PTR _IOW(AMAUDIO_IOC_MAGIC, 0x01, int)
261#define AMAUDIO_IOC_RESET _IOW(AMAUDIO_IOC_MAGIC, 0x02, int)
262#define AMAUDIO_IOC_UPDATE_APP_PTR _IOW(AMAUDIO_IOC_MAGIC, 0x03, int)
263#define AMAUDIO_IOC_AUDIO_OUT_MODE _IOW(AMAUDIO_IOC_MAGIC, 0x04, int)
264#define AMAUDIO_IOC_MIC_LEFT_GAIN _IOW(AMAUDIO_IOC_MAGIC, 0x05, int)
265#define AMAUDIO_IOC_MIC_RIGHT_GAIN _IOW(AMAUDIO_IOC_MAGIC, 0x06, int)
266#define AMAUDIO_IOC_MUSIC_GAIN _IOW(AMAUDIO_IOC_MAGIC, 0x07, int)
267
268#define CC_DUMP_SRC_TYPE_INPUT (0)
269#define CC_DUMP_SRC_TYPE_OUTPUT (1)
270#define CC_DUMP_SRC_TYPE_IN_OUT (2)
271#define CC_DUMP_SRC_TYPE_OUT_IN (3)
272
273static int amaudio2_out_handle = -1;
274static int gDumpDataFlag = 0;
275static int gDumpDataFd1 = -1;
276static int gDumpDataFd2 = -1;
277static int audioin_type = 0;
278static int omx_started = 0;
279static int raw_data_counter = 0;
280static int pcm_data_counter = 0;
281static int digital_raw_enable = 0;
282int output_record_enable = 0;
283int spdif_audio_type = LPCM;
284int type_AUDIO_IN = -1;
285pthread_mutex_t device_change_lock = PTHREAD_MUTEX_INITIALIZER;
286
287static void DoDumpData(void *data_buf, int size, int aud_src_type);
288static int audio_effect_process(short* buffer, int frame_size);
289
290static int getprop_bool(const char * path)
291{
292 char buf[PROPERTY_VALUE_MAX];
293 int ret = -1;
294
295 ret = property_get(path, buf, NULL);
296 if (ret > 0) {
297 if (strcasecmp(buf, "true") == 0 || strcmp(buf, "1") == 0)
298 return 1;
299 }
300
301 return 0;
302}
303
304inline int GetWriteSpace(char *WritePoint, char *ReadPoint, int buffer_size) {
305 int bytes;
306
307 if (WritePoint >= ReadPoint) {
308 bytes = buffer_size - (WritePoint - ReadPoint);
309 } else {
310 bytes = ReadPoint - WritePoint;
311 }
312 return bytes;
313}
314
315inline size_t GetReadSpace(char *WritePoint, char *ReadPoint, int buffer_size) {
316 int bytes;
317
318 if (WritePoint >= ReadPoint) {
319 bytes = WritePoint - ReadPoint;
320 } else {
321 bytes = buffer_size - (ReadPoint - WritePoint);
322 }
323 return bytes;
324}
325
326inline int write_to_buffer(char *current_pointer, char *buffer, int bytes,
327 char *start_buffer, int buffer_size) {
328 int left_bytes = start_buffer + buffer_size - current_pointer;
329
330 if (left_bytes >= bytes) {
331 memcpy(current_pointer, buffer, bytes);
332 } else {
333 memcpy(current_pointer, buffer, left_bytes);
334 memcpy(start_buffer, buffer + left_bytes, bytes - left_bytes);
335 }
336 return 0;
337}
338
339inline int read_from_buffer(char *current_pointer, char *buffer, int bytes,
340 char *start_buffer, int buffer_size) {
341 int left_bytes = start_buffer + buffer_size - current_pointer;
342
343 if (left_bytes >= bytes) {
344 memcpy(buffer, current_pointer, bytes);
345 } else {
346 memcpy(buffer, current_pointer, left_bytes);
347 memcpy(buffer + left_bytes, start_buffer, bytes - left_bytes);
348 }
349 return 0;
350}
351
352inline void* update_pointer(char *current_pointer, int bytes,
353 char *start_buffer, int buffer_size) {
354 current_pointer += bytes;
355 if (current_pointer >= start_buffer + buffer_size) {
356 current_pointer -= buffer_size;
357 }
358 return current_pointer;
359}
360
361//Clip from 16.16 fixed-point to 0.15 fixed-point.
362inline static short clip(int x) {
363 if (x < -32768) {
364 return -32768;
365 } else if (x > 32767) {
366 return 32767;
367 } else {
368 return x;
369 }
370}
371
372static int resampler_init(struct aml_stream_in *in) {
373 ALOGD("%s, Init Resampler!\n", __FUNCTION__);
374
375 static const double kPhaseMultiplier = 1L << 28;
376
377 in->resample.FractionStep = (unsigned int) (in->config.rate
378 * kPhaseMultiplier / pcm_config_in.rate);
379 in->resample.SampleFraction = 0;
380
381 size_t buffer_size = in->config.period_size * 4;
382 in->resample_temp_buffer = malloc(buffer_size);
383 if (in->resample_temp_buffer == NULL) {
384 ALOGE("%s, Malloc resample buffer failed!\n", __FUNCTION__);
385 return -1;
386 }
387 in->max_bytes = (in->config.period_size * pcm_config_in.rate
388 / in->config.rate + 1) << 2;
389 return 0;
390}
391
392static int resample_process(struct aml_stream_in *in, unsigned int in_frame,
393 short* input, short* output) {
394 unsigned int inputIndex = 0;
395 unsigned int outputIndex = 0;
396 unsigned int FractionStep = in->resample.FractionStep;
397
398 static const uint32_t kPhaseMask = (1LU << 28) - 1;
399 unsigned int frac = in->resample.SampleFraction;
400 short lastsample_left = in->resample.lastsample_left;
401 short lastsample_right = in->resample.lastsample_right;
402
403 while (inputIndex == 0) {
404 *output++ = clip(
405 (int) lastsample_left
406 + ((((int) input[0] - (int) lastsample_left)
407 * ((int) frac >> 13)) >> 15));
408 *output++ = clip(
409 (int) lastsample_right
410 + ((((int) input[1] - (int) lastsample_right)
411 * ((int) frac >> 13)) >> 15));
412
413 frac += FractionStep;
414 inputIndex += (frac >> 28);
415 frac = (frac & kPhaseMask);
416 outputIndex++;
417 }
418
419 while (inputIndex < in_frame) {
420 *output++ = clip(
421 (int) input[2 * inputIndex - 2]
422 + ((((int) input[2 * inputIndex]
423 - (int) input[2 * inputIndex - 2])
424 * ((int) frac >> 13)) >> 15));
425 *output++ = clip(
426 (int) input[2 * inputIndex - 1]
427 + ((((int) input[2 * inputIndex + 1]
428 - (int) input[2 * inputIndex - 1])
429 * ((int) frac >> 13)) >> 15));
430
431 frac += FractionStep;
432 inputIndex += (frac >> 28);
433 frac = (frac & kPhaseMask);
434 outputIndex++;
435 }
436
437 in->resample.lastsample_left = input[2 * in_frame - 2];
438 in->resample.lastsample_right = input[2 * in_frame - 1];
439 in->resample.SampleFraction = frac;
440
441 return outputIndex;
442}
443
444static int tmp_buffer_init(struct circle_buffer *tmp, int buffer_size) {
445 struct circle_buffer *buf = tmp;
446 pthread_mutex_lock(&buf->lock);
447
448 buf->size = buffer_size;
449 buf->start_add = malloc(buffer_size * sizeof(char));
450 if (buf->start_add == NULL) {
451 ALOGD("%s, Malloc android out buffer error!\n", __FUNCTION__);
452 pthread_mutex_unlock(&buf->lock);
453 return -1;
454 }
455 buf->rd = buf->start_add;
456 buf->wr = buf->start_add + buf->size / 2;
457
458 pthread_mutex_unlock(&buf->lock);
459 return 0;
460}
461
462static int tmp_buffer_release(struct circle_buffer *tmp) {
463 struct circle_buffer *buf = tmp;
464 pthread_mutex_lock(&buf->lock);
465
466 if (buf->start_add != NULL) {
467 free(buf->start_add);
468 buf->start_add = NULL;
469 }
470 buf->rd = NULL;
471 buf->wr = NULL;
472 buf->size = 0;
473
474 pthread_mutex_unlock(&buf->lock);
475 return 0;
476}
477
478static int tmp_buffer_reset(struct circle_buffer *tmp) {
479 struct circle_buffer *buf = tmp;
480 buf->rd = buf->wr + buf->size / 2;
481 if (buf->rd >= (buf->start_add + buf->size))
482 buf->rd -= buf->size;
483 return 0;
484}
485
486int buffer_write(struct circle_buffer *tmp, char* buffer, size_t bytes) {
487 struct circle_buffer *buf = tmp;
488 pthread_mutex_lock(&buf->lock);
489 if (buf->start_add == NULL || buf->wr == NULL || buf->wr == NULL
490 || buf->size == 0) {
491 ALOGE("%s, Buffer malloc fail!\n", __FUNCTION__);
492 pthread_mutex_unlock(&buf->lock);
493 return -1;
494 }
495 size_t write_space = GetWriteSpace(buf->wr, buf->rd, buf->size);
496 if (write_space < bytes) {
497 pthread_mutex_unlock(&buf->lock);
498 return -1;
499 }
500 write_to_buffer(buf->wr, buffer, bytes, buf->start_add, buf->size);
501 buf->wr = update_pointer(buf->wr, bytes, buf->start_add, buf->size);
502 pthread_mutex_unlock(&buf->lock);
503 return bytes;
504}
505
506int buffer_read(struct circle_buffer *tmp, char* buffer, size_t bytes) {
507 struct circle_buffer *buf = tmp;
508 pthread_mutex_lock(&buf->lock);
509 if (buf->start_add == NULL || buf->wr == NULL || buf->wr == NULL
510 || buf->size == 0) {
511 ALOGE("%s, Buffer malloc fail!\n", __FUNCTION__);
512 pthread_mutex_unlock(&buf->lock);
513 return -1;
514 }
515 size_t read_space = GetReadSpace(buf->wr, buf->rd, buf->size);
516 if (read_space < bytes) {
517 pthread_mutex_unlock(&buf->lock);
518 return -1;
519 }
520 read_from_buffer(buf->rd, buffer, bytes, buf->start_add, buf->size);
521 buf->rd = update_pointer(buf->rd, bytes, buf->start_add, buf->size);
522 pthread_mutex_unlock(&buf->lock);
523 return bytes;
524}
525
526static int get_output_deviceID(void);
527
528int GetOutputdevice(void) {
529 return get_output_deviceID();
530}
531
532static int set_input_stream_sample_rate(unsigned int sr,
533 struct aml_stream_in *in) {
534 if (check_input_stream_sr(sr) == 0) {
535 in->config.rate = sr;
536 } else {
537 in->config.rate = pcm_config_in.rate;
538 }
539 return 0;
540}
541
542static int get_aml_card(void) {
543 int card = -1, err = -1;
544 int fd = -1;
545 unsigned fileSize = 512;
546 char *read_buf = NULL, *pd = NULL;
547 static const char * const SOUND_CARDS_PATH = "/proc/asound/cards";
548 fd = open(SOUND_CARDS_PATH, O_RDONLY);
549 if (fd < 0) {
550 ALOGE("ERROR: failed to open config file %s error: %d\n",
551 SOUND_CARDS_PATH, errno);
552 return -EINVAL;
553 }
554
555 read_buf = (char *) malloc(fileSize);
556 if (!read_buf) {
557 ALOGE("Failed to malloc read_buf");
558 close(fd);
559 return -ENOMEM;
560 }
561 memset(read_buf, 0x0, fileSize);
562 err = read(fd, read_buf, fileSize);
563 if (err < 0) {
564 ALOGE("ERROR: failed to read config file %s error: %d\n",
565 SOUND_CARDS_PATH, errno);
566 close(fd);
567 free(read_buf);
568 return -EINVAL;
569 }
570 pd = strstr(read_buf, "AML");
571 card = *(pd - 3) - '0';
572
573 free(read_buf);
574 close(fd);
575 return card;
576}
577
578static int get_aml_device(int device_ID) {
579 int port = -1, err = 0;
580 int fd = -1;
581 unsigned fileSize = 512;
582 char *read_buf = NULL, *pd = NULL;
583 static const char *const SOUND_PCM_PATH = "/proc/asound/pcm";
584 fd = open(SOUND_PCM_PATH, O_RDONLY);
585 if (fd < 0) {
586 ALOGE("ERROR: failed to open config file %s error: %d\n", SOUND_PCM_PATH, errno);
587 close(fd);
588 return -EINVAL;
589 }
590
591 read_buf = (char *)malloc(fileSize);
592 if (!read_buf) {
593 ALOGE("Failed to malloc read_buf");
594 close(fd);
595 return -ENOMEM;
596 }
597 memset(read_buf, 0x0, fileSize);
598 err = read(fd, read_buf, fileSize);
599 if (fd < 0) {
600 ALOGE("ERROR: failed to read config file %s error: %d\n", SOUND_PCM_PATH, errno);
601 close(fd);
602 return -EINVAL;
603 }
604
605 if (device_ID == 1) {
606 pd = strstr(read_buf, "SPDIF");
607 port = *(pd -3) - '0';
608 } else if (device_ID == 0){
609 pd = strstr(read_buf, "I2S");
610 port = *(pd -3) - '0';
611 }
612OUT:
613 free(read_buf);
614 close(fd);
615 return port;
616}
617
618static int alsa_in_open(struct aml_stream_in *in) {
619 in->config.channels = pcm_config_in.channels;
620 in->config.period_size = pcm_config_in.period_size;
621 in->config.period_count = pcm_config_in.period_count;
622 in->config.format = pcm_config_in.format;
623 in->config.stop_threshold = CAPTURE_PERIOD_SIZE * CAPTURE_PERIOD_COUNT * 10;
624 in->standby = 1;
625 in->resample_request = 0;
626 in->resample_temp_buffer = NULL;
627 in->max_bytes = in->config.period_size << 2;
628 in->pre_gain = 1.0;
629 in->pre_mute = 0;
630
631 if (in->config.rate == 0) {
632 in->config.rate = pcm_config_in.rate;
633 }
634
635 if (in->config.rate != pcm_config_in.rate) {
636 in->resample_request = 1;
637 int ret = resampler_init(in);
638 if (ret < 0) {
639 return -1;
640 }
641 }
642
643 pthread_mutex_lock(&in->lock);
644 in->card = get_aml_card();
645 in->pcm = pcm_open(in->card, in->device, PCM_IN, &(in->config));
646 if (!pcm_is_ready(in->pcm)) {
647 ALOGE("%s, Unable to open PCM device in: %s\n", __FUNCTION__,
648 pcm_get_error(in->pcm));
649 pcm_close(in->pcm);
650 pthread_mutex_unlock(&in->lock);
651 return -1;
652 }
653
654 in->standby = 0;
655 ALOGD("%s, Input device is opened: card(%d), device(%d)\n", __FUNCTION__,
656 in->card, in->device);
657 pthread_mutex_unlock(&in->lock);
658 return 0;
659}
660
661static int alsa_in_close(struct aml_stream_in *in) {
662 ALOGD("%s, Do input close!\n", __FUNCTION__);
663
664 pthread_mutex_lock(&in->lock);
665 if (!in->standby) {
666 pcm_close(in->pcm);
667 in->pcm = NULL;
668 in->standby = 1;
669 }
670 if (in->resample_request && (in->resample_temp_buffer != NULL)) {
671 free(in->resample_temp_buffer);
672 in->resample_temp_buffer = NULL;
673 }
674 pthread_mutex_unlock(&in->lock);
675 return 0;
676}
677
678static int get_in_framesize(struct aml_stream_in *in) {
679 int sample_format = 0;
680 if (in->config.format == PCM_FORMAT_S16_LE) {
681 sample_format = 2;
682 }
683 return sample_format * in->config.channels;
684}
685
686static void apply_stream_volume_and_pregain(float vol, float gain, char *buf, int size) {
687 uint i;
688 short *sample = (short*)buf;
689 for (i = 0; i < size/sizeof(short); i++)
690 sample[i] = gain*vol*sample[i];
691}
692
693static int alsa_in_read(struct aml_stream_in *in, void* buffer, size_t bytes) {
694 int ret;
695 int resample_request = in->resample_request;
696
697 pthread_mutex_lock(&in->lock);
698 if (in->standby) {
699 pthread_mutex_unlock(&in->lock);
700 ALOGD("%s, Input device is closed!\n", __FUNCTION__);
701 return 0;
702 }
703 //if raw data in HDMI-in, no need to resample
704 if (GetOutputdevice() == 2) {
705 resample_request = 0;
706 }
707
708 int output_size = 0;
709 if (resample_request == 1) {
710 ret = pcm_read(in->pcm, in->resample_temp_buffer, bytes);
711 if (ret < 0) {
712 //wait for next frame
713 usleep(bytes * 1000000 / get_in_framesize(in) / in->config.rate);
714 pthread_mutex_unlock(&in->lock);
715 return ret;
716 }
717
718 if (GetOutputdevice() != 2 &&
719 (gUSBCheckFlag & AUDIO_DEVICE_OUT_SPEAKER) != 0) {
720 float vol = get_android_stream_volume();
721 float gain = in->pre_gain;
722 uint pre_mute = in->pre_mute;
723 if (!pre_mute)
724 apply_stream_volume_and_pregain(vol,gain,in->resample_temp_buffer,bytes);
725 else
726 memset(in->resample_temp_buffer, 0, bytes);
727 }
728 DoDumpData(in->resample_temp_buffer, bytes, CC_DUMP_SRC_TYPE_INPUT);
729
730 output_size = resample_process(in, bytes >> 2,
731 (short *) in->resample_temp_buffer, (short *) buffer) << 2;
732 } else {
733 ret = pcm_read(in->pcm, buffer, bytes);
734 if (ret < 0) {
735 //wait for next frame
736 usleep(bytes * 1000000 / get_in_framesize(in) / in->config.rate);
737 ALOGE("Can't read data from alsa!\n");
738 pthread_mutex_unlock(&in->lock);
739 return ret;
740 }
741
742 if (GetOutputdevice() != 2 &&
743 (gUSBCheckFlag & AUDIO_DEVICE_OUT_SPEAKER) != 0) {
744 float vol = get_android_stream_volume();
745 float gain = in->pre_gain;
746 uint pre_mute = in->pre_mute;
747 if (!pre_mute)
748 apply_stream_volume_and_pregain(vol,gain,buffer,bytes);
749 else
750 memset(buffer, 0, bytes);
751 }
752 if (type_AUDIO_IN == 2 && GetOutputdevice() != 2) {
753 short *ptr = buffer;
754 short data;
755 int i = 0;
756 int frame_size = bytes >> 2;
757 for (i = 0; i < frame_size; i++) {
758 data = (short)audio_IIR_process((int)(*ptr), 0);
759 *ptr++ = data;
760 data = (short)audio_IIR_process((int)(*ptr), 1);
761 *ptr++ = data;
762 }
763 }
764 DoDumpData(buffer, bytes, CC_DUMP_SRC_TYPE_INPUT);
765
766 output_size = bytes;
767 }
768 pthread_mutex_unlock(&in->lock);
769 return output_size;
770}
771
772static int alsa_out_open(struct aml_stream_out *out) {
773 out->config.period_size = pcm_config_out.period_size;
774 out->config.rate = pcm_config_out.rate;
775 out->config.period_count = pcm_config_out.period_count;
776 out->standby = 1;
777 if (getprop_bool("ro.platform.has.tvuimode")) {
778 out->config.channels = 8;
779 out->config.format = PCM_FORMAT_S32_LE;
780 out->tmp_buffer_8ch = malloc(out->config.period_size * 4 * 8); /*8 channel, 32bit*/
781 if (out->tmp_buffer_8ch == NULL) {
782 ALOGE("cannot malloc memory for out->tmp_buffer_8ch");
783 return -ENOMEM;
784 }
785 out->audioeffect_tmp_buffer = malloc(out->config.period_size * 6);
786 if (out->audioeffect_tmp_buffer == NULL) {
787 ALOGE("cannot malloc memory for audioeffect_tmp_buffer");
788 return -ENOMEM;
789 }
790 out->is_tv_platform = 1;
791 }else {
792 out->config.channels = pcm_config_out.channels;
793 out->config.format = pcm_config_out.format;
794 out->is_tv_platform = 0;
795 }
796
797 pthread_mutex_lock(&out->lock);
798 out->card = get_aml_card();
799 out->pcm = pcm_open(out->card, out->device, PCM_OUT, &(out->config));
800 if (!pcm_is_ready(out->pcm)) {
801 ALOGE("%s, Unable to open PCM device out: %s\n", __FUNCTION__,
802 pcm_get_error(out->pcm));
803 pcm_close(out->pcm);
804 pthread_mutex_unlock(&out->lock);
805 return -1;
806 }
807 out->standby = 0;
808 ALOGD("%s, Output device is opened: card(%d), device(%d)\n", __FUNCTION__,
809 out->card, out->device);
810 pthread_mutex_unlock(&out->lock);
811 return 0;
812}
813
814static int alsa_out_close(struct aml_stream_out *out) {
815 ALOGD("%s, Do output close!\n", __FUNCTION__);
816
817 pthread_mutex_lock(&out->lock);
818 if (out->is_tv_platform == 1) {
819 free(out->tmp_buffer_8ch);
820 free(out->audioeffect_tmp_buffer);
821 out->is_tv_platform = 0;
822 }
823 if (!out->standby) {
824 pcm_close(out->pcm);
825 out->pcm = NULL;
826 out->standby = 1;
827 }
828 pthread_mutex_unlock(&out->lock);
829 return 0;
830}
831
832static int get_out_framesize(struct aml_stream_out *out) {
833 int sample_format = 0;
834 if (out->config.format == PCM_FORMAT_S16_LE)
835 sample_format = 2;
836 return sample_format * out->config.channels;
837}
838
839static int alsa_out_write(struct aml_stream_out *out, void* buffer,
840 size_t bytes) {
841 int ret;
842 int input_frames = bytes >> 2;
843
844 pthread_mutex_lock(&out->lock);
845 if (out->standby) {
846 pthread_mutex_unlock(&out->lock);
847 ALOGD("%s, Output device is closed!\n", __FUNCTION__);
848 return 0;
849 }
850
851 if (out->is_tv_platform == 1) {
852 int16_t *tmp_buffer = (int16_t *)out->audioeffect_tmp_buffer;
853 int16_t *in_buffer = (int16_t *)buffer;
854 int out_byte = input_frames * 32;
855 int i = 0;
856 memcpy((void *)tmp_buffer, buffer, bytes);
857 audio_effect_process(tmp_buffer, input_frames);
858 for (i = 0; i < input_frames; i ++) {
859 out->tmp_buffer_8ch[8*i] = ((int32_t)(in_buffer[2*i])) << 16;
860 out->tmp_buffer_8ch[8*i + 1] = ((int32_t)(in_buffer[2*i + 1])) << 16;
861 out->tmp_buffer_8ch[8*i + 2] = ((int32_t)(tmp_buffer[2*i])) << 16;
862 out->tmp_buffer_8ch[8*i + 3] = ((int32_t)(tmp_buffer[2*i + 1])) << 16;
863 out->tmp_buffer_8ch[8*i + 4] = 0;
864 out->tmp_buffer_8ch[8*i + 5] = 0;
865 out->tmp_buffer_8ch[8*i + 6] = 0;
866 out->tmp_buffer_8ch[8*i + 7] = 0;
867 }
868 ret = pcm_write(out->pcm, out->tmp_buffer_8ch, out_byte);
869 } else {
870 audio_effect_process((short *)buffer, input_frames);
871 ret = pcm_write(out->pcm, buffer, bytes);
872 }
873
874 if (ret < 0) {
875 usleep(bytes * 1000000 / get_out_framesize(out) / out->config.rate);
876 pthread_mutex_unlock(&out->lock);
877 return ret;
878 }
879
880 pthread_mutex_unlock(&out->lock);
881 return bytes;
882}
883
884static int reset_amaudio(struct aml_stream_out *out, int delay_size) {
885 struct buffer_status *buf = &out->playback_buf;
886 buf->rd = 0;
887 buf->wr = 0;
888 buf->level = buf->size;
889 int ret = ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_RESET, delay_size);
890 if (ret < 0) {
891 ALOGE("%s, amaudio reset delay_size error!\n", __FUNCTION__);
892 return -1;
893 }
894 return 0;
895}
896
897static int set_amaudio2_enable(int flag) {
898 int fd = 0;
899 char string[16];
900 fd = open(AMAUDIO2_PREENABLE, O_CREAT | O_RDWR, 0664);
901 if (fd < 0) {
902 ALOGE("unable to open file %s \n", AMAUDIO2_PREENABLE);
903 return -1;
904 }
905 sprintf(string, "%d", flag);
906 write(fd, string, strlen(string));
907 close(fd);
908 return 0;
909}
910
911static int set_input_device(int flag) {
912 int fd = 0;
913 char string[16];
914 fd = open(AMAUDIO2_INPUTDEVICE, O_CREAT | O_RDWR, 0664);
915 if (fd < 0) {
916 ALOGE("unable to open file %s \n", AMAUDIO2_INPUTDEVICE);
917 return -1;
918 }
919 sprintf(string, "%d", flag);
920 write(fd, string, strlen(string));
921 close(fd);
922 return 0;
923}
924
925static int new_audiotrack(struct aml_stream_out *out) {
926 int ret = 0, i = 0;
927 pthread_mutex_lock(&out->lock);
928 //ALOGD("%s, entering...\n", __FUNCTION__);
929
930 if (gpAmlDevice == NULL) {
931 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
932 pthread_mutex_unlock(&out->lock);
933 return -1;
934 }
935
936 set_amaudio2_enable(1);
937 ret = new_android_audiotrack();
938 if (ret < 0) {
939 ALOGE("%s, New an audio track is fail!\n", __FUNCTION__);
940 pthread_mutex_unlock(&out->lock);
941 return -1;
942 }
943
944 /* amaudio needs alsa running first to get the right params, so wait to make sure track is on */
945 if (out->user_set_device == CC_OUT_USE_AMAUDIO) {
946 while (I2S_state < 5 && gpAmlDevice->aml_Audio_ThreadTurnOnFlag == 1) {
947 usleep(10 * 1000);
948 i++;
949 if (i >= 500) {
950 ALOGE("Time out error: wait %d s for waiting I2S ready.\n", i/100);
951 pthread_mutex_unlock(&out->lock);
952 return -1;
953 }
954 }
955
956 ALOGD("Wait %d times for waiting I2S ready.\n", i);
957 }
958
959 pthread_mutex_unlock(&out->lock);
960 return 0;
961}
962
963static int release_audiotrack(struct aml_stream_out *out) {
964 ALOGD("%s, Release audio track!\n", __FUNCTION__);
965 pthread_mutex_lock(&out->lock);
966 int ret = release_android_audiotrack();
967 if (ret < 0) {
968 ALOGE("%s, Delete audio track is fail!\n", __FUNCTION__);
969 }
970 set_amaudio2_enable(0);
971 pthread_mutex_unlock(&out->lock);
972 return 0;
973}
974
975static int amaudio_out_open(struct aml_stream_out *out) {
976 out->config.period_size = pcm_config_out.period_size;
977 out->config.rate = pcm_config_out.rate;
978 out->config.period_count = pcm_config_out.period_count;
979 out->standby = 1;
980 if (getprop_bool("ro.platform.has.tvuimode")) {
981 out->config.channels = 8;
982 out->config.format = PCM_FORMAT_S32_LE;
983 out->tmp_buffer_8ch = malloc(out->config.period_size * 4 * 8); /*8 channel, 32bit*/
984 if (out->tmp_buffer_8ch == NULL) {
985 ALOGE("cannot malloc memory for out->tmp_buffer_8ch");
986 return -ENOMEM;
987 }
988 out->audioeffect_tmp_buffer = malloc(out->config.period_size * 6);
989 if (out->audioeffect_tmp_buffer == NULL) {
990 ALOGE("cannot malloc memory for audioeffect_tmp_buffer");
991 return -ENOMEM;
992 }
993 out->is_tv_platform = 1;
994 }else {
995 out->config.channels = pcm_config_out.channels;
996 out->config.format = pcm_config_out.format;
997 out->is_tv_platform = 0;
998 }
999
1000 pthread_mutex_lock(&out->lock);
1001 out->amAudio_OutHandle = -1;
1002 out->amAudio_OutHandle = open(AMAUDIO_OUT, O_RDWR);
1003 if (out->amAudio_OutHandle < 0) {
1004 close(out->amAudio_OutHandle);
1005 out->amAudio_OutHandle = -1;
1006 release_android_audiotrack();
1007 pthread_mutex_unlock(&out->lock);
1008 ALOGE("%s, The device amaudio_out cant't be opened!\n", __FUNCTION__);
1009 return -1;
1010 }
1011
1012 struct buffer_status *buf = &out->playback_buf;
1013 buf->size = ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_GET_SIZE);
1014 buf->start_add = (unsigned char*) mmap(NULL, buf->size, PROT_READ | PROT_WRITE,
1015 MAP_FILE | MAP_SHARED, out->amAudio_OutHandle, 0);
1016 if (buf->start_add == 0) {
1017 close(out->amAudio_OutHandle);
1018 out->amAudio_OutHandle = -1;
1019 release_android_audiotrack();
1020 pthread_mutex_unlock(&out->lock);
1021 ALOGE("%s, Error create mmap!\n", __FUNCTION__);
1022 return -1;
1023 }
1024
1025 out->standby = 0;
1026 pthread_mutex_unlock(&out->lock);
1027 ALOGD("%s, Amaudio device is opened!\n", __FUNCTION__);
1028 return 0;
1029}
1030
1031static int amaudio_out_close(struct aml_stream_out *out) {
1032 ALOGD("%s, Do amaudio device close!\n", __FUNCTION__);
1033 pthread_mutex_lock(&out->lock);
1034 if (out->is_tv_platform == 1) {
1035 free(out->tmp_buffer_8ch);
1036 free(out->audioeffect_tmp_buffer);
1037 }
1038 if (out->amAudio_OutHandle > 0) {
1039 close(out->amAudio_OutHandle);
1040 out->amAudio_OutHandle = -1;
1041 munmap(out->playback_buf.start_add, out->playback_buf.size);
1042 }
1043 pthread_mutex_unlock(&out->lock);
1044 return 0;
1045}
1046
1047static int amaudio_out_write(struct aml_stream_out *out, void* buffer,
1048 size_t bytes) {
1049 struct buffer_status *buf = &out->playback_buf;
1050 int input_frames = bytes >> 2;
1051 unsigned char *out_buffer = NULL;
1052
1053 pthread_mutex_lock(&out->lock);
1054
1055 if (out->is_tv_platform == 1) {
1056 int16_t *tmp_buffer = (int16_t *)out->audioeffect_tmp_buffer;
1057 int16_t *in_buffer = (int16_t *)buffer;
1058 size_t out_byte = input_frames * 32;
1059 int i = 0;
1060
1061 memcpy((void *)tmp_buffer, buffer, bytes);
1062 audio_effect_process(tmp_buffer, input_frames);
1063 for (i = 0; i < input_frames; i ++) {
1064 out->tmp_buffer_8ch[8*i] = ((int32_t)(in_buffer[2*i])) << 16;
1065 out->tmp_buffer_8ch[8*i + 1] = ((int32_t)(in_buffer[2*i + 1])) << 16;
1066 out->tmp_buffer_8ch[8*i + 2] = ((int32_t)(tmp_buffer[2*i])) << 16;
1067 out->tmp_buffer_8ch[8*i + 3] = ((int32_t)(tmp_buffer[2*i + 1])) << 16;
1068 out->tmp_buffer_8ch[8*i + 4] = 0;
1069 out->tmp_buffer_8ch[8*i + 5] = 0;
1070 out->tmp_buffer_8ch[8*i + 6] = 0;
1071 out->tmp_buffer_8ch[8*i + 7] = 0;
1072 }
1073
1074 //get rd ptr, and calculate write space
1075 buf->rd = ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_GET_PTR);
1076 buf->level = buf->size - ((buf->size + buf->wr - buf->rd) % buf->size);
1077
1078 if (buf->level <= out_byte) {
1079 ALOGD("Reset amaudio: buf->level=%x,buf->rd = %x,buf->wr=%x\n",
1080 buf->level, buf->rd, buf->wr);
1081 pthread_mutex_unlock(&out->lock);
1082 return -1;
1083 }
1084 out_buffer = buf->start_add + buf->wr;
1085 memcpy((void *)out_buffer, (void *)out->tmp_buffer_8ch, out_byte);
1086
1087 // update the write pointer and write space
1088 buf->wr = (buf->wr + out_byte) % buf->size;
1089 buf->level = buf->size - ((buf->size + buf->wr - buf->rd) % buf->size);
1090 ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_UPDATE_APP_PTR, buf->wr);
1091
1092 } else {
1093 audio_effect_process((short *)buffer, input_frames);
1094
1095 //get rd ptr, and calculate write space
1096 buf->rd = ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_GET_PTR);
1097 buf->level = buf->size - ((buf->size + buf->wr - buf->rd) % buf->size);
1098
1099 if (buf->level <= bytes) {
1100 ALOGD("Reset amaudio: buf->level=%x,buf->rd = %x,buf->wr=%x\n",
1101 buf->level, buf->rd, buf->wr);
1102 pthread_mutex_unlock(&out->lock);
1103 return -1;
1104 }
1105 out_buffer = buf->start_add + buf->wr;
1106 memcpy((void *)out_buffer, buffer, bytes);
1107
1108 // update the write pointer and write space
1109 buf->wr = (buf->wr + bytes) % buf->size;
1110 buf->level = buf->size - ((buf->size + buf->wr - buf->rd) % buf->size);
1111 ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_UPDATE_APP_PTR, buf->wr);
1112 }
1113
1114 pthread_mutex_unlock(&out->lock);
1115 return bytes;
1116}
1117
1118static int malloc_buffer(struct aml_dev *device) {
1119 void *buffer = NULL;
1120 struct aml_stream_in *in = &device->in;
1121 struct aml_stream_out *out = &device->out;
1122
1123 buffer = malloc(TEMP_BUFFER_SIZE);
1124 if (buffer == NULL) {
1125 ALOGD("%s, Malloc temp buffer failed!\n", __FUNCTION__);
1126 return -1;
1127 }
1128 start_temp_buffer = buffer;
1129 in->write_buffer = buffer;
1130 out->read_buffer = buffer;
1131
1132 in->temp_buffer = malloc(in->max_bytes);
1133 if (in->temp_buffer == NULL) {
1134 ALOGD("%s, Malloc input temp buffer failed!\n", __FUNCTION__);
1135 return -1;
1136 }
1137
1138 out->temp_buffer = malloc(pcm_config_out.period_size << 2);
1139 if (out->temp_buffer == NULL) {
1140 ALOGD("%s, Malloc output temp buffer failed!\n", __FUNCTION__);
1141 return -1;
1142 }
1143
1144 return 0;
1145}
1146
1147static int release_buffer(struct aml_dev *device) {
1148 struct aml_stream_in *in = &device->in;
1149 struct aml_stream_out *out = &device->out;
1150
1151 if (start_temp_buffer != NULL) {
1152 free(start_temp_buffer);
1153 start_temp_buffer = NULL;
1154 in->write_buffer = NULL;
1155 out->read_buffer = NULL;
1156 }
1157 if (in->temp_buffer != NULL) {
1158 free(in->temp_buffer);
1159 in->temp_buffer = NULL;
1160 }
1161 if (out->temp_buffer != NULL) {
1162 free(out->temp_buffer);
1163 out->temp_buffer = NULL;
1164 }
1165 return 0;
1166}
1167
1168static int audio_effect_release() {
1169 unload_EQ_lib();
1170 unload_SRS_lib();
1171 unload_aml_IIR_lib();
1172 return 0;
1173}
1174
1175static int set_output_deviceID(int deviceID) {
1176 int ret;
1177
1178 if (gpAmlDevice == NULL) {
1179 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1180 return -1;
1181 }
1182
1183 gpAmlDevice->output_mode = deviceID;
1184 ALOGE("%s, set output device ID: %d!\n", __FUNCTION__, deviceID);
1185 return 0;
1186}
1187
1188static int get_output_deviceID(void) {
1189 if (gpAmlDevice == NULL) {
1190 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1191 return -1;
1192 }
1193 return gpAmlDevice->output_mode;
1194}
1195
1196static int aml_device_init(struct aml_dev *device) {
1197 int ret;
1198
1199 ALOGD("%s, start to open Devices!\n", __FUNCTION__);
1200
1201 //Malloc temp buffer for audiotrak out
1202 ret = tmp_buffer_init(&android_out_buffer, ANDROID_OUT_BUFFER_SIZE);
1203 if (ret < 0) {
1204 ALOGE("%s, malloc temp buffer error!\n", __FUNCTION__);
1205 goto error1;
1206 }
1207
1208 ret = tmp_buffer_init(&DDP_out_buffer, DDP_OUT_BUFFER_SIZE);
1209 if (ret < 0) {
1210 ALOGE("%s, malloc ddp buffer failed!\n", __FUNCTION__);
1211 goto error2;
1212 }
1213 // add a temp buffer to store dd 61937 audio frame
1214 ret = tmp_buffer_init(&DD_out_buffer, DD_61937_BUFFER_SIZE);
1215 if (ret < 0) {
1216 ALOGE("%s, malloc dd 61937 buffer failed!\n", __FUNCTION__);
1217 goto error3;
1218 }
1219 //open input device of tinyalsa
1220 ret = alsa_in_open(&device->in);
1221 if (ret < 0) {
1222 ALOGE("%s, open alsa in device open error!\n", __FUNCTION__);
1223 goto error3;
1224 }
1225
1226 //Malloc temp buffer for input and output
1227 ret = malloc_buffer(device);
1228 if (ret < 0) {
1229 ALOGE("%s, malloc buffer error!\n", __FUNCTION__);
1230 goto error4;
1231 }
1232
1233 if (device->out.user_set_device == CC_OUT_USE_ALSA) {
1234 set_output_deviceID(MODEAMAUDIO);
1235 //open output device of tinyalsa
1236 ret = alsa_out_open(&device->out);
1237 if (ret < 0) {
1238 ALOGE("%s, open alsa out device open error!\n", __FUNCTION__);
1239 goto error5;
1240 }
1241 } else if (device->out.user_set_device == CC_OUT_USE_AMAUDIO) {
1242 set_output_deviceID(MODEAMAUDIO);
1243 //open output device of amaudio
1244 ret = new_audiotrack(&device->out);
1245 if (ret < 0) {
1246 ALOGE("%s, new audiotrack error!\n", __FUNCTION__);
1247 goto error5;
1248 }
1249 ret = amaudio_out_open(&device->out);
1250 if (ret < 0) {
1251 release_audiotrack(&device->out);
1252 ALOGE("%s, open amaudio out device error!\n", __FUNCTION__);
1253 goto error5;
1254 }
1255 } else if (device->out.user_set_device == CC_OUT_USE_ANDROID) {
1256 set_output_deviceID(MODEANDROID);
1257 ret = new_audiotrack(&device->out);
1258 if (ret < 0) {
1259 ALOGE("%s, open android out device error!\n", __FUNCTION__);
1260 goto error5;
1261 }
1262 }
1263
1264 //EQ lib load and init EQ
1265 ret = load_EQ_lib();
1266 if (ret < 0) {
1267 ALOGE("%s, Load EQ lib fail!\n", __FUNCTION__);
1268 device->has_EQ_lib = 0;
1269 } else {
1270 ret = HPEQ_init();
1271 if (ret < 0) {
1272 device->has_EQ_lib = 0;
1273 } else {
1274 device->has_EQ_lib = 1;
1275 }
1276 HPEQ_enable(1);
1277 }
1278
1279 //load srs lib and init it. SRS is behand resampling, so sample rate is as default sr.
1280 ret = load_SRS_lib();
1281 if (ret < 0) {
1282 ALOGE("%s, Load SRS lib fail!\n", __FUNCTION__);
1283 device->has_SRS_lib = 0;
1284 } else {
1285 ret = srs_init(device->out.config.rate);
1286 if (ret < 0) {
1287 device->has_SRS_lib = 0;
1288 } else {
1289 device->has_SRS_lib = 1;
1290 }
1291 }
1292
1293 //load aml_IIR lib
1294 ret = load_aml_IIR_lib();
1295 if (ret < 0) {
1296 ALOGE("%s, Load aml_IIR lib fail!\n", __FUNCTION__);
1297 device->has_aml_IIR_lib = 0;
1298 } else {
1299 char value[PROPERTY_VALUE_MAX];
1300 int paramter = 0;
1301 if (property_get("media.audio.LFP.paramter", value, NULL) > 0) {
1302 paramter = atoi(value);
1303 }
1304 aml_IIR_init(paramter);
1305 device->has_aml_IIR_lib = 1;
1306 }
1307
1308 audio_IIR_init();
1309
1310 ALOGD("%s, exiting...\n", __FUNCTION__);
1311 return 0;
1312
1313 error5: release_buffer(device);
1314 error4: alsa_in_close(&device->in);
1315 error3: tmp_buffer_release (&DDP_out_buffer);
1316 tmp_buffer_release (&DD_out_buffer);
1317 error2: tmp_buffer_release (&android_out_buffer);
1318 error1: return ret;
1319
1320}
1321
1322static int aml_device_close(struct aml_dev *device) {
1323 struct aml_stream_in *in = &device->in;
1324 struct aml_stream_out *out = &device->out;
1325
1326 alsa_in_close(in);
1327
1328 if (in->delay_buf.size != 0) {
1329 free(in->delay_buf.start_add);
1330 }
1331
1332 if (out->output_device == CC_OUT_USE_ALSA) {
1333 alsa_out_close(out);
1334 } else if (out->output_device == CC_OUT_USE_AMAUDIO) {
1335 amaudio_out_close(out);
1336 release_audiotrack(out);
1337 } else if (out->output_device == CC_OUT_USE_ANDROID) {
1338 release_audiotrack(out);
1339 }
1340
1341 omx_codec_close();
1342 omx_codec_dts_close();
1343 omx_started = 0;
1344 tmp_buffer_release (&DDP_out_buffer);
1345 tmp_buffer_release (&DD_out_buffer);
1346 tmp_buffer_release (&android_out_buffer);
1347 release_buffer(device);
1348 audio_effect_release();
1349 return 0;
1350}
1351
1352static void USB_check(struct aml_stream_out *out) {
1353
1354 gUSBCheckFlag = GetUsbAudioCheckFlag();
1355 if (gUSBCheckLastFlag == gUSBCheckFlag) {
1356 return;
1357 }
1358
1359 ALOGI("Audio Device is changed from %x to %x!\n", gUSBCheckLastFlag, gUSBCheckFlag);
1360
1361 //if audio record from submix, don't change device
1362 if ((gUSBCheckFlag & AUDIO_DEVICE_OUT_REMOTE_SUBMIX) != 0) {
1363 gUSBCheckLastFlag = gUSBCheckFlag;
1364 set_output_record_enable(1);
1365 return;
1366 } else if((gUSBCheckLastFlag & AUDIO_DEVICE_OUT_REMOTE_SUBMIX) != 0) {
1367 gUSBCheckLastFlag = gUSBCheckFlag;
1368 set_output_record_enable(0);
1369 return;
1370 }
1371
1372 if ((gUSBCheckFlag & AUDIO_DEVICE_OUT_SPEAKER) == 0) {
1373 if (out->output_device == CC_OUT_USE_AMAUDIO && omx_started == 0) {
1374 amaudio_out_close(out);
1375 set_output_deviceID(MODEANDROID);
1376 out->output_device = CC_OUT_USE_ANDROID;
1377 } else if (out->output_device == CC_OUT_USE_ALSA && omx_started == 0) {
1378 alsa_out_close(out);
1379 new_audiotrack(out);
1380 set_output_deviceID(MODEANDROID);
1381 out->output_device = CC_OUT_USE_ANDROID;
1382 }
1383 ALOGI("%s, USB audio playback device is in.\n", __FUNCTION__);
1384 } else if ((gUSBCheckFlag & AUDIO_DEVICE_OUT_SPEAKER) != 0 && gUSBCheckLastFlag != 0) {
1385 if (out->user_set_device == CC_OUT_USE_AMAUDIO && omx_started == 0) {
1386 amaudio_out_open(out);
1387 set_output_deviceID(MODEAMAUDIO);
1388 out->output_device = CC_OUT_USE_AMAUDIO;
1389 } else if (out->user_set_device == CC_OUT_USE_ALSA
1390 && omx_started == 0) {
1391 release_audiotrack(out);
1392 alsa_out_open(out);
1393 set_output_deviceID(MODEAMAUDIO);
1394 out->output_device = CC_OUT_USE_ALSA;
1395 }
1396 ALOGI("%s, USB audio playback device is out.\n", __FUNCTION__);
1397 }
1398 gUSBCheckLastFlag = gUSBCheckFlag;
1399 return;
1400}
1401
1402static int get_channel_status(void) {
1403 struct mixer *pmixer;
1404 struct mixer_ctl *pctl;
1405 int card_id;
1406 int type_I2S = -1;
1407 int type_SPDIF = -1;
1408
1409 card_id = get_aml_card();
1410 pmixer = mixer_open(card_id);
1411 if (NULL == pmixer) {
1412 ALOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__);
1413 goto err_exit;
1414 }
1415 pctl = mixer_get_ctl_by_name(pmixer, Audio_In_Source_TYPE);
1416 if (NULL != pctl) {
1417 type_AUDIO_IN = mixer_ctl_get_value(pctl, 0);
1418 if (type_AUDIO_IN != 2) {
1419 mixer_close(pmixer);
1420 return LPCM;
1421 }
1422 }
1423
1424 pctl = mixer_get_ctl_by_name(pmixer, SPDIF_IN_AUDIO_TYPE);
1425 if (NULL != pctl) {
1426 type_SPDIF = mixer_ctl_get_value(pctl, 0);
1427 }
1428
1429 pctl = mixer_get_ctl_by_name(pmixer, I2S_IN_AUDIO_TYPE);
1430 if (NULL != pctl) {
1431 type_I2S = mixer_ctl_get_value(pctl, 0);
1432 }
1433
1434 if (type_SPDIF == LPCM && type_I2S == AC3) {
1435 mixer_close(pmixer);
1436 return MUTE;
1437 }
1438
1439 mixer_close(pmixer);
1440 return type_SPDIF;
1441
1442err_exit:
1443 if (NULL != pmixer) {
1444 mixer_close(pmixer);
1445 }
1446 return -1;
1447}
1448
1449static int set_Hardware_resample(int enable) {
1450 struct mixer *pmixer;
1451 struct mixer_ctl *pctl;
1452 int card_id;
1453 card_id = get_aml_card();
1454 pmixer = mixer_open(card_id);
1455 if (NULL == pmixer) {
1456 ALOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__);
1457 goto err_exit;
1458 }
1459 pctl = mixer_get_ctl_by_name(pmixer, HW_RESAMPLE_ENABLE);
1460 if (NULL != pctl) {
1461 mixer_ctl_set_value(pctl, 0, enable);
1462 }
1463err_exit:
1464 if (NULL != pmixer) {
1465 mixer_close(pmixer);
1466 }
1467 return -1;
1468 }
1469
1470 static int set_rawdata_in_enable(struct aml_stream_out *out) {
1471 if (out->output_device == CC_OUT_USE_AMAUDIO) {
1472 amaudio_out_close(out);
1473 } else if (out->output_device == CC_OUT_USE_ALSA) {
1474 alsa_out_close(out);
1475 new_audiotrack(out);
1476 }
1477 set_output_deviceID(MODERAW);
1478 out->output_device = CC_OUT_USE_ANDROID;
1479 set_Hardware_resample(4);
1480 digital_raw_enable = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
1481 if (audioin_type == AC3 || audioin_type == EAC3)
1482 omx_codec_init();
1483 if (audioin_type == DTS || audioin_type == DTSHD)
1484 omx_codec_dts_init();
1485 return 0;
1486}
1487
1488static int set_rawdata_in_disable(struct aml_stream_out *out) {
1489
1490 omx_codec_close();
1491 omx_codec_dts_close();
1492 if ((gUSBCheckFlag & AUDIO_DEVICE_OUT_SPEAKER) != 0) {
1493 if (out->user_set_device == CC_OUT_USE_AMAUDIO) {
1494 set_output_deviceID(MODEAMAUDIO);
1495 amaudio_out_open(out);
1496 out->output_device = CC_OUT_USE_AMAUDIO;
1497 } else if (out->user_set_device == CC_OUT_USE_ANDROID) {
1498 set_output_deviceID(MODEANDROID);
1499 out->output_device = CC_OUT_USE_ANDROID;
1500 } else if (out->user_set_device == CC_OUT_USE_ALSA) {
1501 release_audiotrack(out);
1502 alsa_out_open(out);
1503 set_output_deviceID(MODEAMAUDIO);
1504 out->output_device = CC_OUT_USE_ALSA;
1505 }
1506 } else {
1507 set_output_deviceID(MODEANDROID);
1508 out->output_device = CC_OUT_USE_ANDROID;
1509 }
1510 set_Hardware_resample(5);
1511 return 0;
1512}
1513
1514int set_output_record_enable(int enable) {
1515 pthread_mutex_lock(&device_change_lock);
1516 if (enable == 0) {
1517 output_record_enable = 0;
1518 ALOGI("%s, set output record disable!\n", __FUNCTION__);
1519 } else if (enable == 1) {
1520 output_record_enable = 1;
1521 ALOGI("%s, set output record enable\n", __FUNCTION__);
1522 } else {
1523 ALOGE("%s, invalid setting!\n", __FUNCTION__);
1524 }
1525 pthread_mutex_unlock(&device_change_lock);
1526 return 0;
1527}
1528
1529static int check_audio_type(struct aml_stream_out *out) {
1530 audioin_type = get_channel_status();
1531 if (audioin_type == MUTE)
1532 return MUTE;
1533 spdif_audio_type = audioin_type;
1534 if (audioin_type > LPCM && omx_started == 0) {
1535 raw_data_counter++;
1536 }
1537 if (audioin_type == LPCM && omx_started == 1) {
1538 pcm_data_counter++;
1539 }
1540 if (raw_data_counter >= 1 && omx_started == 0) {
1541 ALOGI("%s, audio type is changed to RAW data input!,type %d\n", __FUNCTION__,audioin_type);
1542 set_rawdata_in_enable(out);
1543 omx_started = 1;
1544 raw_data_counter = 0;
1545 } else if (pcm_data_counter >= 1 && omx_started == 1) {
1546 ALOGI("%s, audio type is changed to PCM data input!,type %d\n", __FUNCTION__,audioin_type);
1547 set_rawdata_in_disable(out);
1548 omx_started = 0;
1549 pcm_data_counter = 0;
1550 }
1551 /*
1552 if omx ddp decoder has been started, but user configure pcm ->raw output
1553 we need reset decoder to enable decoder to dd/dd+ converter
1554 */
1555 else if (omx_started == 1) {
1556 int digtal_out = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
1557 int need_reset_config = 0;
1558 if ((audioin_type == DTS ||audioin_type == EAC3) && digtal_out != digital_raw_enable) {
1559 ALOGI("DD+ passthrough flag changed from %d to %d\n",digital_raw_enable,digtal_out);
1560 need_reset_config = 1;
1561 }
1562 else if (digtal_out > 0 && digital_raw_enable == 0) {
1563 ALOGI("PCM output changed to RAW pass through\n");
1564 need_reset_config = 1;
1565 }
1566 if (need_reset_config) {
1567 ALOGI("pcm to pass through,decoder to reset \n");
1568 set_rawdata_in_disable(out);
1569 set_rawdata_in_enable(out);
1570 //omx_started = 0;
1571 }
1572 }
1573 return 0;
1574}
1575
1576static int audio_effect_process(short* buffer, int frame_size) {
1577 int output_size = frame_size << 2;
1578 if (gpAmlDevice->has_SRS_lib) {
1579 output_size = srs_process(buffer, buffer, frame_size);
1580 }
1581 if (gpAmlDevice->has_EQ_lib) {
1582 HPEQ_process(buffer, buffer, frame_size);
1583 }
1584 if (gpAmlDevice->has_aml_IIR_lib) {
1585 short *ptr = buffer;
1586 short data;
1587 int i;
1588 for (i = 0; i < frame_size; i++) {
1589 data = (short)aml_IIR_process((int)(*ptr), 0);
1590 *ptr++ = data;
1591 data = (short)aml_IIR_process((int)(*ptr), 1);
1592 *ptr++ = data;
1593 }
1594 }
1595 return output_size;
1596}
1597
1598static int set_delay(struct aml_stream_in *in, int frame_size) {
1599 unsigned char *buffer_ptr = NULL;
1600 int delay_buffer_size = in->delay_time * 192;
1601 int buffer_size = delay_buffer_size + frame_size;
1602
1603 if (in->delay_buf.size < buffer_size) {
1604 in->delay_buf.start_add = (char *)realloc(
1605 in->delay_buf.start_add, buffer_size * sizeof(char));
1606 if (!in->delay_buf.start_add) {
1607 ALOGE("realloc delay buffer failed\n");
1608 return -1;
1609 }
1610 memset(in->delay_buf.start_add, 0, in->delay_buf.size);
1611 in->delay_buf.size = buffer_size;
1612 in->delay_buf.rd = in->delay_buf.start_add;
1613 in->delay_buf.wr = in->delay_buf.start_add + delay_buffer_size;
1614 ALOGI("realloc delay buffer size %d byte\n", buffer_size);
1615 }
1616
1617 if (in->last_delay_time != in->delay_time) {
1618 in->delay_buf.wr = in->delay_buf.rd + delay_buffer_size;
1619 if (in->delay_buf.wr >= (in->delay_buf.start_add + in->delay_buf.size))
1620 in->delay_buf.wr -= in->delay_buf.size;
1621 in->last_delay_time = in->delay_time;
1622 }
1623
1624 write_to_buffer(in->delay_buf.wr, in->temp_buffer, frame_size,
1625 in->delay_buf.start_add, in->delay_buf.size);
1626 in->delay_buf.wr = update_pointer(in->delay_buf.wr, frame_size,
1627 in->delay_buf.start_add, in->delay_buf.size);
1628
1629 read_from_buffer(in->delay_buf.rd, in->temp_buffer, frame_size,
1630 in->delay_buf.start_add, in->delay_buf.size);
1631 in->delay_buf.rd = update_pointer(in->delay_buf.rd, frame_size,
1632 in->delay_buf.start_add, in->delay_buf.size);
1633
1634 return 0;
1635}
1636
1637static void* aml_audio_threadloop(void *data __unused) {
1638 struct aml_stream_in *in = NULL;
1639 struct aml_stream_out *out = NULL;
1640 int output_size = 0;
1641 int i = 0, ret;
1642
1643 if (gpAmlDevice == NULL) {
1644 ALOGE("%s, gpAmlDevice is NULL\n", __FUNCTION__);
1645 return ((void *) 0);
1646 }
1647
1648 in = &gpAmlDevice->in;
1649 out = &gpAmlDevice->out;
1650
1651 gUSBCheckLastFlag = 0;
1652 gUSBCheckFlag = 0;
1653
1654 gpAmlDevice->aml_Audio_ThreadExecFlag = 1;
1655 prctl(PR_SET_NAME, (unsigned long)"aml_TV_audio");
1656 ret = aml_device_init(gpAmlDevice);
1657 if (ret < 0) {
1658 ALOGE("%s, Devices fail opened!\n", __FUNCTION__);
1659 return NULL;
1660 }
1661
1662 while (gpAmlDevice != NULL && gpAmlDevice->aml_Audio_ThreadTurnOnFlag) {
1663 //exit threadloop
1664 if (gpAmlDevice->aml_Audio_ThreadTurnOnFlag == 0) {
1665 ALOGD("%s, aml_Audio_ThreadTurnOnFlag is 0 break now.\n",
1666 __FUNCTION__);
1667 break;
1668 }
1669 if (GetWriteSpace((char *) in->write_buffer, (char *) out->read_buffer,
1670 TEMP_BUFFER_SIZE) > in->max_bytes) {
1671 output_size = alsa_in_read(in, in->temp_buffer,
1672 in->config.period_size * 4);
1673 if (output_size < 0) {
1674 //ALOGE("%s, alsa_in_read fail!\n", __FUNCTION__);
1675 } else {
1676 if (check_audio_type(out) == MUTE)
1677 memset((char *) in->temp_buffer, 0, output_size);
1678 if (in->delay_time != 0 && get_output_deviceID() == 0) {
1679 set_delay(in, output_size);
1680 }
1681 write_to_buffer((char *) in->write_buffer,
1682 (char *) in->temp_buffer, output_size,
1683 (char *) start_temp_buffer, TEMP_BUFFER_SIZE);
1684 in->write_buffer = update_pointer((char *) in->write_buffer,
1685 output_size, (char *) start_temp_buffer,
1686 TEMP_BUFFER_SIZE);
1687 }
1688
1689 }
1690
1691 USB_check(out);
1692
1693 if (GetReadSpace((char *) in->write_buffer, (char *) out->read_buffer,
1694 TEMP_BUFFER_SIZE) > pcm_config_out.period_size << 2) {
1695 read_from_buffer((char *) out->read_buffer,
1696 (char *) out->temp_buffer, pcm_config_out.period_size << 2,
1697 (char *) start_temp_buffer, TEMP_BUFFER_SIZE);
1698
1699 output_size = pcm_config_out.period_size << 2;
1700 if (gpAmlDevice->out.output_device == CC_OUT_USE_ALSA) {
1701 output_size = alsa_out_write(out, out->temp_buffer,
1702 output_size);
1703 } else if (gpAmlDevice->out.output_device == CC_OUT_USE_AMAUDIO) {
1704 output_size = amaudio_out_write(out, out->temp_buffer,
1705 output_size);
1706 if (output_size < 0) {
1707 amaudio_out_close(out);
1708 set_output_deviceID(MODEAMAUDIO);
1709 amaudio_out_open(out);
1710 reset_amaudio(out, 4096);
1711 }
1712 if (output_record_enable == 1) {
1713 buffer_write(&android_out_buffer, out->temp_buffer,
1714 output_size);
1715 }
1716 } else if (gpAmlDevice->out.output_device == CC_OUT_USE_ANDROID) {
1717 output_size = buffer_write(&android_out_buffer,
1718 out->temp_buffer, output_size);
1719 }
1720
1721 if (output_size < 0) {
1722 //ALOGE("%s, out_write fail! bytes = %d \n", __FUNCTION__, output_size);
1723 } else {
1724 out->read_buffer = update_pointer((char *) out->read_buffer,
1725 output_size, (char *) start_temp_buffer,
1726 TEMP_BUFFER_SIZE);
1727 DoDumpData(out->temp_buffer, output_size,
1728 CC_DUMP_SRC_TYPE_OUTPUT);
1729 memset(out->temp_buffer, 0, output_size);
1730 }
1731 }
1732 }
1733
1734 if (gpAmlDevice != NULL) {
1735 gpAmlDevice->aml_Audio_ThreadTurnOnFlag = 0;
1736 ALOGD("%s, set aml_Audio_ThreadTurnOnFlag as 0.\n", __FUNCTION__);
1737 gpAmlDevice->aml_Audio_ThreadExecFlag = 0;
1738 ALOGD("%s, set aml_Audio_ThreadExecFlag as 0.\n", __FUNCTION__);
1739 }
1740
1741 ALOGD("%s, exiting...\n", __FUNCTION__);
1742 return ((void *) 0);
1743}
1744
1745static int clrDevice(struct aml_dev *device) {
1746 memset((void *) device, 0, sizeof(struct aml_dev));
1747
1748 device->in.config.channels = 2;
1749 device->in.config.rate = DEFAULT_IN_SAMPLE_RATE;
1750 device->in.config.period_size = CAPTURE_PERIOD_SIZE;
1751 device->in.config.period_count = CAPTURE_PERIOD_COUNT;
1752 device->in.config.format = PCM_FORMAT_S16_LE;
1753
1754 device->out.config.channels = 2;
1755 device->out.config.rate = DEFAULT_OUT_SAMPLE_RATE;
1756 device->out.config.period_size = PLAYBACK_PERIOD_SIZE;
1757 device->out.config.period_count = PLAYBACK_PERIOD_COUNT;
1758 device->out.config.format = PCM_FORMAT_S16_LE;
1759
1760 return 0;
1761}
1762
1763int aml_audio_open(unsigned int sr, int input_device, int output_device) {
1764 pthread_attr_t attr;
1765 struct sched_param param;
1766 int ret;
1767
1768 ALOGD("%s, sr = %d, input_device = %d, output_device = %d\n",
1769 __FUNCTION__, sr, input_device, output_device);
1770
1771 aml_audio_close();
1772
1773 pthread_mutex_lock(&amaudio_dev_op_mutex);
1774
1775 gpAmlDevice = &gmAmlDevice;
1776 clrDevice(gpAmlDevice);
1777
1778 ret = set_input_stream_sample_rate(sr, &gpAmlDevice->in);
1779 if (ret < 0) {
1780 ALOGE("%s, set_input_stream_sample_rate fail!\n", __FUNCTION__);
1781 clrDevice(gpAmlDevice);
1782 gpAmlDevice = NULL;
1783 pthread_mutex_unlock(&amaudio_dev_op_mutex);
1784 return -1;
1785 }
1786
1787 gpAmlDevice->out.output_device = output_device;
1788 gpAmlDevice->out.user_set_device = output_device;
1789 if (gpAmlDevice->out.user_set_device == CC_OUT_USE_ALSA) {
1790 ALOGD("%s,Use tinyalsa as output device!\n", __FUNCTION__);
1791 } else if (gpAmlDevice->out.user_set_device == CC_OUT_USE_AMAUDIO) {
1792 ALOGD("%s, Use amlogic amaudio as output device!\n", __FUNCTION__);
1793 } else if (gpAmlDevice->out.user_set_device == CC_OUT_USE_ANDROID) {
1794 ALOGD("%s, Use amlogic android as output device!\n", __FUNCTION__);
1795 } else {
1796 ALOGE("%s, Unkown output device, use default amaudio\n", __FUNCTION__);
1797 gpAmlDevice->out.user_set_device = CC_OUT_USE_AMAUDIO;
1798 }
1799
1800 ret = set_input_device(input_device);
1801 if (ret < 0) {
1802 ALOGE("Fail to set input device for HW resample!\n");
1803 }
1804
1805 gpAmlDevice->in.device = get_aml_device(input_device);
1806
1807 pthread_attr_init(&attr);
1808 pthread_attr_setschedpolicy(&attr, SCHED_RR);
1809 param.sched_priority = sched_get_priority_max(SCHED_RR);
1810 /*pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
1811 param.sched_priority = sched_get_priority_max(SCHED_FIFO);
1812 ALOGD("%s, aml_audio thread has %d priority!\n",
1813 __FUNCTION__, param.sched_priority);*/
1814 pthread_attr_setschedparam(&attr, &param);
1815 gpAmlDevice->aml_Audio_ThreadTurnOnFlag = 1;
1816 gpAmlDevice->aml_Audio_ThreadExecFlag = 0;
1817 ret = pthread_create(&gpAmlDevice->aml_Audio_ThreadID, &attr,
1818 &aml_audio_threadloop, NULL);
1819 pthread_attr_destroy(&attr);
1820 if (ret != 0) {
1821 ALOGE("%s, Create thread fail!\n", __FUNCTION__);
1822 aml_device_close(gpAmlDevice);
1823 clrDevice(gpAmlDevice);
1824 gpAmlDevice = NULL;
1825 pthread_mutex_unlock(&amaudio_dev_op_mutex);
1826 return -1;
1827 }
1828
1829 creat_pthread_for_android_check(&gpAmlDevice->android_check_ThreadID);
1830
1831 pthread_mutex_unlock(&amaudio_dev_op_mutex);
1832
1833 ALOGD("%s, exiting...\n", __FUNCTION__);
1834 return 0;
1835}
1836
1837int aml_audio_close(void) {
1838 int i = 0, tmp_timeout_count = 1000;
1839
1840 ALOGD("%s, gpAmlDevice = %p\n", __FUNCTION__, gpAmlDevice);
1841
1842 pthread_mutex_lock(&amaudio_dev_op_mutex);
1843
1844 if (gpAmlDevice != NULL) {
1845 gpAmlDevice->aml_Audio_ThreadTurnOnFlag = 0;
1846 ALOGD("%s, set aml_Audio_ThreadTurnOnFlag as 0.\n", __FUNCTION__);
1847 while (1) {
1848 if (gpAmlDevice->aml_Audio_ThreadExecFlag == 0) {
1849 break;
1850 }
1851 if (i >= tmp_timeout_count) {
1852 break;
1853 }
1854 i++;
1855 usleep(10 * 1000);
1856 }
1857
1858 if (i >= tmp_timeout_count) {
1859 ALOGE("%s, we have try %d times, but the aml audio thread's exec flag is still(%d)!!!\n",
1860 __FUNCTION__, tmp_timeout_count,
1861 gpAmlDevice->aml_Audio_ThreadExecFlag);
1862 } else {
1863 ALOGD("%s, kill aml audio thread success after try %d times.\n",
1864 __FUNCTION__, i);
1865 }
1866
1867 pthread_join(gpAmlDevice->aml_Audio_ThreadID, NULL);
1868 gpAmlDevice->aml_Audio_ThreadID = 0;
1869
1870 exit_pthread_for_android_check(gpAmlDevice->android_check_ThreadID);
1871 gpAmlDevice->android_check_ThreadID = 0;
1872
1873 aml_device_close(gpAmlDevice);
1874 clrDevice(gpAmlDevice);
1875 gpAmlDevice = NULL;
1876
1877 ALOGD("%s, aml audio close success.\n", __FUNCTION__);
1878 }
1879
1880 pthread_mutex_unlock(&amaudio_dev_op_mutex);
1881 return 0;
1882}
1883
1884int check_input_stream_sr(unsigned int sr) {
1885 if (sr >= 8000 && sr <= 48000) {
1886 return 0;
1887 }
1888 return -1;
1889}
1890
1891int set_output_mode(int mode) {
1892 if (gpAmlDevice == NULL) {
1893 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1894 return -1;
1895 }
1896
1897 if (mode < CC_OUT_MODE_DIRECT || mode > CC_OUT_MODE_DIRECT_MIX) {
1898 ALOGE("%s, mode error: mode = %d!\n", __FUNCTION__, mode);
1899 return -1;
1900 }
1901
1902 int OutHandle = gpAmlDevice->out.amAudio_OutHandle;
1903 if (OutHandle < 0) {
1904 ALOGE("%s, amaudio out handle error!\n", __FUNCTION__);
1905 return -1;
1906 }
1907
1908 pthread_mutex_lock(&gpAmlDevice->out.lock);
1909 ioctl(OutHandle, AMAUDIO_IOC_AUDIO_OUT_MODE, mode);
1910 pthread_mutex_unlock(&gpAmlDevice->out.lock);
1911 return 0;
1912}
1913
1914int set_music_gain(int gain) {
1915 if (gpAmlDevice == NULL) {
1916 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1917 return -1;
1918 }
1919
1920 int OutHandle = gpAmlDevice->out.amAudio_OutHandle;
1921 if (OutHandle < 0) {
1922 ALOGE("%s, amaudio out handle error!\n", __FUNCTION__);
1923 return -1;
1924 }
1925
1926 pthread_mutex_lock(&gpAmlDevice->out.lock);
1927 if (gain > 256) {
1928 gain = 256;
1929 }
1930 if (gain < 0) {
1931 gain = 0;
1932 }
1933 ioctl(OutHandle, AMAUDIO_IOC_MUSIC_GAIN, gain);
1934 ALOGD("%s, music gain :%d!\n", __FUNCTION__, gain);
1935 pthread_mutex_unlock(&gpAmlDevice->out.lock);
1936 return 0;
1937}
1938
1939int set_left_gain(int left_gain) {
1940 if (gpAmlDevice == NULL) {
1941 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1942 return -1;
1943 }
1944
1945 int OutHandle = gpAmlDevice->out.amAudio_OutHandle;
1946 if (OutHandle < 0) {
1947 ALOGE("%s, amaudio out handle error!\n", __FUNCTION__);
1948 return -1;
1949 }
1950 pthread_mutex_lock(&gpAmlDevice->out.lock);
1951 if (left_gain > 256) {
1952 left_gain = 256;
1953 }
1954 if (left_gain < 0) {
1955 left_gain = 0;
1956 }
1957 ioctl(OutHandle, AMAUDIO_IOC_MIC_LEFT_GAIN, left_gain);
1958 ALOGD("%s, left mic gain :%d!\n", __FUNCTION__, left_gain);
1959 pthread_mutex_unlock(&gpAmlDevice->out.lock);
1960 return 0;
1961}
1962
1963int set_right_gain(int right_gain) {
1964 if (gpAmlDevice == NULL) {
1965 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1966 return -1;
1967 }
1968 int OutHandle = gpAmlDevice->out.amAudio_OutHandle;
1969 if (OutHandle < 0) {
1970 ALOGE("%s, amaudio out handle error!\n", __FUNCTION__);
1971 return -1;
1972 }
1973 pthread_mutex_lock(&gpAmlDevice->out.lock);
1974 if (right_gain > 256) {
1975 right_gain = 256;
1976 }
1977 if (right_gain < 0) {
1978 right_gain = 0;
1979 }
1980 ioctl(OutHandle, AMAUDIO_IOC_MIC_RIGHT_GAIN, right_gain);
1981 ALOGD("%s, right mic gain :%d!\n", __FUNCTION__, right_gain);
1982 pthread_mutex_unlock(&gpAmlDevice->out.lock);
1983 return 0;
1984}
1985
1986int set_audio_delay(int delay_ms) {
1987 gpAmlDevice->in.delay_time = delay_ms;
1988 ALOGI("Set audio delay time %d ms!\n", delay_ms);
1989 return 0;
1990}
1991
1992int get_audio_delay(void) {
1993 return gpAmlDevice->in.delay_time;
1994}
1995
1996int SetDumpDataFlag(int tmp_flag) {
1997 int tmp_val;
1998 tmp_val = gDumpDataFlag;
1999 gDumpDataFlag = tmp_flag;
2000 return tmp_val;
2001}
2002
2003int GetDumpDataFlag(void) {
2004 int tmp_val = 0;
2005 tmp_val = gDumpDataFlag;
2006 return tmp_val;
2007}
2008
2009static void DoDumpData(void *data_buf, int size, int aud_src_type) {
2010 int tmp_type = 0;
2011 char prop_value[PROPERTY_VALUE_MAX] = { 0 };
2012 char file_path_01[PROPERTY_VALUE_MAX] = { 0 };
2013 char file_path_02[PROPERTY_VALUE_MAX] = { 0 };
2014
2015 if (GetDumpDataFlag() == 0) {
2016 return;
2017 }
2018
2019 memset(prop_value, '\0', PROPERTY_VALUE_MAX);
2020 property_get("audio.dumpdata.en", prop_value, "null");
2021 if (strcasecmp(prop_value, "null") == 0
2022 || strcasecmp(prop_value, "0") == 0) {
2023 if (gDumpDataFd1 >= 0) {
2024 close(gDumpDataFd1);
2025 gDumpDataFd1 = -1;
2026 }
2027 if (gDumpDataFd2 >= 0) {
2028 close(gDumpDataFd2);
2029 gDumpDataFd2 = -1;
2030 }
2031
2032 return;
2033 }
2034
2035 tmp_type = CC_DUMP_SRC_TYPE_INPUT;
2036 property_get("audio.dumpdata.src", prop_value, "null");
2037 if (strcasecmp(prop_value, "null") == 0
2038 || strcasecmp(prop_value, "input") == 0) {
2039 tmp_type = CC_DUMP_SRC_TYPE_INPUT;
2040 } else if (strcasecmp(prop_value, "output") == 0) {
2041 tmp_type = CC_DUMP_SRC_TYPE_OUTPUT;
2042 } else if (strcasecmp(prop_value, "input,output") == 0) {
2043 tmp_type = CC_DUMP_SRC_TYPE_IN_OUT;
2044 } else if (strcasecmp(prop_value, "output,input") == 0) {
2045 tmp_type = CC_DUMP_SRC_TYPE_OUT_IN;
2046 }
2047
2048 if (tmp_type == CC_DUMP_SRC_TYPE_INPUT
2049 || tmp_type == CC_DUMP_SRC_TYPE_OUTPUT) {
2050 if (tmp_type != aud_src_type) {
2051 return;
2052 }
2053 }
2054
2055 memset(file_path_01, '\0', PROPERTY_VALUE_MAX);
2056 property_get("audio.dumpdata.path", file_path_01, "null");
2057 if (strcasecmp(file_path_01, "null") == 0) {
2058 file_path_01[0] = '\0';
2059 }
2060
2061 if (tmp_type == CC_DUMP_SRC_TYPE_IN_OUT
2062 || tmp_type == CC_DUMP_SRC_TYPE_OUT_IN) {
2063 memset(file_path_02, '\0', PROPERTY_VALUE_MAX);
2064 property_get("audio.dumpdata.path2", file_path_02, "null");
2065 if (strcasecmp(file_path_02, "null") == 0) {
2066 file_path_02[0] = '\0';
2067 }
2068 }
2069
2070 if (gDumpDataFd1 < 0 && file_path_01[0] != '\0') {
2071 if (access(file_path_01, 0) == 0) {
2072 gDumpDataFd1 = open(file_path_01, O_RDWR | O_SYNC);
2073 if (gDumpDataFd1 < 0) {
2074 ALOGE("%s, Open device file \"%s\" error: %s.\n", __FUNCTION__,
2075 file_path_01, strerror(errno));
2076 }
2077 } else {
2078 gDumpDataFd1 = open(file_path_01, O_WRONLY | O_CREAT | O_EXCL,
2079 S_IRUSR | S_IWUSR);
2080 if (gDumpDataFd1 < 0) {
2081 ALOGE("%s, Create device file \"%s\" error: %s.\n",
2082 __FUNCTION__, file_path_01, strerror(errno));
2083 }
2084 }
2085 }
2086
2087 if (gDumpDataFd2 < 0 && file_path_02[0] != '\0'
2088 && (tmp_type == CC_DUMP_SRC_TYPE_IN_OUT
2089 || tmp_type == CC_DUMP_SRC_TYPE_OUT_IN)) {
2090 if (access(file_path_02, 0) == 0) {
2091 gDumpDataFd2 = open(file_path_02, O_RDWR | O_SYNC);
2092 if (gDumpDataFd2 < 0) {
2093 ALOGE("%s, Open device file \"%s\" error: %s.\n", __FUNCTION__,
2094 file_path_02, strerror(errno));
2095 }
2096 } else {
2097 gDumpDataFd2 = open(file_path_02, O_WRONLY | O_CREAT | O_EXCL,
2098 S_IRUSR | S_IWUSR);
2099 if (gDumpDataFd2 < 0) {
2100 ALOGE("%s, Create device file \"%s\" error: %s.\n",
2101 __FUNCTION__, file_path_02, strerror(errno));
2102 }
2103 }
2104 }
2105
2106 if (tmp_type == CC_DUMP_SRC_TYPE_IN_OUT) {
2107 if (aud_src_type == CC_DUMP_SRC_TYPE_INPUT && gDumpDataFd1 >= 0) {
2108 write(gDumpDataFd1, data_buf, size);
2109 } else if (aud_src_type == CC_DUMP_SRC_TYPE_OUTPUT
2110 && gDumpDataFd2 >= 0) {
2111 write(gDumpDataFd2, data_buf, size);
2112 }
2113 } else if (tmp_type == CC_DUMP_SRC_TYPE_OUT_IN) {
2114 if (aud_src_type == CC_DUMP_SRC_TYPE_OUTPUT && gDumpDataFd1 >= 0) {
2115 write(gDumpDataFd1, data_buf, size);
2116 } else if (aud_src_type == CC_DUMP_SRC_TYPE_INPUT
2117 && gDumpDataFd2 >= 0) {
2118 write(gDumpDataFd2, data_buf, size);
2119 }
2120 } else {
2121 if (gDumpDataFd1 >= 0) {
2122 write(gDumpDataFd1, data_buf, size);
2123 }
2124 }
2125}
2126
2127int aml_audio_set_pregain(float gain)
2128{
2129 ALOGD("%s, pre-gain = %f dB\n", __FUNCTION__, gain);
2130
2131 pthread_mutex_lock(&amaudio_dev_op_mutex);
2132
2133 if (gpAmlDevice != NULL) {
2134 gpAmlDevice->in.pre_gain = powf(10, gain/20);
2135 }
2136
2137 pthread_mutex_unlock(&amaudio_dev_op_mutex);
2138
2139 return 0;
2140}
2141
2142int aml_audio_get_pregain(float *gain)
2143{
2144 if (gpAmlDevice != NULL) {
2145 *gain = 20*log10f(gpAmlDevice->in.pre_gain);
2146 return 0;
2147 }
2148
2149 ALOGE("%s, no active gpAmlDevice!\n", __FUNCTION__);
2150 return -1;
2151}
2152
2153int aml_audio_set_pre_mute(uint mute)
2154{
2155 ALOGD("%s, mute = %d\n", __FUNCTION__, mute);
2156
2157 pthread_mutex_lock(&amaudio_dev_op_mutex);
2158
2159 if (gpAmlDevice != NULL) {
2160 gpAmlDevice->in.pre_mute = mute;
2161 }
2162
2163 pthread_mutex_unlock(&amaudio_dev_op_mutex);
2164
2165 return 0;
2166}
2167
2168int aml_audio_get_pre_mute(uint *mute)
2169{
2170 if (gpAmlDevice != NULL) {
2171 *mute = gpAmlDevice->in.pre_mute;
2172 return 0;
2173 }
2174
2175 ALOGE("%s, no active gpAmlDevice!\n", __FUNCTION__);
2176 return -1;
2177}
2178