summaryrefslogtreecommitdiff
path: root/libTVaudio/audio/aml_audio.c (plain)
blob: 473663dee4c732c2e62d7e4e0c0fdae19a9122af
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 i = 0, ret = 0, times = 0;
927 int dly_tm = 10000, dly_cnt = 200, retry_times = 5; //2s * 5times
928
929 pthread_mutex_lock(&out->lock);
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 set_amaudio2_enable(1);
936
937renew_audiotrack:
938 ret = new_android_audiotrack();
939 if (ret < 0) {
940 ALOGE("%s, New an audio track is fail!\n", __FUNCTION__);
941 pthread_mutex_unlock(&out->lock);
942 return -1;
943 }
944
945 /* amaudio needs alsa running first to get the right params, so wait to make sure track is on */
946 if (out->user_set_device == CC_OUT_USE_AMAUDIO) {
947 while (I2S_state < 5 && gpAmlDevice->aml_Audio_ThreadTurnOnFlag == 1) {
948 usleep(dly_tm);
949 i++;
950 if (i >= dly_cnt) {
951 release_android_audiotrack();
952 if (times < retry_times) {
953 i = 0;
954 times++;
955 goto renew_audiotrack;
956 }
957 pthread_mutex_unlock(&out->lock);
958 ALOGE("%s, Time out error: wait %d ms for waiting I2S ready. I2S_state = %d\n",
959 __FUNCTION__, i * dly_tm * retry_times/1000, I2S_state);
960 return -1;
961 }
962 }
963 ALOGD("%s, sucess: wait %d ms for waiting I2S ready. retry_times = %d\n",
964 __FUNCTION__, i * dly_tm / 1000, times);
965 }
966 pthread_mutex_unlock(&out->lock);
967 return 0;
968}
969
970static int release_audiotrack(struct aml_stream_out *out) {
971 ALOGD("%s, Release audio track!\n", __FUNCTION__);
972 pthread_mutex_lock(&out->lock);
973 int ret = release_android_audiotrack();
974 if (ret < 0) {
975 ALOGE("%s, Delete audio track is fail!\n", __FUNCTION__);
976 }
977 set_amaudio2_enable(0);
978 pthread_mutex_unlock(&out->lock);
979 return 0;
980}
981
982static int amaudio_out_open(struct aml_stream_out *out) {
983 out->config.period_size = pcm_config_out.period_size;
984 out->config.rate = pcm_config_out.rate;
985 out->config.period_count = pcm_config_out.period_count;
986 out->standby = 1;
987 if (getprop_bool("ro.platform.has.tvuimode")) {
988 out->config.channels = 8;
989 out->config.format = PCM_FORMAT_S32_LE;
990 out->tmp_buffer_8ch = malloc(out->config.period_size * 4 * 8); /*8 channel, 32bit*/
991 if (out->tmp_buffer_8ch == NULL) {
992 ALOGE("cannot malloc memory for out->tmp_buffer_8ch");
993 return -ENOMEM;
994 }
995 out->audioeffect_tmp_buffer = malloc(out->config.period_size * 6);
996 if (out->audioeffect_tmp_buffer == NULL) {
997 ALOGE("cannot malloc memory for audioeffect_tmp_buffer");
998 return -ENOMEM;
999 }
1000 out->is_tv_platform = 1;
1001 }else {
1002 out->config.channels = pcm_config_out.channels;
1003 out->config.format = pcm_config_out.format;
1004 out->is_tv_platform = 0;
1005 }
1006
1007 pthread_mutex_lock(&out->lock);
1008 out->amAudio_OutHandle = -1;
1009 out->amAudio_OutHandle = open(AMAUDIO_OUT, O_RDWR);
1010 if (out->amAudio_OutHandle < 0) {
1011 close(out->amAudio_OutHandle);
1012 out->amAudio_OutHandle = -1;
1013 release_android_audiotrack();
1014 pthread_mutex_unlock(&out->lock);
1015 ALOGE("%s, The device amaudio_out cant't be opened!\n", __FUNCTION__);
1016 return -1;
1017 }
1018
1019 struct buffer_status *buf = &out->playback_buf;
1020 buf->size = ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_GET_SIZE);
1021 buf->start_add = (unsigned char*) mmap(NULL, buf->size, PROT_READ | PROT_WRITE,
1022 MAP_FILE | MAP_SHARED, out->amAudio_OutHandle, 0);
1023 if (buf->start_add == 0) {
1024 close(out->amAudio_OutHandle);
1025 out->amAudio_OutHandle = -1;
1026 release_android_audiotrack();
1027 pthread_mutex_unlock(&out->lock);
1028 ALOGE("%s, Error create mmap!\n", __FUNCTION__);
1029 return -1;
1030 }
1031
1032 out->standby = 0;
1033 pthread_mutex_unlock(&out->lock);
1034 ALOGD("%s, Amaudio device is opened!\n", __FUNCTION__);
1035 return 0;
1036}
1037
1038static int amaudio_out_close(struct aml_stream_out *out) {
1039 ALOGD("%s, Do amaudio device close!\n", __FUNCTION__);
1040 pthread_mutex_lock(&out->lock);
1041 if (out->is_tv_platform == 1) {
1042 free(out->tmp_buffer_8ch);
1043 free(out->audioeffect_tmp_buffer);
1044 }
1045 if (out->amAudio_OutHandle > 0) {
1046 close(out->amAudio_OutHandle);
1047 out->amAudio_OutHandle = -1;
1048 munmap(out->playback_buf.start_add, out->playback_buf.size);
1049 }
1050 pthread_mutex_unlock(&out->lock);
1051 return 0;
1052}
1053
1054static int amaudio_out_write(struct aml_stream_out *out, void* buffer,
1055 size_t bytes) {
1056 struct buffer_status *buf = &out->playback_buf;
1057 int input_frames = bytes >> 2;
1058 unsigned char *out_buffer = NULL;
1059
1060 pthread_mutex_lock(&out->lock);
1061
1062 if (out->is_tv_platform == 1) {
1063 int16_t *tmp_buffer = (int16_t *)out->audioeffect_tmp_buffer;
1064 int16_t *in_buffer = (int16_t *)buffer;
1065 size_t out_byte = input_frames * 32;
1066 int i = 0;
1067
1068 memcpy((void *)tmp_buffer, buffer, bytes);
1069 audio_effect_process(tmp_buffer, input_frames);
1070 for (i = 0; i < input_frames; i ++) {
1071 out->tmp_buffer_8ch[8*i] = ((int32_t)(in_buffer[2*i])) << 16;
1072 out->tmp_buffer_8ch[8*i + 1] = ((int32_t)(in_buffer[2*i + 1])) << 16;
1073 out->tmp_buffer_8ch[8*i + 2] = ((int32_t)(tmp_buffer[2*i])) << 16;
1074 out->tmp_buffer_8ch[8*i + 3] = ((int32_t)(tmp_buffer[2*i + 1])) << 16;
1075 out->tmp_buffer_8ch[8*i + 4] = 0;
1076 out->tmp_buffer_8ch[8*i + 5] = 0;
1077 out->tmp_buffer_8ch[8*i + 6] = 0;
1078 out->tmp_buffer_8ch[8*i + 7] = 0;
1079 }
1080
1081 //get rd ptr, and calculate write space
1082 buf->rd = ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_GET_PTR);
1083 buf->level = buf->size - ((buf->size + buf->wr - buf->rd) % buf->size);
1084
1085 if (buf->level <= out_byte) {
1086 ALOGD("Reset amaudio: buf->level=%x,buf->rd = %x,buf->wr=%x\n",
1087 buf->level, buf->rd, buf->wr);
1088 pthread_mutex_unlock(&out->lock);
1089 return -1;
1090 }
1091 out_buffer = buf->start_add + buf->wr;
1092 memcpy((void *)out_buffer, (void *)out->tmp_buffer_8ch, out_byte);
1093
1094 // update the write pointer and write space
1095 buf->wr = (buf->wr + out_byte) % buf->size;
1096 buf->level = buf->size - ((buf->size + buf->wr - buf->rd) % buf->size);
1097 ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_UPDATE_APP_PTR, buf->wr);
1098
1099 } else {
1100 audio_effect_process((short *)buffer, input_frames);
1101
1102 //get rd ptr, and calculate write space
1103 buf->rd = ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_GET_PTR);
1104 buf->level = buf->size - ((buf->size + buf->wr - buf->rd) % buf->size);
1105
1106 if (buf->level <= bytes) {
1107 ALOGD("Reset amaudio: buf->level=%x,buf->rd = %x,buf->wr=%x\n",
1108 buf->level, buf->rd, buf->wr);
1109 pthread_mutex_unlock(&out->lock);
1110 return -1;
1111 }
1112 out_buffer = buf->start_add + buf->wr;
1113 memcpy((void *)out_buffer, buffer, bytes);
1114
1115 // update the write pointer and write space
1116 buf->wr = (buf->wr + bytes) % buf->size;
1117 buf->level = buf->size - ((buf->size + buf->wr - buf->rd) % buf->size);
1118 ioctl(out->amAudio_OutHandle, AMAUDIO_IOC_UPDATE_APP_PTR, buf->wr);
1119 }
1120
1121 pthread_mutex_unlock(&out->lock);
1122 return bytes;
1123}
1124
1125static int malloc_buffer(struct aml_dev *device) {
1126 void *buffer = NULL;
1127 struct aml_stream_in *in = &device->in;
1128 struct aml_stream_out *out = &device->out;
1129
1130 buffer = malloc(TEMP_BUFFER_SIZE);
1131 if (buffer == NULL) {
1132 ALOGD("%s, Malloc temp buffer failed!\n", __FUNCTION__);
1133 return -1;
1134 }
1135 start_temp_buffer = buffer;
1136 in->write_buffer = buffer;
1137 out->read_buffer = buffer;
1138
1139 in->temp_buffer = malloc(in->max_bytes);
1140 if (in->temp_buffer == NULL) {
1141 ALOGD("%s, Malloc input temp buffer failed!\n", __FUNCTION__);
1142 return -1;
1143 }
1144
1145 out->temp_buffer = malloc(pcm_config_out.period_size << 2);
1146 if (out->temp_buffer == NULL) {
1147 ALOGD("%s, Malloc output temp buffer failed!\n", __FUNCTION__);
1148 return -1;
1149 }
1150
1151 return 0;
1152}
1153
1154static int release_buffer(struct aml_dev *device) {
1155 struct aml_stream_in *in = &device->in;
1156 struct aml_stream_out *out = &device->out;
1157
1158 if (start_temp_buffer != NULL) {
1159 free(start_temp_buffer);
1160 start_temp_buffer = NULL;
1161 in->write_buffer = NULL;
1162 out->read_buffer = NULL;
1163 }
1164 if (in->temp_buffer != NULL) {
1165 free(in->temp_buffer);
1166 in->temp_buffer = NULL;
1167 }
1168 if (out->temp_buffer != NULL) {
1169 free(out->temp_buffer);
1170 out->temp_buffer = NULL;
1171 }
1172 return 0;
1173}
1174
1175static int audio_effect_release() {
1176 unload_EQ_lib();
1177 unload_SRS_lib();
1178 unload_aml_IIR_lib();
1179 return 0;
1180}
1181
1182static int set_output_deviceID(int deviceID) {
1183 int ret;
1184
1185 if (gpAmlDevice == NULL) {
1186 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1187 return -1;
1188 }
1189
1190 gpAmlDevice->output_mode = deviceID;
1191 ALOGE("%s, set output device ID: %d!\n", __FUNCTION__, deviceID);
1192 return 0;
1193}
1194
1195static int get_output_deviceID(void) {
1196 if (gpAmlDevice == NULL) {
1197 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1198 return -1;
1199 }
1200 return gpAmlDevice->output_mode;
1201}
1202
1203static int aml_device_init(struct aml_dev *device) {
1204 int ret;
1205
1206 ALOGD("%s, start to open Devices!\n", __FUNCTION__);
1207
1208 //Malloc temp buffer for audiotrak out
1209 ret = tmp_buffer_init(&android_out_buffer, ANDROID_OUT_BUFFER_SIZE);
1210 if (ret < 0) {
1211 ALOGE("%s, malloc temp buffer error!\n", __FUNCTION__);
1212 goto error1;
1213 }
1214
1215 ret = tmp_buffer_init(&DDP_out_buffer, DDP_OUT_BUFFER_SIZE);
1216 if (ret < 0) {
1217 ALOGE("%s, malloc ddp buffer failed!\n", __FUNCTION__);
1218 goto error2;
1219 }
1220 // add a temp buffer to store dd 61937 audio frame
1221 ret = tmp_buffer_init(&DD_out_buffer, DD_61937_BUFFER_SIZE);
1222 if (ret < 0) {
1223 ALOGE("%s, malloc dd 61937 buffer failed!\n", __FUNCTION__);
1224 goto error3;
1225 }
1226 //open input device of tinyalsa
1227 ret = alsa_in_open(&device->in);
1228 if (ret < 0) {
1229 ALOGE("%s, open alsa in device open error!\n", __FUNCTION__);
1230 goto error3;
1231 }
1232
1233 //Malloc temp buffer for input and output
1234 ret = malloc_buffer(device);
1235 if (ret < 0) {
1236 ALOGE("%s, malloc buffer error!\n", __FUNCTION__);
1237 goto error4;
1238 }
1239
1240 if (device->out.user_set_device == CC_OUT_USE_ALSA) {
1241 set_output_deviceID(MODEAMAUDIO);
1242 //open output device of tinyalsa
1243 ret = alsa_out_open(&device->out);
1244 if (ret < 0) {
1245 ALOGE("%s, open alsa out device open error!\n", __FUNCTION__);
1246 goto error5;
1247 }
1248 } else if (device->out.user_set_device == CC_OUT_USE_AMAUDIO) {
1249 set_output_deviceID(MODEAMAUDIO);
1250 //open output device of amaudio
1251 ret = new_audiotrack(&device->out);
1252 if (ret < 0) {
1253 ALOGE("%s, new audiotrack error!\n", __FUNCTION__);
1254 goto error5;
1255 }
1256 ret = amaudio_out_open(&device->out);
1257 if (ret < 0) {
1258 release_audiotrack(&device->out);
1259 ALOGE("%s, open amaudio out device error!\n", __FUNCTION__);
1260 goto error5;
1261 }
1262 } else if (device->out.user_set_device == CC_OUT_USE_ANDROID) {
1263 set_output_deviceID(MODEANDROID);
1264 ret = new_audiotrack(&device->out);
1265 if (ret < 0) {
1266 ALOGE("%s, open android out device error!\n", __FUNCTION__);
1267 goto error5;
1268 }
1269 }
1270
1271 //EQ lib load and init EQ
1272 ret = load_EQ_lib();
1273 if (ret < 0) {
1274 ALOGE("%s, Load EQ lib fail!\n", __FUNCTION__);
1275 device->has_EQ_lib = 0;
1276 } else {
1277 ret = HPEQ_init();
1278 if (ret < 0) {
1279 device->has_EQ_lib = 0;
1280 } else {
1281 device->has_EQ_lib = 1;
1282 }
1283 HPEQ_enable(1);
1284 }
1285
1286 //load srs lib and init it. SRS is behand resampling, so sample rate is as default sr.
1287 ret = load_SRS_lib();
1288 if (ret < 0) {
1289 ALOGE("%s, Load SRS lib fail!\n", __FUNCTION__);
1290 device->has_SRS_lib = 0;
1291 } else {
1292 ret = srs_init(device->out.config.rate);
1293 if (ret < 0) {
1294 device->has_SRS_lib = 0;
1295 } else {
1296 device->has_SRS_lib = 1;
1297 }
1298 }
1299
1300 //load aml_IIR lib
1301 ret = load_aml_IIR_lib();
1302 if (ret < 0) {
1303 ALOGE("%s, Load aml_IIR lib fail!\n", __FUNCTION__);
1304 device->has_aml_IIR_lib = 0;
1305 } else {
1306 char value[PROPERTY_VALUE_MAX];
1307 int paramter = 0;
1308 if (property_get("media.audio.LFP.paramter", value, NULL) > 0) {
1309 paramter = atoi(value);
1310 }
1311 aml_IIR_init(paramter);
1312 device->has_aml_IIR_lib = 1;
1313 }
1314
1315 audio_IIR_init();
1316
1317 ALOGD("%s, exiting...\n", __FUNCTION__);
1318 return 0;
1319
1320 error5: release_buffer(device);
1321 error4: alsa_in_close(&device->in);
1322 error3: tmp_buffer_release (&DDP_out_buffer);
1323 tmp_buffer_release (&DD_out_buffer);
1324 error2: tmp_buffer_release (&android_out_buffer);
1325 error1: return ret;
1326
1327}
1328
1329static int aml_device_close(struct aml_dev *device) {
1330 struct aml_stream_in *in = &device->in;
1331 struct aml_stream_out *out = &device->out;
1332
1333 alsa_in_close(in);
1334
1335 if (in->delay_buf.size != 0) {
1336 free(in->delay_buf.start_add);
1337 }
1338
1339 if (out->output_device == CC_OUT_USE_ALSA) {
1340 alsa_out_close(out);
1341 } else if (out->output_device == CC_OUT_USE_AMAUDIO) {
1342 amaudio_out_close(out);
1343 release_audiotrack(out);
1344 } else if (out->output_device == CC_OUT_USE_ANDROID) {
1345 release_audiotrack(out);
1346 }
1347
1348 omx_codec_close();
1349 omx_codec_dts_close();
1350 omx_started = 0;
1351 tmp_buffer_release (&DDP_out_buffer);
1352 tmp_buffer_release (&DD_out_buffer);
1353 tmp_buffer_release (&android_out_buffer);
1354 release_buffer(device);
1355 audio_effect_release();
1356 return 0;
1357}
1358
1359static void USB_check(struct aml_stream_out *out) {
1360
1361 gUSBCheckFlag = GetUsbAudioCheckFlag();
1362 if (gUSBCheckLastFlag == gUSBCheckFlag) {
1363 return;
1364 }
1365
1366 ALOGI("Audio Device is changed from %x to %x!\n", gUSBCheckLastFlag, gUSBCheckFlag);
1367
1368 //if audio record from submix, don't change device
1369 if ((gUSBCheckFlag & AUDIO_DEVICE_OUT_REMOTE_SUBMIX) != 0) {
1370 gUSBCheckLastFlag = gUSBCheckFlag;
1371 set_output_record_enable(1);
1372 return;
1373 } else if((gUSBCheckLastFlag & AUDIO_DEVICE_OUT_REMOTE_SUBMIX) != 0) {
1374 gUSBCheckLastFlag = gUSBCheckFlag;
1375 set_output_record_enable(0);
1376 return;
1377 }
1378
1379 if ((gUSBCheckFlag & AUDIO_DEVICE_OUT_SPEAKER) == 0) {
1380 if (out->output_device == CC_OUT_USE_AMAUDIO && omx_started == 0) {
1381 amaudio_out_close(out);
1382 set_output_deviceID(MODEANDROID);
1383 out->output_device = CC_OUT_USE_ANDROID;
1384 } else if (out->output_device == CC_OUT_USE_ALSA && omx_started == 0) {
1385 alsa_out_close(out);
1386 new_audiotrack(out);
1387 set_output_deviceID(MODEANDROID);
1388 out->output_device = CC_OUT_USE_ANDROID;
1389 }
1390 ALOGI("%s, USB audio playback device is in.\n", __FUNCTION__);
1391 } else if ((gUSBCheckFlag & AUDIO_DEVICE_OUT_SPEAKER) != 0 && gUSBCheckLastFlag != 0) {
1392 if (out->user_set_device == CC_OUT_USE_AMAUDIO && omx_started == 0) {
1393 amaudio_out_open(out);
1394 set_output_deviceID(MODEAMAUDIO);
1395 out->output_device = CC_OUT_USE_AMAUDIO;
1396 } else if (out->user_set_device == CC_OUT_USE_ALSA
1397 && omx_started == 0) {
1398 release_audiotrack(out);
1399 alsa_out_open(out);
1400 set_output_deviceID(MODEAMAUDIO);
1401 out->output_device = CC_OUT_USE_ALSA;
1402 }
1403 ALOGI("%s, USB audio playback device is out.\n", __FUNCTION__);
1404 }
1405 gUSBCheckLastFlag = gUSBCheckFlag;
1406 return;
1407}
1408
1409static int get_channel_status(void) {
1410 struct mixer *pmixer;
1411 struct mixer_ctl *pctl;
1412 int card_id;
1413 int type_I2S = -1;
1414 int type_SPDIF = -1;
1415
1416 card_id = get_aml_card();
1417 pmixer = mixer_open(card_id);
1418 if (NULL == pmixer) {
1419 ALOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__);
1420 goto err_exit;
1421 }
1422 pctl = mixer_get_ctl_by_name(pmixer, Audio_In_Source_TYPE);
1423 if (NULL != pctl) {
1424 type_AUDIO_IN = mixer_ctl_get_value(pctl, 0);
1425 if (type_AUDIO_IN != 2) {
1426 mixer_close(pmixer);
1427 return LPCM;
1428 }
1429 }
1430
1431 pctl = mixer_get_ctl_by_name(pmixer, SPDIF_IN_AUDIO_TYPE);
1432 if (NULL != pctl) {
1433 type_SPDIF = mixer_ctl_get_value(pctl, 0);
1434 }
1435
1436 pctl = mixer_get_ctl_by_name(pmixer, I2S_IN_AUDIO_TYPE);
1437 if (NULL != pctl) {
1438 type_I2S = mixer_ctl_get_value(pctl, 0);
1439 }
1440
1441 if (type_SPDIF == LPCM && type_I2S == AC3) {
1442 mixer_close(pmixer);
1443 return MUTE;
1444 }
1445
1446 mixer_close(pmixer);
1447 return type_SPDIF;
1448
1449err_exit:
1450 if (NULL != pmixer) {
1451 mixer_close(pmixer);
1452 }
1453 return -1;
1454}
1455
1456static int set_Hardware_resample(int enable) {
1457 struct mixer *pmixer;
1458 struct mixer_ctl *pctl;
1459 int card_id;
1460 card_id = get_aml_card();
1461 pmixer = mixer_open(card_id);
1462 if (NULL == pmixer) {
1463 ALOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__);
1464 goto err_exit;
1465 }
1466 pctl = mixer_get_ctl_by_name(pmixer, HW_RESAMPLE_ENABLE);
1467 if (NULL != pctl) {
1468 mixer_ctl_set_value(pctl, 0, enable);
1469 }
1470err_exit:
1471 if (NULL != pmixer) {
1472 mixer_close(pmixer);
1473 }
1474 return -1;
1475 }
1476
1477 static int set_rawdata_in_enable(struct aml_stream_out *out) {
1478 if (out->output_device == CC_OUT_USE_AMAUDIO) {
1479 amaudio_out_close(out);
1480 } else if (out->output_device == CC_OUT_USE_ALSA) {
1481 alsa_out_close(out);
1482 new_audiotrack(out);
1483 }
1484 set_output_deviceID(MODERAW);
1485 out->output_device = CC_OUT_USE_ANDROID;
1486 set_Hardware_resample(4);
1487 digital_raw_enable = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
1488 if (audioin_type == AC3 || audioin_type == EAC3)
1489 omx_codec_init();
1490 if (audioin_type == DTS || audioin_type == DTSHD)
1491 omx_codec_dts_init();
1492 return 0;
1493}
1494
1495static int set_rawdata_in_disable(struct aml_stream_out *out) {
1496
1497 omx_codec_close();
1498 omx_codec_dts_close();
1499 if ((gUSBCheckFlag & AUDIO_DEVICE_OUT_SPEAKER) != 0) {
1500 if (out->user_set_device == CC_OUT_USE_AMAUDIO) {
1501 set_output_deviceID(MODEAMAUDIO);
1502 amaudio_out_open(out);
1503 out->output_device = CC_OUT_USE_AMAUDIO;
1504 } else if (out->user_set_device == CC_OUT_USE_ANDROID) {
1505 set_output_deviceID(MODEANDROID);
1506 out->output_device = CC_OUT_USE_ANDROID;
1507 } else if (out->user_set_device == CC_OUT_USE_ALSA) {
1508 release_audiotrack(out);
1509 alsa_out_open(out);
1510 set_output_deviceID(MODEAMAUDIO);
1511 out->output_device = CC_OUT_USE_ALSA;
1512 }
1513 } else {
1514 set_output_deviceID(MODEANDROID);
1515 out->output_device = CC_OUT_USE_ANDROID;
1516 }
1517 set_Hardware_resample(5);
1518 return 0;
1519}
1520
1521int set_output_record_enable(int enable) {
1522 pthread_mutex_lock(&device_change_lock);
1523 if (enable == 0) {
1524 output_record_enable = 0;
1525 ALOGI("%s, set output record disable!\n", __FUNCTION__);
1526 } else if (enable == 1) {
1527 output_record_enable = 1;
1528 ALOGI("%s, set output record enable\n", __FUNCTION__);
1529 } else {
1530 ALOGE("%s, invalid setting!\n", __FUNCTION__);
1531 }
1532 pthread_mutex_unlock(&device_change_lock);
1533 return 0;
1534}
1535
1536static int check_audio_type(struct aml_stream_out *out) {
1537 audioin_type = get_channel_status();
1538 if (audioin_type == MUTE)
1539 return MUTE;
1540 spdif_audio_type = audioin_type;
1541 if (audioin_type > LPCM && omx_started == 0) {
1542 raw_data_counter++;
1543 }
1544 if (audioin_type == LPCM && omx_started == 1) {
1545 pcm_data_counter++;
1546 }
1547 if (raw_data_counter >= 1 && omx_started == 0) {
1548 ALOGI("%s, audio type is changed to RAW data input!,type %d\n", __FUNCTION__,audioin_type);
1549 set_rawdata_in_enable(out);
1550 omx_started = 1;
1551 raw_data_counter = 0;
1552 } else if (pcm_data_counter >= 1 && omx_started == 1) {
1553 ALOGI("%s, audio type is changed to PCM data input!,type %d\n", __FUNCTION__,audioin_type);
1554 set_rawdata_in_disable(out);
1555 omx_started = 0;
1556 pcm_data_counter = 0;
1557 }
1558 /*
1559 if omx ddp decoder has been started, but user configure pcm ->raw output
1560 we need reset decoder to enable decoder to dd/dd+ converter
1561 */
1562 else if (omx_started == 1) {
1563 int digtal_out = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
1564 int need_reset_config = 0;
1565 if ((audioin_type == DTS ||audioin_type == EAC3) && digtal_out != digital_raw_enable) {
1566 ALOGI("DD+ passthrough flag changed from %d to %d\n",digital_raw_enable,digtal_out);
1567 need_reset_config = 1;
1568 }
1569 else if (digtal_out > 0 && digital_raw_enable == 0) {
1570 ALOGI("PCM output changed to RAW pass through\n");
1571 need_reset_config = 1;
1572 }
1573 if (need_reset_config) {
1574 ALOGI("pcm to pass through,decoder to reset \n");
1575 set_rawdata_in_disable(out);
1576 set_rawdata_in_enable(out);
1577 //omx_started = 0;
1578 }
1579 }
1580 return 0;
1581}
1582
1583static int audio_effect_process(short* buffer, int frame_size) {
1584 int output_size = frame_size << 2;
1585 if (gpAmlDevice->has_SRS_lib) {
1586 output_size = srs_process(buffer, buffer, frame_size);
1587 }
1588 if (gpAmlDevice->has_EQ_lib) {
1589 HPEQ_process(buffer, buffer, frame_size);
1590 }
1591 if (gpAmlDevice->has_aml_IIR_lib) {
1592 short *ptr = buffer;
1593 short data;
1594 int i;
1595 for (i = 0; i < frame_size; i++) {
1596 data = (short)aml_IIR_process((int)(*ptr), 0);
1597 *ptr++ = data;
1598 data = (short)aml_IIR_process((int)(*ptr), 1);
1599 *ptr++ = data;
1600 }
1601 }
1602 return output_size;
1603}
1604
1605static int set_delay(struct aml_stream_in *in, int frame_size) {
1606 unsigned char *buffer_ptr = NULL;
1607 int delay_buffer_size = in->delay_time * 192;
1608 int buffer_size = delay_buffer_size + frame_size;
1609
1610 if (in->delay_buf.size < buffer_size) {
1611 in->delay_buf.start_add = (char *)realloc(
1612 in->delay_buf.start_add, buffer_size * sizeof(char));
1613 if (!in->delay_buf.start_add) {
1614 ALOGE("realloc delay buffer failed\n");
1615 return -1;
1616 }
1617 memset(in->delay_buf.start_add, 0, in->delay_buf.size);
1618 in->delay_buf.size = buffer_size;
1619 in->delay_buf.rd = in->delay_buf.start_add;
1620 in->delay_buf.wr = in->delay_buf.start_add + delay_buffer_size;
1621 ALOGI("realloc delay buffer size %d byte\n", buffer_size);
1622 }
1623
1624 if (in->last_delay_time != in->delay_time) {
1625 in->delay_buf.wr = in->delay_buf.rd + delay_buffer_size;
1626 if (in->delay_buf.wr >= (in->delay_buf.start_add + in->delay_buf.size))
1627 in->delay_buf.wr -= in->delay_buf.size;
1628 in->last_delay_time = in->delay_time;
1629 }
1630
1631 write_to_buffer(in->delay_buf.wr, in->temp_buffer, frame_size,
1632 in->delay_buf.start_add, in->delay_buf.size);
1633 in->delay_buf.wr = update_pointer(in->delay_buf.wr, frame_size,
1634 in->delay_buf.start_add, in->delay_buf.size);
1635
1636 read_from_buffer(in->delay_buf.rd, in->temp_buffer, frame_size,
1637 in->delay_buf.start_add, in->delay_buf.size);
1638 in->delay_buf.rd = update_pointer(in->delay_buf.rd, frame_size,
1639 in->delay_buf.start_add, in->delay_buf.size);
1640
1641 return 0;
1642}
1643
1644static void* aml_audio_threadloop(void *data __unused) {
1645 struct aml_stream_in *in = NULL;
1646 struct aml_stream_out *out = NULL;
1647 int output_size = 0;
1648 int i = 0, ret;
1649
1650 if (gpAmlDevice == NULL) {
1651 ALOGE("%s, gpAmlDevice is NULL\n", __FUNCTION__);
1652 return ((void *) 0);
1653 }
1654
1655 in = &gpAmlDevice->in;
1656 out = &gpAmlDevice->out;
1657
1658 gUSBCheckLastFlag = 0;
1659 gUSBCheckFlag = 0;
1660
1661 gpAmlDevice->aml_Audio_ThreadExecFlag = 1;
1662 prctl(PR_SET_NAME, (unsigned long)"aml_TV_audio");
1663 ret = aml_device_init(gpAmlDevice);
1664 if (ret < 0) {
1665 ALOGE("%s, Devices fail opened!\n", __FUNCTION__);
1666 return NULL;
1667 }
1668
1669 while (gpAmlDevice != NULL && gpAmlDevice->aml_Audio_ThreadTurnOnFlag) {
1670 //exit threadloop
1671 if (gpAmlDevice->aml_Audio_ThreadTurnOnFlag == 0) {
1672 ALOGD("%s, aml_Audio_ThreadTurnOnFlag is 0 break now.\n",
1673 __FUNCTION__);
1674 break;
1675 }
1676 if (GetWriteSpace((char *) in->write_buffer, (char *) out->read_buffer,
1677 TEMP_BUFFER_SIZE) > in->max_bytes) {
1678 output_size = alsa_in_read(in, in->temp_buffer,
1679 in->config.period_size * 4);
1680 if (output_size < 0) {
1681 //ALOGE("%s, alsa_in_read fail!\n", __FUNCTION__);
1682 } else {
1683 if (check_audio_type(out) == MUTE)
1684 memset((char *) in->temp_buffer, 0, output_size);
1685 if (in->delay_time != 0 && get_output_deviceID() == 0) {
1686 set_delay(in, output_size);
1687 }
1688 write_to_buffer((char *) in->write_buffer,
1689 (char *) in->temp_buffer, output_size,
1690 (char *) start_temp_buffer, TEMP_BUFFER_SIZE);
1691 in->write_buffer = update_pointer((char *) in->write_buffer,
1692 output_size, (char *) start_temp_buffer,
1693 TEMP_BUFFER_SIZE);
1694 }
1695
1696 }
1697
1698 USB_check(out);
1699
1700 if (GetReadSpace((char *) in->write_buffer, (char *) out->read_buffer,
1701 TEMP_BUFFER_SIZE) > pcm_config_out.period_size << 2) {
1702 read_from_buffer((char *) out->read_buffer,
1703 (char *) out->temp_buffer, pcm_config_out.period_size << 2,
1704 (char *) start_temp_buffer, TEMP_BUFFER_SIZE);
1705
1706 output_size = pcm_config_out.period_size << 2;
1707 if (gpAmlDevice->out.output_device == CC_OUT_USE_ALSA) {
1708 output_size = alsa_out_write(out, out->temp_buffer,
1709 output_size);
1710 } else if (gpAmlDevice->out.output_device == CC_OUT_USE_AMAUDIO) {
1711 output_size = amaudio_out_write(out, out->temp_buffer,
1712 output_size);
1713 if (output_size < 0) {
1714 amaudio_out_close(out);
1715 set_output_deviceID(MODEAMAUDIO);
1716 amaudio_out_open(out);
1717 reset_amaudio(out, 4096);
1718 }
1719 if (output_record_enable == 1) {
1720 buffer_write(&android_out_buffer, out->temp_buffer,
1721 output_size);
1722 }
1723 } else if (gpAmlDevice->out.output_device == CC_OUT_USE_ANDROID) {
1724 output_size = buffer_write(&android_out_buffer,
1725 out->temp_buffer, output_size);
1726 }
1727
1728 if (output_size < 0) {
1729 //ALOGE("%s, out_write fail! bytes = %d \n", __FUNCTION__, output_size);
1730 } else {
1731 out->read_buffer = update_pointer((char *) out->read_buffer,
1732 output_size, (char *) start_temp_buffer,
1733 TEMP_BUFFER_SIZE);
1734 DoDumpData(out->temp_buffer, output_size,
1735 CC_DUMP_SRC_TYPE_OUTPUT);
1736 memset(out->temp_buffer, 0, output_size);
1737 }
1738 }
1739 }
1740
1741 if (gpAmlDevice != NULL) {
1742 gpAmlDevice->aml_Audio_ThreadTurnOnFlag = 0;
1743 ALOGD("%s, set aml_Audio_ThreadTurnOnFlag as 0.\n", __FUNCTION__);
1744 gpAmlDevice->aml_Audio_ThreadExecFlag = 0;
1745 ALOGD("%s, set aml_Audio_ThreadExecFlag as 0.\n", __FUNCTION__);
1746 }
1747
1748 ALOGD("%s, exiting...\n", __FUNCTION__);
1749 return ((void *) 0);
1750}
1751
1752static int clrDevice(struct aml_dev *device) {
1753 memset((void *) device, 0, sizeof(struct aml_dev));
1754
1755 device->in.config.channels = 2;
1756 device->in.config.rate = DEFAULT_IN_SAMPLE_RATE;
1757 device->in.config.period_size = CAPTURE_PERIOD_SIZE;
1758 device->in.config.period_count = CAPTURE_PERIOD_COUNT;
1759 device->in.config.format = PCM_FORMAT_S16_LE;
1760
1761 device->out.config.channels = 2;
1762 device->out.config.rate = DEFAULT_OUT_SAMPLE_RATE;
1763 device->out.config.period_size = PLAYBACK_PERIOD_SIZE;
1764 device->out.config.period_count = PLAYBACK_PERIOD_COUNT;
1765 device->out.config.format = PCM_FORMAT_S16_LE;
1766
1767 return 0;
1768}
1769
1770int aml_audio_open(unsigned int sr, int input_device, int output_device) {
1771 pthread_attr_t attr;
1772 struct sched_param param;
1773 int ret;
1774
1775 ALOGD("%s, sr = %d, input_device = %d, output_device = %d\n",
1776 __FUNCTION__, sr, input_device, output_device);
1777
1778 aml_audio_close();
1779
1780 pthread_mutex_lock(&amaudio_dev_op_mutex);
1781
1782 gpAmlDevice = &gmAmlDevice;
1783 clrDevice(gpAmlDevice);
1784
1785 ret = set_input_stream_sample_rate(sr, &gpAmlDevice->in);
1786 if (ret < 0) {
1787 ALOGE("%s, set_input_stream_sample_rate fail!\n", __FUNCTION__);
1788 clrDevice(gpAmlDevice);
1789 gpAmlDevice = NULL;
1790 pthread_mutex_unlock(&amaudio_dev_op_mutex);
1791 return -1;
1792 }
1793
1794 gpAmlDevice->out.output_device = output_device;
1795 gpAmlDevice->out.user_set_device = output_device;
1796 if (gpAmlDevice->out.user_set_device == CC_OUT_USE_ALSA) {
1797 ALOGD("%s,Use tinyalsa as output device!\n", __FUNCTION__);
1798 } else if (gpAmlDevice->out.user_set_device == CC_OUT_USE_AMAUDIO) {
1799 ALOGD("%s, Use amlogic amaudio as output device!\n", __FUNCTION__);
1800 } else if (gpAmlDevice->out.user_set_device == CC_OUT_USE_ANDROID) {
1801 ALOGD("%s, Use amlogic android as output device!\n", __FUNCTION__);
1802 } else {
1803 ALOGE("%s, Unkown output device, use default amaudio\n", __FUNCTION__);
1804 gpAmlDevice->out.user_set_device = CC_OUT_USE_AMAUDIO;
1805 }
1806
1807 ret = set_input_device(input_device);
1808 if (ret < 0) {
1809 ALOGE("Fail to set input device for HW resample!\n");
1810 }
1811
1812 gpAmlDevice->in.device = get_aml_device(input_device);
1813
1814 pthread_attr_init(&attr);
1815 pthread_attr_setschedpolicy(&attr, SCHED_RR);
1816 param.sched_priority = sched_get_priority_max(SCHED_RR);
1817 /*pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
1818 param.sched_priority = sched_get_priority_max(SCHED_FIFO);
1819 ALOGD("%s, aml_audio thread has %d priority!\n",
1820 __FUNCTION__, param.sched_priority);*/
1821 pthread_attr_setschedparam(&attr, &param);
1822 gpAmlDevice->aml_Audio_ThreadTurnOnFlag = 1;
1823 gpAmlDevice->aml_Audio_ThreadExecFlag = 0;
1824 ret = pthread_create(&gpAmlDevice->aml_Audio_ThreadID, &attr,
1825 &aml_audio_threadloop, NULL);
1826 pthread_attr_destroy(&attr);
1827 if (ret != 0) {
1828 ALOGE("%s, Create thread fail!\n", __FUNCTION__);
1829 aml_device_close(gpAmlDevice);
1830 clrDevice(gpAmlDevice);
1831 gpAmlDevice = NULL;
1832 pthread_mutex_unlock(&amaudio_dev_op_mutex);
1833 return -1;
1834 }
1835
1836 creat_pthread_for_android_check(&gpAmlDevice->android_check_ThreadID);
1837
1838 pthread_mutex_unlock(&amaudio_dev_op_mutex);
1839
1840 ALOGD("%s, exiting...\n", __FUNCTION__);
1841 return 0;
1842}
1843
1844int aml_audio_close(void) {
1845 int i = 0, tmp_timeout_count = 1000;
1846
1847 ALOGD("%s, gpAmlDevice = %p\n", __FUNCTION__, gpAmlDevice);
1848
1849 pthread_mutex_lock(&amaudio_dev_op_mutex);
1850
1851 if (gpAmlDevice != NULL) {
1852 gpAmlDevice->aml_Audio_ThreadTurnOnFlag = 0;
1853 ALOGD("%s, set aml_Audio_ThreadTurnOnFlag as 0.\n", __FUNCTION__);
1854 while (1) {
1855 if (gpAmlDevice->aml_Audio_ThreadExecFlag == 0) {
1856 break;
1857 }
1858 if (i >= tmp_timeout_count) {
1859 break;
1860 }
1861 i++;
1862 usleep(10 * 1000);
1863 }
1864
1865 if (i >= tmp_timeout_count) {
1866 ALOGE("%s, we have try %d times, but the aml audio thread's exec flag is still(%d)!!!\n",
1867 __FUNCTION__, tmp_timeout_count,
1868 gpAmlDevice->aml_Audio_ThreadExecFlag);
1869 } else {
1870 ALOGD("%s, kill aml audio thread success after try %d times.\n",
1871 __FUNCTION__, i);
1872 }
1873
1874 pthread_join(gpAmlDevice->aml_Audio_ThreadID, NULL);
1875 gpAmlDevice->aml_Audio_ThreadID = 0;
1876
1877 exit_pthread_for_android_check(gpAmlDevice->android_check_ThreadID);
1878 gpAmlDevice->android_check_ThreadID = 0;
1879
1880 aml_device_close(gpAmlDevice);
1881 clrDevice(gpAmlDevice);
1882 gpAmlDevice = NULL;
1883
1884 ALOGD("%s, aml audio close success.\n", __FUNCTION__);
1885 }
1886
1887 pthread_mutex_unlock(&amaudio_dev_op_mutex);
1888 return 0;
1889}
1890
1891int check_input_stream_sr(unsigned int sr) {
1892 if (sr >= 8000 && sr <= 48000) {
1893 return 0;
1894 }
1895 return -1;
1896}
1897
1898int set_output_mode(int mode) {
1899 if (gpAmlDevice == NULL) {
1900 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1901 return -1;
1902 }
1903
1904 if (mode < CC_OUT_MODE_DIRECT || mode > CC_OUT_MODE_DIRECT_MIX) {
1905 ALOGE("%s, mode error: mode = %d!\n", __FUNCTION__, mode);
1906 return -1;
1907 }
1908
1909 int OutHandle = gpAmlDevice->out.amAudio_OutHandle;
1910 if (OutHandle < 0) {
1911 ALOGE("%s, amaudio out handle error!\n", __FUNCTION__);
1912 return -1;
1913 }
1914
1915 pthread_mutex_lock(&gpAmlDevice->out.lock);
1916 ioctl(OutHandle, AMAUDIO_IOC_AUDIO_OUT_MODE, mode);
1917 pthread_mutex_unlock(&gpAmlDevice->out.lock);
1918 return 0;
1919}
1920
1921int set_music_gain(int gain) {
1922 if (gpAmlDevice == NULL) {
1923 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1924 return -1;
1925 }
1926
1927 int OutHandle = gpAmlDevice->out.amAudio_OutHandle;
1928 if (OutHandle < 0) {
1929 ALOGE("%s, amaudio out handle error!\n", __FUNCTION__);
1930 return -1;
1931 }
1932
1933 pthread_mutex_lock(&gpAmlDevice->out.lock);
1934 if (gain > 256) {
1935 gain = 256;
1936 }
1937 if (gain < 0) {
1938 gain = 0;
1939 }
1940 ioctl(OutHandle, AMAUDIO_IOC_MUSIC_GAIN, gain);
1941 ALOGD("%s, music gain :%d!\n", __FUNCTION__, gain);
1942 pthread_mutex_unlock(&gpAmlDevice->out.lock);
1943 return 0;
1944}
1945
1946int set_left_gain(int left_gain) {
1947 if (gpAmlDevice == NULL) {
1948 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1949 return -1;
1950 }
1951
1952 int OutHandle = gpAmlDevice->out.amAudio_OutHandle;
1953 if (OutHandle < 0) {
1954 ALOGE("%s, amaudio out handle error!\n", __FUNCTION__);
1955 return -1;
1956 }
1957 pthread_mutex_lock(&gpAmlDevice->out.lock);
1958 if (left_gain > 256) {
1959 left_gain = 256;
1960 }
1961 if (left_gain < 0) {
1962 left_gain = 0;
1963 }
1964 ioctl(OutHandle, AMAUDIO_IOC_MIC_LEFT_GAIN, left_gain);
1965 ALOGD("%s, left mic gain :%d!\n", __FUNCTION__, left_gain);
1966 pthread_mutex_unlock(&gpAmlDevice->out.lock);
1967 return 0;
1968}
1969
1970int set_right_gain(int right_gain) {
1971 if (gpAmlDevice == NULL) {
1972 ALOGE("%s, aml audio is not open, must open it first!\n", __FUNCTION__);
1973 return -1;
1974 }
1975 int OutHandle = gpAmlDevice->out.amAudio_OutHandle;
1976 if (OutHandle < 0) {
1977 ALOGE("%s, amaudio out handle error!\n", __FUNCTION__);
1978 return -1;
1979 }
1980 pthread_mutex_lock(&gpAmlDevice->out.lock);
1981 if (right_gain > 256) {
1982 right_gain = 256;
1983 }
1984 if (right_gain < 0) {
1985 right_gain = 0;
1986 }
1987 ioctl(OutHandle, AMAUDIO_IOC_MIC_RIGHT_GAIN, right_gain);
1988 ALOGD("%s, right mic gain :%d!\n", __FUNCTION__, right_gain);
1989 pthread_mutex_unlock(&gpAmlDevice->out.lock);
1990 return 0;
1991}
1992
1993int set_audio_delay(int delay_ms) {
1994 gpAmlDevice->in.delay_time = delay_ms;
1995 ALOGI("Set audio delay time %d ms!\n", delay_ms);
1996 return 0;
1997}
1998
1999int get_audio_delay(void) {
2000 return gpAmlDevice->in.delay_time;
2001}
2002
2003int SetDumpDataFlag(int tmp_flag) {
2004 int tmp_val;
2005 tmp_val = gDumpDataFlag;
2006 gDumpDataFlag = tmp_flag;
2007 return tmp_val;
2008}
2009
2010int GetDumpDataFlag(void) {
2011 int tmp_val = 0;
2012 tmp_val = gDumpDataFlag;
2013 return tmp_val;
2014}
2015
2016static void DoDumpData(void *data_buf, int size, int aud_src_type) {
2017 int tmp_type = 0;
2018 char prop_value[PROPERTY_VALUE_MAX] = { 0 };
2019 char file_path_01[PROPERTY_VALUE_MAX] = { 0 };
2020 char file_path_02[PROPERTY_VALUE_MAX] = { 0 };
2021
2022 if (GetDumpDataFlag() == 0) {
2023 return;
2024 }
2025
2026 memset(prop_value, '\0', PROPERTY_VALUE_MAX);
2027 property_get("audio.dumpdata.en", prop_value, "null");
2028 if (strcasecmp(prop_value, "null") == 0
2029 || strcasecmp(prop_value, "0") == 0) {
2030 if (gDumpDataFd1 >= 0) {
2031 close(gDumpDataFd1);
2032 gDumpDataFd1 = -1;
2033 }
2034 if (gDumpDataFd2 >= 0) {
2035 close(gDumpDataFd2);
2036 gDumpDataFd2 = -1;
2037 }
2038
2039 return;
2040 }
2041
2042 tmp_type = CC_DUMP_SRC_TYPE_INPUT;
2043 property_get("audio.dumpdata.src", prop_value, "null");
2044 if (strcasecmp(prop_value, "null") == 0
2045 || strcasecmp(prop_value, "input") == 0) {
2046 tmp_type = CC_DUMP_SRC_TYPE_INPUT;
2047 } else if (strcasecmp(prop_value, "output") == 0) {
2048 tmp_type = CC_DUMP_SRC_TYPE_OUTPUT;
2049 } else if (strcasecmp(prop_value, "input,output") == 0) {
2050 tmp_type = CC_DUMP_SRC_TYPE_IN_OUT;
2051 } else if (strcasecmp(prop_value, "output,input") == 0) {
2052 tmp_type = CC_DUMP_SRC_TYPE_OUT_IN;
2053 }
2054
2055 if (tmp_type == CC_DUMP_SRC_TYPE_INPUT
2056 || tmp_type == CC_DUMP_SRC_TYPE_OUTPUT) {
2057 if (tmp_type != aud_src_type) {
2058 return;
2059 }
2060 }
2061
2062 memset(file_path_01, '\0', PROPERTY_VALUE_MAX);
2063 property_get("audio.dumpdata.path", file_path_01, "null");
2064 if (strcasecmp(file_path_01, "null") == 0) {
2065 file_path_01[0] = '\0';
2066 }
2067
2068 if (tmp_type == CC_DUMP_SRC_TYPE_IN_OUT
2069 || tmp_type == CC_DUMP_SRC_TYPE_OUT_IN) {
2070 memset(file_path_02, '\0', PROPERTY_VALUE_MAX);
2071 property_get("audio.dumpdata.path2", file_path_02, "null");
2072 if (strcasecmp(file_path_02, "null") == 0) {
2073 file_path_02[0] = '\0';
2074 }
2075 }
2076
2077 if (gDumpDataFd1 < 0 && file_path_01[0] != '\0') {
2078 if (access(file_path_01, 0) == 0) {
2079 gDumpDataFd1 = open(file_path_01, O_RDWR | O_SYNC);
2080 if (gDumpDataFd1 < 0) {
2081 ALOGE("%s, Open device file \"%s\" error: %s.\n", __FUNCTION__,
2082 file_path_01, strerror(errno));
2083 }
2084 } else {
2085 gDumpDataFd1 = open(file_path_01, O_WRONLY | O_CREAT | O_EXCL,
2086 S_IRUSR | S_IWUSR);
2087 if (gDumpDataFd1 < 0) {
2088 ALOGE("%s, Create device file \"%s\" error: %s.\n",
2089 __FUNCTION__, file_path_01, strerror(errno));
2090 }
2091 }
2092 }
2093
2094 if (gDumpDataFd2 < 0 && file_path_02[0] != '\0'
2095 && (tmp_type == CC_DUMP_SRC_TYPE_IN_OUT
2096 || tmp_type == CC_DUMP_SRC_TYPE_OUT_IN)) {
2097 if (access(file_path_02, 0) == 0) {
2098 gDumpDataFd2 = open(file_path_02, O_RDWR | O_SYNC);
2099 if (gDumpDataFd2 < 0) {
2100 ALOGE("%s, Open device file \"%s\" error: %s.\n", __FUNCTION__,
2101 file_path_02, strerror(errno));
2102 }
2103 } else {
2104 gDumpDataFd2 = open(file_path_02, O_WRONLY | O_CREAT | O_EXCL,
2105 S_IRUSR | S_IWUSR);
2106 if (gDumpDataFd2 < 0) {
2107 ALOGE("%s, Create device file \"%s\" error: %s.\n",
2108 __FUNCTION__, file_path_02, strerror(errno));
2109 }
2110 }
2111 }
2112
2113 if (tmp_type == CC_DUMP_SRC_TYPE_IN_OUT) {
2114 if (aud_src_type == CC_DUMP_SRC_TYPE_INPUT && gDumpDataFd1 >= 0) {
2115 write(gDumpDataFd1, data_buf, size);
2116 } else if (aud_src_type == CC_DUMP_SRC_TYPE_OUTPUT
2117 && gDumpDataFd2 >= 0) {
2118 write(gDumpDataFd2, data_buf, size);
2119 }
2120 } else if (tmp_type == CC_DUMP_SRC_TYPE_OUT_IN) {
2121 if (aud_src_type == CC_DUMP_SRC_TYPE_OUTPUT && gDumpDataFd1 >= 0) {
2122 write(gDumpDataFd1, data_buf, size);
2123 } else if (aud_src_type == CC_DUMP_SRC_TYPE_INPUT
2124 && gDumpDataFd2 >= 0) {
2125 write(gDumpDataFd2, data_buf, size);
2126 }
2127 } else {
2128 if (gDumpDataFd1 >= 0) {
2129 write(gDumpDataFd1, data_buf, size);
2130 }
2131 }
2132}
2133
2134int aml_audio_set_pregain(float gain)
2135{
2136 ALOGD("%s, pre-gain = %f dB\n", __FUNCTION__, gain);
2137
2138 pthread_mutex_lock(&amaudio_dev_op_mutex);
2139
2140 if (gpAmlDevice != NULL) {
2141 gpAmlDevice->in.pre_gain = powf(10, gain/20);
2142 }
2143
2144 pthread_mutex_unlock(&amaudio_dev_op_mutex);
2145
2146 return 0;
2147}
2148
2149int aml_audio_get_pregain(float *gain)
2150{
2151 if (gpAmlDevice != NULL) {
2152 *gain = 20*log10f(gpAmlDevice->in.pre_gain);
2153 return 0;
2154 }
2155
2156 ALOGE("%s, no active gpAmlDevice!\n", __FUNCTION__);
2157 return -1;
2158}
2159
2160int aml_audio_set_pre_mute(uint mute)
2161{
2162 ALOGD("%s, mute = %d\n", __FUNCTION__, mute);
2163
2164 pthread_mutex_lock(&amaudio_dev_op_mutex);
2165
2166 if (gpAmlDevice != NULL) {
2167 gpAmlDevice->in.pre_mute = mute;
2168 }
2169
2170 pthread_mutex_unlock(&amaudio_dev_op_mutex);
2171
2172 return 0;
2173}
2174
2175int aml_audio_get_pre_mute(uint *mute)
2176{
2177 if (gpAmlDevice != NULL) {
2178 *mute = gpAmlDevice->in.pre_mute;
2179 return 0;
2180 }
2181
2182 ALOGE("%s, no active gpAmlDevice!\n", __FUNCTION__);
2183 return -1;
2184}
2185