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