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