summaryrefslogtreecommitdiff
path: root/audio_hw.c (plain)
blob: ff36310acea80abf9ba784a9fc464ea7624f9722
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_primary"
18//#define LOG_NALOGV 0
19//#define LOG_NALOGV_FUNCTION
20#ifdef LOG_NALOGV_FUNCTION
21#define LOGFUNC(...) ((void)0)
22#else
23#define LOGFUNC(...) (ALOGD(__VA_ARGS__))
24#endif
25
26#include <errno.h>
27#include <pthread.h>
28#include <stdint.h>
29#include <sys/time.h>
30#include <stdlib.h>
31#include <sys/stat.h>
32#include <fcntl.h>
33#include <time.h>
34#include <utils/Timers.h>
35#include <cutils/log.h>
36#include <cutils/str_parms.h>
37#include <cutils/properties.h>
38#include <linux/ioctl.h>
39#include <hardware/hardware.h>
40#include <system/audio.h>
41#include <hardware/audio.h>
42#include <sound/asound.h>
43#include <tinyalsa/asoundlib.h>
44#include <audio_utils/echo_reference.h>
45#include <hardware/audio_effect.h>
46#include <audio_effects/effect_aec.h>
47#include <audio_route/audio_route.h>
48
49#include "libTVaudio/audio/audio_effect_control.h"
50#include "audio_hw.h"
51#include "audio_hw_utils.h"
52#include "spdifenc_wrap.h"
53//extern int spdifenc_write(const void *buffer, size_t numBytes);
54//extern uint64_t spdifenc_get_total();
55extern void aml_audio_hwsync_clear_status(struct aml_stream_out *out);
56extern int aml_audio_hwsync_find_frame(struct aml_stream_out *out,
57 const void *in_buffer, size_t in_bytes, uint64_t *cur_pts, int *outsize);
58
59/* ALSA cards for AML */
60#define CARD_AMLOGIC_BOARD 0
61/* ALSA ports for AML */
62#define PORT_I2S 0
63#define PORT_SPDIF 1
64#define PORT_PCM 2
65/* number of frames per period */
66#define DEFAULT_PERIOD_SIZE 1024
67#define DEFAULT_CAPTURE_PERIOD_SIZE 1024
68//static unsigned PERIOD_SIZE = DEFAULT_PERIOD_SIZE;
69static unsigned CAPTURE_PERIOD_SIZE = DEFAULT_CAPTURE_PERIOD_SIZE;
70/* number of periods for low power playback */
71#define PLAYBACK_PERIOD_COUNT 4
72/* number of periods for capture */
73#define CAPTURE_PERIOD_COUNT 4
74
75/* minimum sleep time in out_write() when write threshold is not reached */
76#define MIN_WRITE_SLEEP_US 5000
77
78#define RESAMPLER_BUFFER_FRAMES (PERIOD_SIZE * 6)
79#define RESAMPLER_BUFFER_SIZE (4 * RESAMPLER_BUFFER_FRAMES)
80
81#define NSEC_PER_SECOND 1000000000ULL
82
83//static unsigned int DEFAULT_OUT_SAMPLING_RATE = 48000;
84
85/* sampling rate when using MM low power port */
86#define MM_LOW_POWER_SAMPLING_RATE 44100
87/* sampling rate when using MM full power port */
88#define MM_FULL_POWER_SAMPLING_RATE 48000
89/* sampling rate when using VX port for narrow band */
90#define VX_NB_SAMPLING_RATE 8000
91#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
92
93#define TSYNC_FIRSTAPTS "/sys/class/tsync/firstapts"
94#define TSYNC_PCRSCR "/sys/class/tsync/pts_pcrscr"
95#define TSYNC_EVENT "/sys/class/tsync/event"
96#define TSYNC_APTS "/sys/class/tsync/pts_audio"
97#define SYSTIME_CORRECTION_THRESHOLD (90000*10/100)
98#define APTS_DISCONTINUE_THRESHOLD_MIN (90000/1000*100)
99#define APTS_DISCONTINUE_THRESHOLD_MAX (5*90000)
100
101static const struct pcm_config pcm_config_out = {
102 .channels = 2,
103 .rate = MM_FULL_POWER_SAMPLING_RATE,
104 .period_size = DEFAULT_PERIOD_SIZE,
105 .period_count = PLAYBACK_PERIOD_COUNT,
106 .format = PCM_FORMAT_S16_LE,
107};
108
109static const struct pcm_config pcm_config_out_direct = {
110 .channels = 2,
111 .rate = MM_FULL_POWER_SAMPLING_RATE,
112 .period_size = DEFAULT_PERIOD_SIZE,
113 .period_count = PLAYBACK_PERIOD_COUNT,
114 .format = PCM_FORMAT_S16_LE,
115};
116
117static const struct pcm_config pcm_config_in = {
118 .channels = 2,
119 .rate = MM_FULL_POWER_SAMPLING_RATE,
120 .period_size = DEFAULT_CAPTURE_PERIOD_SIZE,
121 .period_count = CAPTURE_PERIOD_COUNT,
122 .format = PCM_FORMAT_S16_LE,
123};
124
125static const struct pcm_config pcm_config_bt = {
126 .channels = 1,
127 .rate = VX_NB_SAMPLING_RATE,
128 .period_size = DEFAULT_PERIOD_SIZE,
129 .period_count = PLAYBACK_PERIOD_COUNT,
130 .format = PCM_FORMAT_S16_LE,
131};
132
133#define HW_SYNC_STATE_HEADER 0
134#define HW_SYNC_STATE_BODY 1
135#define HW_SYNC_STATE_RESYNC 2
136
137static void select_output_device(struct aml_audio_device *adev);
138static void select_input_device(struct aml_audio_device *adev);
139static void select_devices(struct aml_audio_device *adev);
140static int adev_set_voice_volume(struct audio_hw_device *dev, float volume);
141static int do_input_standby(struct aml_stream_in *in);
142static int do_output_standby(struct aml_stream_out *out);
143static uint32_t out_get_sample_rate(const struct audio_stream *stream);
144static int out_pause(struct audio_stream_out *stream);
145static inline short CLIP(int r)
146{
147 return (r > 0x7fff) ? 0x7fff :
148 (r < -0x8000) ? 0x8000 :
149 r;
150}
151//code here for audio hal mixer when hwsync with af mixer output stream output
152//at the same,need do a software mixer in audio hal.
153static int aml_hal_mixer_init(struct aml_hal_mixer *mixer)
154{
155 pthread_mutex_lock(&mixer->lock);
156 mixer->wp = 0;
157 mixer->rp = 0;
158 mixer->buf_size = AML_HAL_MIXER_BUF_SIZE;
159 mixer->need_cache_flag = 1;
160 pthread_mutex_unlock(&mixer->lock);
161 return 0;
162}
163static uint aml_hal_mixer_get_space(struct aml_hal_mixer *mixer)
164{
165 unsigned space;
166 if (mixer->wp >= mixer->rp) {
167 space = mixer->buf_size - (mixer->wp - mixer->rp);
168 } else {
169 space = mixer->rp - mixer->wp;
170 }
171 return space > 64 ? (space - 64) : 0;
172}
173static int aml_hal_mixer_get_content(struct aml_hal_mixer *mixer)
174{
175 unsigned content = 0;
176 pthread_mutex_lock(&mixer->lock);
177 if (mixer->wp >= mixer->rp) {
178 content = mixer->wp - mixer->rp;
179 } else {
180 content = mixer->wp - mixer->rp + mixer->buf_size;
181 }
182 //ALOGI("wp %d,rp %d\n",mixer->wp,mixer->rp);
183 pthread_mutex_unlock(&mixer->lock);
184 return content;
185}
186//we assue the cached size is always smaller then buffer size
187//need called by device mutux locked
188static int aml_hal_mixer_write(struct aml_hal_mixer *mixer, const void *w_buf, uint size)
189{
190 unsigned space;
191 unsigned write_size = size;
192 unsigned tail = 0;
193 pthread_mutex_lock(&mixer->lock);
194 space = aml_hal_mixer_get_space(mixer);
195 if (space < size) {
196 ALOGI("write data no space,space %d,size %d,rp %d,wp %d,reset all ptr\n", space, size, mixer->rp, mixer->wp);
197 mixer->wp = 0;
198 mixer->rp = 0;
199 }
200 //TODO
201 if (write_size > space) {
202 write_size = space;
203 }
204 if (write_size + mixer->wp > mixer->buf_size) {
205 tail = mixer->buf_size - mixer->wp;
206 memcpy(mixer->start_buf + mixer->wp, w_buf, tail);
207 write_size -= tail;
208 memcpy(mixer->start_buf, (unsigned char*)w_buf + tail, write_size);
209 mixer->wp = write_size;
210 } else {
211 memcpy(mixer->start_buf + mixer->wp, w_buf, write_size);
212 mixer->wp += write_size;
213 mixer->wp %= AML_HAL_MIXER_BUF_SIZE;
214 }
215 pthread_mutex_unlock(&mixer->lock);
216 return size;
217}
218//need called by device mutux locked
219static int aml_hal_mixer_read(struct aml_hal_mixer *mixer, void *r_buf, uint size)
220{
221 unsigned cached_size;
222 unsigned read_size = size;
223 unsigned tail = 0;
224 cached_size = aml_hal_mixer_get_content(mixer);
225 pthread_mutex_lock(&mixer->lock);
226 // we always assue we have enough data to read when hwsync enabled.
227 // if we do not have,insert zero data.
228 if (cached_size < size) {
229 ALOGI("read data has not enough data to mixer,read %d, have %d,rp %d,wp %d\n", size, cached_size, mixer->rp, mixer->wp);
230 memset((unsigned char*)r_buf + cached_size, 0, size - cached_size);
231 read_size = cached_size;
232 }
233 if (read_size + mixer->rp > mixer->buf_size) {
234 tail = mixer->buf_size - mixer->rp;
235 memcpy(r_buf, mixer->start_buf + mixer->rp, tail);
236 read_size -= tail;
237 memcpy((unsigned char*)r_buf + tail, mixer->start_buf, read_size);
238 mixer->rp = read_size;
239 } else {
240 memcpy(r_buf, mixer->start_buf + mixer->rp, read_size);
241 mixer->rp += read_size;
242 mixer->rp %= AML_HAL_MIXER_BUF_SIZE;
243 }
244 pthread_mutex_unlock(&mixer->lock);
245 return size;
246}
247// aml audio hal mixer code end
248#if 0
249static inline bool hwsync_header_valid(uint8_t *header)
250{
251 return (header[0] == 0x55) &&
252 (header[1] == 0x55) &&
253 (header[2] == 0x00) &&
254 (header[3] == 0x01);
255}
256
257static inline uint64_t hwsync_header_get_pts(uint8_t *header)
258{
259 return (((uint64_t)header[8]) << 56) |
260 (((uint64_t)header[9]) << 48) |
261 (((uint64_t)header[10]) << 40) |
262 (((uint64_t)header[11]) << 32) |
263 (((uint64_t)header[12]) << 24) |
264 (((uint64_t)header[13]) << 16) |
265 (((uint64_t)header[14]) << 8) |
266 ((uint64_t)header[15]);
267}
268
269static inline uint32_t hwsync_header_get_size(uint8_t *header)
270{
271 return (((uint32_t)header[4]) << 24) |
272 (((uint32_t)header[5]) << 16) |
273 (((uint32_t)header[6]) << 8) |
274 ((uint32_t)header[7]);
275}
276#endif
277
278static void select_devices(struct aml_audio_device *adev)
279{
280 LOGFUNC("%s(mode=%d, out_device=%#x)", __FUNCTION__, adev->mode, adev->out_device);
281 int headset_on;
282 int headphone_on;
283 int speaker_on;
284 int hdmi_on;
285 int earpiece;
286 int mic_in;
287 int headset_mic;
288
289 headset_on = adev->out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET;
290 headphone_on = adev->out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
291 speaker_on = adev->out_device & AUDIO_DEVICE_OUT_SPEAKER;
292 hdmi_on = adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL;
293 earpiece = adev->out_device & AUDIO_DEVICE_OUT_EARPIECE;
294 mic_in = adev->in_device & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC);
295 headset_mic = adev->in_device & AUDIO_DEVICE_IN_WIRED_HEADSET;
296
297 LOGFUNC("%s : hs=%d , hp=%d, sp=%d, hdmi=0x%x,earpiece=0x%x", __func__,
298 headset_on, headphone_on, speaker_on, hdmi_on, earpiece);
299 LOGFUNC("%s : in_device(%#x), mic_in(%#x), headset_mic(%#x)", __func__,
300 adev->in_device, mic_in, headset_mic);
301 audio_route_reset(adev->ar);
302 if (hdmi_on) {
303 audio_route_apply_path(adev->ar, "hdmi");
304 }
305 if (headphone_on || headset_on) {
306 audio_route_apply_path(adev->ar, "headphone");
307 }
308 if (speaker_on || earpiece) {
309 audio_route_apply_path(adev->ar, "speaker");
310 }
311 if (mic_in) {
312 audio_route_apply_path(adev->ar, "main_mic");
313 }
314 if (headset_mic) {
315 audio_route_apply_path(adev->ar, "headset-mic");
316 }
317
318 audio_route_update_mixer(adev->ar);
319
320}
321
322static void select_mode(struct aml_audio_device *adev)
323{
324 LOGFUNC("%s(out_device=%#x)", __FUNCTION__, adev->out_device);
325 LOGFUNC("%s(in_device=%#x)", __FUNCTION__, adev->in_device);
326 return;
327
328 /* force earpiece route for in call state if speaker is the
329 only currently selected route. This prevents having to tear
330 down the modem PCMs to change route from speaker to earpiece
331 after the ringtone is played, but doesn't cause a route
332 change if a headset or bt device is already connected. If
333 speaker is not the only thing active, just remove it from
334 the route. We'll assume it'll never be used initally during
335 a call. This works because we're sure that the audio policy
336 manager will update the output device after the audio mode
337 change, even if the device selection did not change. */
338 if ((adev->out_device & AUDIO_DEVICE_OUT_ALL) == AUDIO_DEVICE_OUT_SPEAKER) {
339 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
340 } else {
341 adev->out_device &= ~AUDIO_DEVICE_OUT_SPEAKER;
342 }
343
344 return;
345}
346
347static int get_aml_card(void)
348{
349 int card = -1, err = 0;
350 int fd = -1;
351 unsigned fileSize = 512;
352 char *read_buf = NULL, *pd = NULL;
353 static const char *const SOUND_CARDS_PATH = "/proc/asound/cards";
354 fd = open(SOUND_CARDS_PATH, O_RDONLY);
355 if (fd < 0) {
356 ALOGE("ERROR: failed to open config file %s error: %d\n", SOUND_CARDS_PATH, errno);
357 close(fd);
358 return -EINVAL;
359 }
360
361 read_buf = (char *)malloc(fileSize);
362 if (!read_buf) {
363 ALOGE("Failed to malloc read_buf");
364 close(fd);
365 return -ENOMEM;
366 }
367 memset(read_buf, 0x0, fileSize);
368 err = read(fd, read_buf, fileSize);
369 if (fd < 0) {
370 ALOGE("ERROR: failed to read config file %s error: %d\n", SOUND_CARDS_PATH, errno);
371 close(fd);
372 return -EINVAL;
373 }
374 pd = strstr(read_buf, "AML");
375 card = *(pd - 3) - '0';
376
377OUT:
378 free(read_buf);
379 close(fd);
380 return card;
381}
382
383static int get_pcm_bt_port(void)
384{
385 int port = -1, err = 0;
386 int fd = -1;
387 unsigned fileSize = 512;
388 char *read_buf = NULL, *pd = NULL;
389 static const char *const SOUND_PCM_PATH = "/proc/asound/pcm";
390 fd = open(SOUND_PCM_PATH, O_RDONLY);
391 if (fd < 0) {
392 ALOGE("ERROR: failed to open config file %s error: %d\n", SOUND_PCM_PATH, errno);
393 close(fd);
394 return -EINVAL;
395 }
396
397 read_buf = (char *)malloc(fileSize);
398 if (!read_buf) {
399 ALOGE("Failed to malloc read_buf");
400 close(fd);
401 return -ENOMEM;
402 }
403 memset(read_buf, 0x0, fileSize);
404 err = read(fd, read_buf, fileSize);
405 if (fd < 0) {
406 ALOGE("ERROR: failed to read config file %s error: %d\n", SOUND_PCM_PATH, errno);
407 close(fd);
408 return -EINVAL;
409 }
410 pd = strstr(read_buf, "pcm2bt-pcm");
411 port = *(pd + 11) - '0';
412
413OUT:
414 free(read_buf);
415 close(fd);
416 return port;
417}
418
419static int get_spdif_port()
420{
421 int port = -1, err = 0;
422 int fd = -1;
423 unsigned fileSize = 512;
424 char *read_buf = NULL, *pd = NULL;
425 static const char *const SOUND_PCM_PATH = "/proc/asound/pcm";
426 fd = open(SOUND_PCM_PATH, O_RDONLY);
427 if (fd < 0) {
428 ALOGE("ERROR: failed to open config file %s error: %d\n", SOUND_PCM_PATH, errno);
429 close(fd);
430 return -EINVAL;
431 }
432
433 read_buf = (char *)malloc(fileSize);
434 if (!read_buf) {
435 ALOGE("Failed to malloc read_buf");
436 close(fd);
437 return -ENOMEM;
438 }
439 memset(read_buf, 0x0, fileSize);
440 err = read(fd, read_buf, fileSize);
441 if (fd < 0) {
442 ALOGE("ERROR: failed to read config file %s error: %d\n", SOUND_PCM_PATH, errno);
443 close(fd);
444 return -EINVAL;
445 }
446 pd = strstr(read_buf, "SPDIF");
447 port = *(pd - 3) - '0';
448
449OUT:
450 free(read_buf);
451 close(fd);
452 return port;
453}
454/* must be called with hw device and output stream mutexes locked */
455static int start_output_stream(struct aml_stream_out *out)
456{
457 struct aml_audio_device *adev = out->dev;
458 unsigned int card = CARD_AMLOGIC_BOARD;
459 unsigned int port = PORT_I2S;
460 int ret;
461 int i = 0;
462 struct aml_stream_out *out_removed = NULL;
463 bool hwsync_lpcm = (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(out->hal_format));
464 LOGFUNC("%s(adev->out_device=%#x, adev->mode=%d)",
465 __FUNCTION__, adev->out_device, adev->mode);
466 if (adev->mode != AUDIO_MODE_IN_CALL) {
467 /* FIXME: only works if only one output can be active at a time */
468 select_devices(adev);
469 }
470 if (out->hw_sync_mode == true) {
471 adev->hwsync_output = out;
472#if 0
473 for (i = 0; i < MAX_STREAM_NUM; i++) {
474 if (adev->active_output[i]) {
475 out_removed = adev->active_output[i];
476 pthread_mutex_lock(&out_removed->lock);
477 if (!out_removed->standby) {
478 ALOGI("hwsync start,force %p standby\n", out_removed);
479 do_output_standby(out_removed);
480 }
481 pthread_mutex_unlock(&out_removed->lock);
482 }
483 }
484#endif
485 }
486 card = get_aml_card();
487 if (adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
488 port = PORT_PCM;
489 out->config = pcm_config_bt;
490 } else if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT && !hwsync_lpcm) {
491 port = PORT_SPDIF;
492 }
493
494 LOGFUNC("*%s, open card(%d) port(%d)", __FUNCTION__, card, port);
495
496 /* default to low power: will be corrected in out_write if necessary before first write to
497 * tinyalsa.
498 */
499 out->write_threshold = out->config.period_size * PLAYBACK_PERIOD_COUNT;
500 out->config.start_threshold = out->config.period_size * PLAYBACK_PERIOD_COUNT;
501 out->config.avail_min = 0;//SHORT_PERIOD_SIZE;
502 //added by xujian for NTS hwsync/system stream mix smooth playback.
503 //we need re-use the tinyalsa pcm handle by all the output stream, including
504 //hwsync direct output stream,system mixer output stream.
505 //TODO we need diff the code with AUDIO_DEVICE_OUT_ALL_SCO.
506 //as it share the same hal but with the different card id.
507 //TODO need reopen the tinyalsa card when sr/ch changed,
508 if (adev->pcm == NULL) {
509 out->pcm = pcm_open(card, port, PCM_OUT /*| PCM_MMAP | PCM_NOIRQ*/, &(out->config));
510 if (!pcm_is_ready(out->pcm)) {
511 ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm));
512 pcm_close(out->pcm);
513 return -ENOMEM;
514 }
515 if (out->config.rate != out_get_sample_rate(&out->stream.common)) {
516 LOGFUNC("%s(out->config.rate=%d, out->config.channels=%d)",
517 __FUNCTION__, out->config.rate, out->config.channels);
518 ret = create_resampler(out_get_sample_rate(&out->stream.common),
519 out->config.rate,
520 out->config.channels,
521 RESAMPLER_QUALITY_DEFAULT,
522 NULL,
523 &out->resampler);
524 if (ret != 0) {
525 ALOGE("cannot create resampler for output");
526 return -ENOMEM;
527 }
528 out->buffer_frames = (out->config.period_size * out->config.rate) /
529 out_get_sample_rate(&out->stream.common) + 1;
530 out->buffer = malloc(pcm_frames_to_bytes(out->pcm, out->buffer_frames));
531 if (out->buffer == NULL) {
532 ALOGE("cannot malloc memory for out->buffer");
533 return -ENOMEM;
534 }
535 }
536 adev->pcm = out->pcm;
537 ALOGI("device pcm %p\n", adev->pcm);
538 } else {
539 ALOGI("stream %p share the pcm %p\n", out, adev->pcm);
540 out->pcm = adev->pcm;
541 }
542 LOGFUNC("channels=%d---format=%d---period_count%d---period_size%d---rate=%d---",
543 out->config.channels, out->config.format, out->config.period_count,
544 out->config.period_size, out->config.rate);
545
546 if (adev->echo_reference != NULL) {
547 out->echo_reference = adev->echo_reference;
548 }
549 if (out->resampler) {
550 out->resampler->reset(out->resampler);
551 }
552 if (out->is_tv_platform == 1) {
553 sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "2:2");
554 }
555 //set_codec_type(0);
556 if (out->hw_sync_mode == 1) {
557 LOGFUNC("start_output_stream with hw sync enable %p\n", out);
558 }
559 for (i = 0; i < MAX_STREAM_NUM; i++) {
560 if (adev->active_output[i] == NULL) {
561 ALOGI("store out (%p) to index %d\n", out, i);
562 adev->active_output[i] = out;
563 adev->active_output_count++;
564 break;
565 }
566 }
567 if (i == MAX_STREAM_NUM) {
568 ALOGE("error,no space to store the dev stream \n");
569 }
570 return 0;
571}
572
573/* dircet stream mainly map to audio HDMI port */
574static int start_output_stream_direct(struct aml_stream_out *out)
575{
576 struct aml_audio_device *adev = out->dev;
577 unsigned int card = CARD_AMLOGIC_BOARD;
578 unsigned int port = PORT_SPDIF;
579 int ret = 0;
580
581 int codec_type = get_codec_type(out->hal_format);
582 if (codec_type == AUDIO_FORMAT_PCM && out->config.rate > 48000 && (out->flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
583 ALOGI("start output stream for high sample rate pcm for direct mode\n");
584 codec_type = TYPE_PCM_HIGH_SR;
585 }
586 if (codec_type == AUDIO_FORMAT_PCM && out->config.channels >= 6 && (out->flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
587 ALOGI("start output stream for multi-channel pcm for direct mode\n");
588 codec_type = TYPE_MULTI_PCM;
589 }
590
591 card = get_aml_card();
592 ALOGI("%s: hdmi sound card id %d,device id %d \n", __func__, card, port);
593
594 if (out->config.channels == 6) {
595 ALOGI("round 6ch to 8 ch output \n");
596 /* our hw only support 8 channel configure,so when 5.1,hw mask the last two channels*/
597 sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "6:7");
598 out->config.channels = 8;
599 }
600 /*
601 * 8 channel audio only support 32 byte mode,so need convert them to
602 * PCM_FORMAT_S32_LE
603 */
604 if (out->config.channels == 8) {
605 port = PORT_I2S;
606 out->config.format = PCM_FORMAT_S32_LE;
607 adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
608 ALOGI("[%s %d]8CH format output: set port/0 adev->out_device/%d\n",
609 __FUNCTION__, __LINE__, AUDIO_DEVICE_OUT_SPEAKER);
610 }
611 if (getprop_bool("media.libplayer.wfd")) {
612 out->config.period_size = PERIOD_SIZE;
613 }
614 switch (out->hal_format) {
615 case AUDIO_FORMAT_E_AC3:
616 out->config.period_size = PERIOD_SIZE * 2;
617 out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 2;
618 out->config.start_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 2;
619 //as dd+ frame size = 1 and alsa sr as divide 16
620 //out->raw_61937_frame_size = 16;
621 break;
622 case AUDIO_FORMAT_DTS_HD:
623 case AUDIO_FORMAT_TRUEHD:
624 out->config.period_size = PERIOD_SIZE * 4 * 2;
625 out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 4 * 2;
626 out->config.start_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 4 * 2;
627 //out->raw_61937_frame_size = 16;//192k 2ch
628 break;
629 case AUDIO_FORMAT_PCM:
630 default:
631 out->config.period_size = PERIOD_SIZE;
632 out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE;
633 out->config.start_threshold = PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
634 //out->raw_61937_frame_size = 4;
635 }
636 out->config.avail_min = 0;
637 set_codec_type(codec_type);
638
639 if (out->config.channels == 6) {
640 ALOGI("round 6ch to 8 ch output \n");
641 /* our hw only support 8 channel configure,so when 5.1,hw mask the last two channels*/
642 sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "6:7");
643 out->config.channels = 8;
644 }
645 ALOGI("ALSA open configs: channels=%d, format=%d, period_count=%d, period_size=%d,,rate=%d",
646 out->config.channels, out->config.format, out->config.period_count,
647 out->config.period_size, out->config.rate);
648
649 if (out->pcm == NULL) {
650 out->pcm = pcm_open(card, port, PCM_OUT, &out->config);
651 if (!pcm_is_ready(out->pcm)) {
652 ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm));
653 pcm_close(out->pcm);
654 return -EINVAL;
655 }
656 } else {
657 ALOGE("stream %p share the pcm %p\n", out, out->pcm);
658 }
659
660 if (codec_type_is_raw_data(codec_type) && !(out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
661 spdifenc_init(out->pcm, out->hal_format);
662 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
663 }
664 out->codec_type = codec_type;
665 out->bytes_write_total = 0;
666
667 if (out->hw_sync_mode == 1) {
668 LOGFUNC("start_output_stream with hw sync enable %p\n", out);
669 }
670
671 return 0;
672}
673
674static int check_input_parameters(uint32_t sample_rate, audio_format_t format, int channel_count)
675{
676 LOGFUNC("%s(sample_rate=%d, format=%d, channel_count=%d)", __FUNCTION__, sample_rate, format, channel_count);
677
678 if (format != AUDIO_FORMAT_PCM_16_BIT) {
679 return -EINVAL;
680 }
681
682 if ((channel_count < 1) || (channel_count > 2)) {
683 return -EINVAL;
684 }
685
686 switch (sample_rate) {
687 case 8000:
688 case 11025:
689 case 16000:
690 case 22050:
691 case 24000:
692 case 32000:
693 case 44100:
694 case 48000:
695 break;
696 default:
697 return -EINVAL;
698 }
699
700 return 0;
701}
702
703static size_t get_input_buffer_size(unsigned int period_size, uint32_t sample_rate, audio_format_t format, int channel_count)
704{
705 size_t size;
706
707 LOGFUNC("%s(sample_rate=%d, format=%d, channel_count=%d)", __FUNCTION__, sample_rate, format, channel_count);
708
709 if (check_input_parameters(sample_rate, format, channel_count) != 0) {
710 return 0;
711 }
712
713 /* take resampling into account and return the closest majoring
714 multiple of 16 frames, as audioflinger expects audio buffers to
715 be a multiple of 16 frames */
716 if (period_size == 0) {
717 period_size = (pcm_config_in.period_size * sample_rate) / pcm_config_in.rate;
718 }
719
720 size = period_size;
721 size = ((size + 15) / 16) * 16;
722
723 return size * channel_count * sizeof(short);
724}
725
726static void add_echo_reference(struct aml_stream_out *out,
727 struct echo_reference_itfe *reference)
728{
729 pthread_mutex_lock(&out->lock);
730 out->echo_reference = reference;
731 pthread_mutex_unlock(&out->lock);
732}
733
734static void remove_echo_reference(struct aml_stream_out *out,
735 struct echo_reference_itfe *reference)
736{
737 pthread_mutex_lock(&out->lock);
738 if (out->echo_reference == reference) {
739 /* stop writing to echo reference */
740 reference->write(reference, NULL);
741 out->echo_reference = NULL;
742 }
743 pthread_mutex_unlock(&out->lock);
744}
745
746static void put_echo_reference(struct aml_audio_device *adev,
747 struct echo_reference_itfe *reference)
748{
749 if (adev->echo_reference != NULL &&
750 reference == adev->echo_reference) {
751 if (adev->active_output[0] != NULL) {
752 remove_echo_reference(adev->active_output[0], reference);
753 }
754 release_echo_reference(reference);
755 adev->echo_reference = NULL;
756 }
757}
758
759static struct echo_reference_itfe *get_echo_reference(struct aml_audio_device *adev,
760 audio_format_t format __unused,
761 uint32_t channel_count,
762 uint32_t sampling_rate)
763{
764 put_echo_reference(adev, adev->echo_reference);
765 if (adev->active_output[0] != NULL) {
766 struct audio_stream *stream = &adev->active_output[0]->stream.common;
767 uint32_t wr_channel_count = popcount(stream->get_channels(stream));
768 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
769
770 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
771 channel_count,
772 sampling_rate,
773 AUDIO_FORMAT_PCM_16_BIT,
774 wr_channel_count,
775 wr_sampling_rate,
776 &adev->echo_reference);
777 if (status == 0) {
778 add_echo_reference(adev->active_output[0], adev->echo_reference);
779 }
780 }
781 return adev->echo_reference;
782}
783
784static int get_playback_delay(struct aml_stream_out *out,
785 size_t frames,
786 struct echo_reference_buffer *buffer)
787{
788
789 size_t kernel_frames;
790 int status;
791 status = pcm_get_htimestamp(out->pcm, &kernel_frames, &buffer->time_stamp);
792 if (status < 0) {
793 buffer->time_stamp.tv_sec = 0;
794 buffer->time_stamp.tv_nsec = 0;
795 buffer->delay_ns = 0;
796 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
797 "setting playbackTimestamp to 0");
798 return status;
799 }
800 kernel_frames = pcm_get_buffer_size(out->pcm) - kernel_frames;
801 ALOGV("~~pcm_get_buffer_size(out->pcm)=%d", pcm_get_buffer_size(out->pcm));
802 /* adjust render time stamp with delay added by current driver buffer.
803 * Add the duration of current frame as we want the render time of the last
804 * sample being written. */
805 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames) * 1000000000) /
806 out->config.rate);
807
808 ALOGV("get_playback_delay time_stamp = [%ld].[%ld], delay_ns: [%d],"
809 "kernel_frames:[%d]", buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec,
810 buffer->delay_ns, kernel_frames);
811 return 0;
812}
813
814static uint32_t out_get_sample_rate(const struct audio_stream *stream)
815{
816 const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
817 unsigned int rate = out->hal_rate;
818 //ALOGV("out_get_sample_rate() = %d", rate);
819 return rate;
820}
821
822static int out_set_sample_rate(struct audio_stream *stream __unused, uint32_t rate __unused)
823{
824 return 0;
825}
826
827static size_t out_get_buffer_size(const struct audio_stream *stream)
828{
829 struct aml_stream_out *out = (struct aml_stream_out *)stream;
830
831 //LOGFUNC("%s(out->config.rate=%d)", __FUNCTION__, out->config.rate);
832
833 /* take resampling into account and return the closest majoring
834 * multiple of 16 frames, as audioflinger expects audio buffers to
835 * be a multiple of 16 frames
836 */
837 size_t size = out->config.period_size;
838 switch (out->hal_format) {
839 case AUDIO_FORMAT_AC3:
840 case AUDIO_FORMAT_DTS:
841 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
842 size = 4 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
843 } else {
844 size = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE / 2;
845 }
846 break;
847 case AUDIO_FORMAT_E_AC3:
848 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
849 size = 16 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
850 } else {
851 size = PERIOD_SIZE; //2*PLAYBACK_PERIOD_COUNT*PERIOD_SIZE;
852 }
853 break;
854 case AUDIO_FORMAT_DTS_HD:
855 case AUDIO_FORMAT_TRUEHD:
856 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
857 size = 16 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
858 } else {
859 size = 4 * PLAYBACK_PERIOD_COUNT * PERIOD_SIZE;
860 }
861 break;
862 case AUDIO_FORMAT_PCM:
863 default:
864 size = PERIOD_SIZE;
865 }
866 size = ((size + 15) / 16) * 16;
867 return size * audio_stream_out_frame_size((struct audio_stream_out *)stream);
868}
869
870static audio_channel_mask_t out_get_channels(const struct audio_stream *stream __unused)
871{
872 //const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
873
874 return AUDIO_CHANNEL_OUT_STEREO;
875}
876
877static audio_channel_mask_t out_get_channels_direct(const struct audio_stream *stream)
878{
879 const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
880
881 return out->hal_channel_mask;
882}
883
884static audio_format_t out_get_format(const struct audio_stream *stream __unused)
885{
886 return AUDIO_FORMAT_PCM_16_BIT;
887}
888
889static audio_format_t out_get_format_direct(const struct audio_stream *stream)
890{
891 const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
892
893 return out->hal_format;
894}
895
896static int out_set_format(struct audio_stream *stream __unused, audio_format_t format __unused)
897{
898 return 0;
899}
900
901/* must be called with hw device and output stream mutexes locked */
902static int do_output_standby(struct aml_stream_out *out)
903{
904 struct aml_audio_device *adev = out->dev;
905 int i = 0;
906
907 LOGFUNC("%s(%p)", __FUNCTION__, out);
908
909 if (!out->standby) {
910 //commit here for hwsync/mix stream hal mixer
911 //pcm_close(out->pcm);
912 //out->pcm = NULL;
913 if (out->buffer) {
914 free(out->buffer);
915 out->buffer = NULL;
916 }
917 if (out->resampler) {
918 release_resampler(out->resampler);
919 out->resampler = NULL;
920 }
921 /* stop writing to echo reference */
922 if (out->echo_reference != NULL) {
923 out->echo_reference->write(out->echo_reference, NULL);
924 out->echo_reference = NULL;
925 }
926 out->standby = 1;
927 for (i = 0; i < MAX_STREAM_NUM; i++) {
928 if (adev->active_output[i] == out) {
929 adev->active_output[i] = NULL;
930 adev->active_output_count--;
931 ALOGI("remove out (%p) from index %d\n", out, i);
932 break;
933 }
934 }
935 if (out->hw_sync_mode == 1 || adev->hwsync_output == out) {
936#if 0
937 //here to check if hwsync in pause status,if that,chear the status
938 //to release the sound card to other active output stream
939 if (out->pause_status == true && adev->active_output_count > 0) {
940 if (pcm_is_ready(out->pcm)) {
941 int r = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_PAUSE, 0);
942 if (r < 0) {
943 ALOGE("here cannot resume channel\n");
944 } else {
945 r = 0;
946 }
947 ALOGI("clear the hwsync output pause status.resume pcm\n");
948 }
949 out->pause_status = false;
950 }
951#endif
952 out->pause_status = false;
953 adev->hwsync_output = NULL;
954 ALOGI("clear hwsync_output when hwsync standby\n");
955 }
956 if (i == MAX_STREAM_NUM) {
957 ALOGE("error, not found stream in dev stream list\n");
958 }
959 /* no active output here,we can close the pcm to release the sound card now*/
960 if (adev->active_output_count == 0) {
961 if (adev->pcm) {
962 ALOGI("close pcm %p\n", adev->pcm);
963 pcm_close(adev->pcm);
964 adev->pcm = NULL;
965 }
966 out->pause_status = false;
967 }
968 }
969 return 0;
970}
971/* must be called with hw device and output stream mutexes locked */
972static int do_output_standby_direct(struct aml_stream_out *out)
973{
974 int status = 0;
975
976 ALOGI("%s,out %p", __FUNCTION__, out);
977
978 if (!out->standby) {
979 if (out->buffer) {
980 free(out->buffer);
981 out->buffer = NULL;
982 }
983
984 out->standby = 1;
985 pcm_close(out->pcm);
986 out->pcm = NULL;
987 }
988 set_codec_type(TYPE_PCM);
989 /* clear the hdmitx channel config to default */
990 if (out->multich == 6) {
991 sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "0:0");
992 }
993 return status;
994}
995static int out_standby(struct audio_stream *stream)
996{
997 LOGFUNC("%s(%p)", __FUNCTION__, stream);
998 struct aml_stream_out *out = (struct aml_stream_out *)stream;
999 int status = 0;
1000 pthread_mutex_lock(&out->dev->lock);
1001 pthread_mutex_lock(&out->lock);
1002 status = do_output_standby(out);
1003 pthread_mutex_unlock(&out->lock);
1004 pthread_mutex_unlock(&out->dev->lock);
1005 return status;
1006}
1007
1008static int out_standby_direct(struct audio_stream *stream)
1009{
1010 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1011 int status = 0;
1012
1013 ALOGI("%s(%p),out %p", __FUNCTION__, stream, out);
1014
1015 pthread_mutex_lock(&out->dev->lock);
1016 pthread_mutex_lock(&out->lock);
1017 if (!out->standby) {
1018 if (out->buffer) {
1019 free(out->buffer);
1020 out->buffer = NULL;
1021 }
1022
1023 out->standby = 1;
1024 pcm_close(out->pcm);
1025 out->pcm = NULL;
1026 }
1027 set_codec_type(TYPE_PCM);
1028 /* clear the hdmitx channel config to default */
1029 if (out->multich == 6) {
1030 sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "0:0");
1031 }
1032 pthread_mutex_unlock(&out->lock);
1033 pthread_mutex_unlock(&out->dev->lock);
1034 return status;
1035}
1036
1037static int out_dump(const struct audio_stream *stream __unused, int fd __unused)
1038{
1039 LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, fd);
1040 return 0;
1041}
1042static int
1043out_flush(struct audio_stream_out *stream)
1044{
1045 LOGFUNC("%s(%p)", __FUNCTION__, stream);
1046 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1047 struct aml_audio_device *adev = out->dev;
1048 int ret = 0;
1049 bool hwsync_lpcm = (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(out->hal_format));
1050 do_standby_func standy_func = NULL;
1051 if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT && !hwsync_lpcm) {
1052 standy_func = do_output_standby_direct;
1053 } else {
1054 standy_func = do_output_standby;
1055 }
1056 pthread_mutex_lock(&adev->lock);
1057 pthread_mutex_lock(&out->lock);
1058 if (out->pause_status == true) {
1059 // when pause status, set status prepare to avoid static pop sound
1060 ret = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_PREPARE);
1061 if (ret < 0) {
1062 ALOGE("cannot prepare pcm!");
1063 goto exit;
1064 }
1065 }
1066 standy_func(out);
1067 out->frame_write_sum = 0;
1068 out->last_frames_postion = 0;
1069exit:
1070 pthread_mutex_unlock(&adev->lock);
1071 pthread_mutex_unlock(&out->lock);
1072 return 0;
1073}
1074static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
1075{
1076 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1077 struct aml_audio_device *adev = out->dev;
1078 struct aml_stream_in *in;
1079 struct str_parms *parms;
1080 char *str;
1081 char value[32];
1082 int ret;
1083 uint val = 0;
1084 bool force_input_standby = false;
1085 bool hwsync_lpcm = (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(out->hal_format));
1086 do_standby_func standy_func = NULL;
1087 do_startup_func startup_func = NULL;
1088 if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT && !hwsync_lpcm) {
1089 standy_func = do_output_standby_direct;
1090 startup_func = start_output_stream_direct;
1091 } else {
1092 standy_func = do_output_standby;
1093 startup_func = start_output_stream;
1094 }
1095 LOGFUNC("%s(kvpairs(%s), out_device=%#x)", __FUNCTION__, kvpairs, adev->out_device);
1096 parms = str_parms_create_str(kvpairs);
1097
1098 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
1099 if (ret >= 0) {
1100 val = atoi(value);
1101 pthread_mutex_lock(&adev->lock);
1102 pthread_mutex_lock(&out->lock);
1103 if (((adev->out_device & AUDIO_DEVICE_OUT_ALL) != val) && (val != 0)) {
1104 if (1/* out == adev->active_output[0]*/) {
1105 ALOGI("audio hw select device!\n");
1106 standy_func(out);
1107 /* a change in output device may change the microphone selection */
1108 if (adev->active_input &&
1109 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1110 force_input_standby = true;
1111 }
1112 /* force standby if moving to/from HDMI */
1113 if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^
1114 (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) ||
1115 ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^
1116 (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET))) {
1117 standy_func(out);
1118 }
1119 }
1120 adev->out_device &= ~AUDIO_DEVICE_OUT_ALL;
1121 adev->out_device |= val;
1122 select_devices(adev);
1123 }
1124 pthread_mutex_unlock(&out->lock);
1125 if (force_input_standby) {
1126 in = adev->active_input;
1127 pthread_mutex_lock(&in->lock);
1128 do_input_standby(in);
1129 pthread_mutex_unlock(&in->lock);
1130 }
1131 pthread_mutex_unlock(&adev->lock);
1132 goto exit;
1133 }
1134 int sr = 0;
1135 ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_SAMPLING_RATE, &sr);
1136 if (ret >= 0) {
1137 if (sr > 0) {
1138 struct pcm_config *config = &out->config;
1139 ALOGI("audio hw sampling_rate change from %d to %d \n", config->rate, sr);
1140 config->rate = sr;
1141 pthread_mutex_lock(&adev->lock);
1142 pthread_mutex_lock(&out->lock);
1143 if (!out->standby) {
1144 standy_func(out);
1145 startup_func(out);
1146 out->standby = 0;
1147 }
1148 pthread_mutex_unlock(&adev->lock);
1149 pthread_mutex_unlock(&out->lock);
1150 }
1151 goto exit;
1152 }
1153 int frame_size = 0;
1154 ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_FRAME_COUNT, &frame_size);
1155 if (ret >= 0) {
1156 if (frame_size > 0) {
1157 struct pcm_config *config = &out->config;
1158 ALOGI("audio hw frame size change from %d to %d \n", config->period_size, frame_size);
1159 config->period_size = frame_size;
1160 pthread_mutex_lock(&adev->lock);
1161 pthread_mutex_lock(&out->lock);
1162 if (!out->standby) {
1163 standy_func(out);
1164 startup_func(out);
1165 out->standby = 0;
1166 }
1167 pthread_mutex_unlock(&adev->lock);
1168 pthread_mutex_unlock(&out->lock);
1169 }
1170 goto exit;
1171 }
1172 int EQ_parameters[5] = {0, 0, 0, 0, 0};
1173 char tmp[2];
1174 int data = 0, i = 0;
1175 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_EQ, value, sizeof(value));
1176 //ALOGI("audio effect EQ parameters are %s\n", value);
1177 if (ret >= 0) {
1178 for (i; i < 5; i++) {
1179 tmp[0] = value[2 * i];
1180 tmp[1] = value[2 * i + 1];
1181 data = atoi(tmp);
1182 EQ_parameters[i] = data - 10;
1183 }
1184 ALOGI("audio effect EQ parameters are %d,%d,%d,%d,%d\n", EQ_parameters[0],
1185 EQ_parameters[1], EQ_parameters[2], EQ_parameters[3], EQ_parameters[4]);
1186 ret = 0;
1187 HPEQ_setParameter(EQ_parameters[0], EQ_parameters[1],
1188 EQ_parameters[2], EQ_parameters[3], EQ_parameters[4]);
1189 goto exit;
1190 }
1191 int SRS_parameters[5] = {0, 0, 0, 0, 0};
1192 char tmp1[3];
1193 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_SRS, value, sizeof(value));
1194 //ALOGI("audio effect SRS parameters are %s\n", value);
1195 if (ret >= 0) {
1196 for (i; i < 5; i++) {
1197 tmp1[0] = value[3 * i];
1198 tmp1[1] = value[3 * i + 1];
1199 tmp1[2] = value[3 * i + 2];
1200 SRS_parameters[i] = atoi(tmp1);
1201 }
1202 ALOGI("audio effect SRS parameters are %d,%d,%d,%d,%d\n", SRS_parameters[0],
1203 SRS_parameters[1], SRS_parameters[2], SRS_parameters[3], SRS_parameters[4]);
1204 ret = 0;
1205 srs_setParameter(SRS_parameters);
1206 goto exit;
1207 }
1208 int SRS_gain[2] = {0, 0};
1209 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_SRS_GAIN, value, sizeof(value));
1210 if (ret >= 0) {
1211 for (i; i < 2; i++) {
1212 tmp1[0] = value[3 * i];
1213 tmp1[1] = value[3 * i + 1];
1214 tmp1[2] = value[3 * i + 2];
1215 SRS_gain[i] = atoi(tmp1);
1216 }
1217 ALOGI("audio effect SRS input/output gain are %d,%d\n", SRS_gain[0], SRS_gain[1]);
1218 ret = 0;
1219 srs_set_gain(SRS_gain[0], SRS_gain[1]);
1220 goto exit;
1221 }
1222 int SRS_switch[3] = {0, 0, 0};
1223 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_SRS_SWITCH, value, sizeof(value));
1224 if (ret >= 0) {
1225 for (i; i < 3; i++) {
1226 tmp[0] = value[2 * i];
1227 tmp[1] = value[2 * i + 1];
1228 SRS_switch[i] = atoi(tmp);
1229 }
1230 ALOGI("audio effect SRS switch %d, %d, %d\n", SRS_switch[0], SRS_switch[1], SRS_switch[2]);
1231 ret = 0;
1232 srs_surround_enable(SRS_switch[0]);
1233 srs_dialogclarity_enable(SRS_switch[1]);
1234 srs_truebass_enable(SRS_switch[2]);
1235 goto exit;
1236 }
1237 ret = str_parms_get_str(parms, "hw_av_sync", value, sizeof(value));
1238 if (ret >= 0) {
1239 int hw_sync_id = atoi(value);
1240 unsigned char sync_enable = (hw_sync_id == 12345678) ? 1 : 0;
1241 ALOGI("(%p)set hw_sync_id %d,%s hw sync mode\n",
1242 out, hw_sync_id, sync_enable ? "enable" : "disable");
1243 out->hw_sync_mode = sync_enable;
1244 out->first_apts_flag = false;
1245 pthread_mutex_lock(&adev->lock);
1246 pthread_mutex_lock(&out->lock);
1247 out->frame_write_sum = 0;
1248 out->last_frames_postion = 0;
1249 /* clear up previous playback output status */
1250 if (!out->standby) {
1251 standy_func(out);
1252 }
1253 //adev->hwsync_output = sync_enable?out:NULL;
1254 if (sync_enable) {
1255 ALOGI("init hal mixer when hwsync\n");
1256 aml_hal_mixer_init(&adev->hal_mixer);
1257 }
1258 pthread_mutex_unlock(&out->lock);
1259 pthread_mutex_unlock(&adev->lock);
1260 ret = 0;
1261 goto exit;
1262 }
1263exit:
1264 str_parms_destroy(parms);
1265 return ret;
1266}
1267
1268static char * out_get_parameters(const struct audio_stream *stream __unused, const char *keys __unused)
1269{
1270 return strdup("");
1271}
1272
1273static uint32_t out_get_latency(const struct audio_stream_out *stream)
1274{
1275 const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
1276 uint32_t whole_latency;
1277 int ret = 0;
1278 snd_pcm_sframes_t frames = 0;
1279 whole_latency = (out->config.period_size * out->config.period_count * 1000) / out->config.rate;
1280 if (!out->pcm || !pcm_is_ready(out->pcm)) {
1281 return whole_latency;
1282 }
1283 ret = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_DELAY, &frames);
1284 if (ret < 0) {
1285 return whole_latency;
1286 }
1287 return (frames * 1000) / out->config.rate/* (out->pcm->config.rate)*/;
1288}
1289
1290static int out_set_volume(struct audio_stream_out *stream, float left, float right)
1291{
1292 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1293 out->volume_l = left;
1294 out->volume_r = right;
1295 return 0;
1296}
1297
1298static int out_pause(struct audio_stream_out *stream)
1299{
1300 LOGFUNC("out_pause(%p)\n", stream);
1301
1302 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1303 struct aml_audio_device *adev = out->dev;
1304 int r = 0;
1305 pthread_mutex_lock(&adev->lock);
1306 pthread_mutex_lock(&out->lock);
1307 if (out->standby || out->pause_status == true) {
1308 goto exit;
1309 }
1310 if (out->hw_sync_mode) {
1311 adev->hwsync_output = NULL;
1312 if (adev->active_output_count > 1) {
1313 ALOGI("more than one active stream,skip alsa hw pause\n");
1314 goto exit1;
1315 }
1316 }
1317 if (pcm_is_ready(out->pcm)) {
1318 r = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_PAUSE, 1);
1319 if (r < 0) {
1320 ALOGE("cannot pause channel\n");
1321 } else {
1322 r = 0;
1323 }
1324 }
1325exit1:
1326 if (out->hw_sync_mode) {
1327 sysfs_set_sysfs_str(TSYNC_EVENT, "AUDIO_PAUSE");
1328 }
1329 out->pause_status = true;
1330exit:
1331 pthread_mutex_unlock(&adev->lock);
1332 pthread_mutex_unlock(&out->lock);
1333 return r;
1334}
1335
1336static int out_resume(struct audio_stream_out *stream)
1337{
1338 LOGFUNC("out_resume (%p)\n", stream);
1339 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1340 struct aml_audio_device *adev = out->dev;
1341 int r = 0;
1342 pthread_mutex_lock(&adev->lock);
1343 pthread_mutex_lock(&out->lock);
1344 if (out->standby || out->pause_status == false) {
1345 goto exit;
1346 }
1347 if (pcm_is_ready(out->pcm)) {
1348 r = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_PAUSE, 0);
1349 if (r < 0) {
1350 ALOGE("cannot resume channel\n");
1351 } else {
1352 r = 0;
1353 }
1354 }
1355 if (out->hw_sync_mode) {
1356 ALOGI("init hal mixer when hwsync resume\n");
1357 adev->hwsync_output = out;
1358 aml_hal_mixer_init(&adev->hal_mixer);
1359 sysfs_set_sysfs_str(TSYNC_EVENT, "AUDIO_RESUME");
1360 }
1361 out->pause_status = false;
1362exit:
1363 pthread_mutex_unlock(&adev->lock);
1364 pthread_mutex_unlock(&out->lock);
1365 return r;
1366}
1367
1368
1369static int audio_effect_process(struct audio_stream_out *stream,
1370 short* buffer, int frame_size)
1371{
1372 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1373 int output_size = frame_size << 2;
1374
1375 if (out->has_SRS_lib) {
1376 output_size = srs_process(buffer, buffer, frame_size);
1377 }
1378 if (out->has_EQ_lib) {
1379 HPEQ_process(buffer, buffer, frame_size);
1380 }
1381 if (out->has_aml_IIR_lib) {
1382 short *ptr = buffer;
1383 short data;
1384 int i;
1385 for (i = 0; i < frame_size; i++) {
1386 data = (short)aml_IIR_process((int)(*ptr), 0);
1387 *ptr++ = data;
1388 data = (short)aml_IIR_process((int)(*ptr), 1);
1389 *ptr++ = data;
1390 }
1391 }
1392 return output_size;
1393}
1394
1395static ssize_t out_write_legacy(struct audio_stream_out *stream, const void* buffer,
1396 size_t bytes)
1397{
1398 int ret = 0;
1399 size_t oldBytes = bytes;
1400 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1401 struct aml_audio_device *adev = out->dev;
1402 size_t frame_size = audio_stream_out_frame_size(stream);
1403 size_t in_frames = bytes / frame_size;
1404 size_t out_frames;
1405 bool force_input_standby = false;
1406 int16_t *in_buffer = (int16_t *)buffer;
1407 int16_t *out_buffer = in_buffer;
1408 struct aml_stream_in *in;
1409 uint ouput_len;
1410 char *data, *data_dst;
1411 volatile char *data_src;
1412 uint i, total_len;
1413 int codec_type = 0;
1414 int samesource_flag = 0;
1415 uint32_t latency_frames = 0;
1416 int need_mix = 0;
1417 short *mix_buf = NULL;
1418 unsigned char enable_dump = getprop_bool("media.audiohal.outdump");
1419 // limit HAL mixer buffer level within 200ms
1420 while ((adev->hwsync_output != NULL && adev->hwsync_output != out) &&
1421 (aml_hal_mixer_get_content(&adev->hal_mixer) > 200 * 48 * 4)) {
1422 usleep(20000);
1423 }
1424 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
1425 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
1426 * mutex
1427 */
1428 pthread_mutex_lock(&adev->lock);
1429 pthread_mutex_lock(&out->lock);
1430 //here to check whether hwsync out stream and other stream are enabled at the same time.
1431 //if that we need do the hal mixer of the two out stream.
1432 if (out->hw_sync_mode == 1) {
1433 int content_size = aml_hal_mixer_get_content(&adev->hal_mixer);
1434 //ALOGI("content_size %d\n",content_size);
1435 if (content_size > 0) {
1436 if (adev->hal_mixer.need_cache_flag == 0) {
1437 //ALOGI("need do hal mixer\n");
1438 need_mix = 1;
1439 } else if (content_size < 80 * 48 * 4) { //80 ms
1440 //ALOGI("hal mixed cached size %d\n", content_size);
1441 } else {
1442 ALOGI("start enable mix,cached size %d\n", content_size);
1443 adev->hal_mixer.need_cache_flag = 0;
1444 }
1445
1446 } else {
1447 // ALOGI("content size %d,duration %d ms\n",content_size,content_size/48/4);
1448 }
1449 }
1450 /* if hwsync output stream are enabled,write other output to a mixe buffer and sleep for the pcm duration time */
1451 if (adev->hwsync_output != NULL && adev->hwsync_output != out) {
1452 //ALOGI("dev hwsync enable,hwsync %p) cur (%p),size %d\n",adev->hwsync_output,out,bytes);
1453 // out->frame_write_sum += in_frames;
1454#if 0
1455 if (!out->standby) {
1456 do_output_standby(out);
1457 }
1458#endif
1459 if (out->standby) {
1460 ret = start_output_stream(out);
1461 if (ret != 0) {
1462 pthread_mutex_unlock(&adev->lock);
1463 ALOGE("start_output_stream failed");
1464 goto exit;
1465 }
1466 out->standby = false;
1467 }
1468 ret = -1;
1469 aml_hal_mixer_write(&adev->hal_mixer, buffer, bytes);
1470 pthread_mutex_unlock(&adev->lock);
1471 goto exit;
1472 }
1473 if (out->pause_status == true) {
1474 pthread_mutex_unlock(&adev->lock);
1475 pthread_mutex_unlock(&out->lock);
1476 ALOGI("call out_write when pause status (%p)\n", stream);
1477 return 0;
1478 }
1479 if ((out->standby) && (out->hw_sync_mode == 1)) {
1480 // todo: check timestamp header PTS discontinue for new sync point after seek
1481 out->first_apts_flag = false;
1482 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1483 out->hw_sync_header_cnt = 0;
1484 }
1485
1486#if 1
1487 if (enable_dump && out->hw_sync_mode == 0) {
1488 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1489 if (fp1) {
1490 int flen = fwrite((char *)buffer, 1, bytes, fp1);
1491 fclose(fp1);
1492 }
1493 }
1494#endif
1495
1496 if (out->hw_sync_mode == 1) {
1497 char buf[64] = {0};
1498 unsigned char *header;
1499
1500 if (out->hw_sync_state == HW_SYNC_STATE_RESYNC) {
1501 uint i = 0;
1502 uint8_t *p = (uint8_t *)buffer;
1503 while (i < bytes) {
1504 if (hwsync_header_valid(p)) {
1505 ALOGI("HWSYNC resync.%p", out);
1506 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1507 out->hw_sync_header_cnt = 0;
1508 out->first_apts_flag = false;
1509 bytes -= i;
1510 buffer += i;
1511 in_frames = bytes / frame_size;
1512 ALOGI("in_frames = %d", in_frames);
1513 in_buffer = (int16_t *)buffer;
1514 break;
1515 } else {
1516 i += 4;
1517 p += 4;
1518 }
1519 }
1520
1521 if (out->hw_sync_state == HW_SYNC_STATE_RESYNC) {
1522 ALOGI("Keep searching for HWSYNC header.%p", out);
1523 pthread_mutex_unlock(&adev->lock);
1524 goto exit;
1525 }
1526 }
1527
1528 header = (unsigned char *)buffer;
1529 }
1530 if (out->standby) {
1531 ret = start_output_stream(out);
1532 if (ret != 0) {
1533 pthread_mutex_unlock(&adev->lock);
1534 ALOGE("start_output_stream failed");
1535 goto exit;
1536 }
1537 out->standby = false;
1538 /* a change in output device may change the microphone selection */
1539 if (adev->active_input &&
1540 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1541 force_input_standby = true;
1542 }
1543 }
1544 pthread_mutex_unlock(&adev->lock);
1545#if 1
1546 /* Reduce number of channels, if necessary */
1547 if (popcount(out_get_channels(&stream->common)) >
1548 (int)out->config.channels) {
1549 unsigned int i;
1550
1551 /* Discard right channel */
1552 for (i = 1; i < in_frames; i++) {
1553 in_buffer[i] = in_buffer[i * 2];
1554 }
1555
1556 /* The frame size is now half */
1557 frame_size /= 2;
1558 }
1559#endif
1560 /* only use resampler if required */
1561 if (out->config.rate != out_get_sample_rate(&stream->common)) {
1562 out_frames = out->buffer_frames;
1563 out->resampler->resample_from_input(out->resampler,
1564 in_buffer, &in_frames,
1565 (int16_t*)out->buffer, &out_frames);
1566 in_buffer = (int16_t*)out->buffer;
1567 out_buffer = in_buffer;
1568 } else {
1569 out_frames = in_frames;
1570 }
1571 if (out->echo_reference != NULL) {
1572
1573 struct echo_reference_buffer b;
1574 b.raw = (void *)buffer;
1575 b.frame_count = in_frames;
1576 get_playback_delay(out, out_frames, &b);
1577 out->echo_reference->write(out->echo_reference, &b);
1578 }
1579
1580#if 0
1581 if (enable_dump && out->hw_sync_mode == 1) {
1582 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1583 if (fp1) {
1584 int flen = fwrite((char *)in_buffer, 1, out_frames * frame_size, fp1);
1585 LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size);
1586 fclose(fp1);
1587 } else {
1588 LOGFUNC("could not open file:/data/i2s_audio_out.pcm");
1589 }
1590 }
1591#endif
1592#if 1
1593if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
1594 codec_type = get_sysfs_int("/sys/class/audiodsp/digital_codec");
1595 //samesource_flag = get_sysfs_int("/sys/class/audiodsp/audio_samesource");
1596 if (codec_type != out->last_codec_type/*samesource_flag == 0*/ && codec_type == 0) {
1597 ALOGI("to enable same source,need reset alsa,type %d,same source flag %d \n", codec_type, samesource_flag);
1598 pcm_stop(out->pcm);
1599 }
1600 out->last_codec_type = codec_type;
1601}
1602#endif
1603 if (out->is_tv_platform == 1) {
1604 int16_t *tmp_buffer = (int16_t *)out->audioeffect_tmp_buffer;
1605 memcpy((void *)tmp_buffer, (void *)in_buffer, out_frames * 4);
1606 audio_effect_process(stream, tmp_buffer, out_frames);
1607 for (i = 0; i < out_frames; i ++) {
1608 out->tmp_buffer_8ch[8 * i] = ((int32_t)(in_buffer[2 * i])) << 16;
1609 out->tmp_buffer_8ch[8 * i + 1] = ((int32_t)(in_buffer[2 * i + 1])) << 16;
1610 out->tmp_buffer_8ch[8 * i + 2] = ((int32_t)(tmp_buffer[2 * i])) << 16;
1611 out->tmp_buffer_8ch[8 * i + 3] = ((int32_t)(tmp_buffer[2 * i + 1])) << 16;
1612 out->tmp_buffer_8ch[8 * i + 4] = 0;
1613 out->tmp_buffer_8ch[8 * i + 5] = 0;
1614 out->tmp_buffer_8ch[8 * i + 6] = 0;
1615 out->tmp_buffer_8ch[8 * i + 7] = 0;
1616 }
1617 /*if (out->frame_count < 5*1024) {
1618 memset(out->tmp_buffer_8ch, 0, out_frames * frame_size * 8);
1619 }*/
1620 ret = pcm_write(out->pcm, out->tmp_buffer_8ch, out_frames * frame_size * 8);
1621 out->frame_write_sum += out_frames;
1622 } else {
1623 if (out->hw_sync_mode) {
1624
1625 int remain = out_frames * frame_size;
1626 uint8_t *p = buffer;
1627
1628 //ALOGI(" --- out_write %d, cache cnt = %d, body = %d, hw_sync_state = %d", out_frames * frame_size, out->body_align_cnt, out->hw_sync_body_cnt, out->hw_sync_state);
1629
1630 while (remain > 0) {
1631 if (out->hw_sync_state == HW_SYNC_STATE_HEADER) {
1632 //ALOGI("Add to header buffer [%d], 0x%x", out->hw_sync_header_cnt, *p);
1633 out->hw_sync_header[out->hw_sync_header_cnt++] = *p++;
1634 remain--;
1635 if (out->hw_sync_header_cnt == 16) {
1636 int64_t pts;
1637 if (!hwsync_header_valid(&out->hw_sync_header[0])) {
1638 ALOGE("hwsync header out of sync! Resync.");
1639 out->hw_sync_state = HW_SYNC_STATE_RESYNC;
1640 break;
1641 }
1642 out->hw_sync_state = HW_SYNC_STATE_BODY;
1643 out->hw_sync_body_cnt = hwsync_header_get_size(&out->hw_sync_header[0]);
1644 out->body_align_cnt = 0;
1645 pts = hwsync_header_get_pts(&out->hw_sync_header[0]);
1646 pts = pts * 90 / 1000000;
1647#if 1
1648 char buf[64] = {0};
1649 if (out->first_apts_flag == false) {
1650 uint32_t apts_cal;
1651 ALOGI("HW SYNC new first APTS %lld,body size %d", pts, out->hw_sync_body_cnt);
1652 out->first_apts_flag = true;
1653 out->first_apts = pts;
1654 out->frame_write_sum = 0;
1655 out->last_apts_from_header = pts;
1656 sprintf(buf, "AUDIO_START:0x%llx", pts & 0xffffffff);
1657 ALOGI("tsync -> %s", buf);
1658 if (sysfs_set_sysfs_str(TSYNC_EVENT, buf) == -1) {
1659 ALOGE("set AUDIO_START failed \n");
1660 }
1661 } else {
1662 int64_t apts;
1663 uint32_t latency = out_get_latency(out) * 90;
1664 apts = (uint64_t)out->frame_write_sum * 90000 / DEFAULT_OUT_SAMPLING_RATE;
1665 apts += out->first_apts;
1666 // check PTS discontinue, which may happen when audio track switching
1667 // discontinue means PTS calculated based on first_apts and frame_write_sum
1668 // does not match the timestamp of next audio samples
1669 apts -= latency;
1670 if (apts < 0) {
1671 apts = 0;
1672 }
1673 // here we use acutal audio frame gap,not use the differece of caculated current apts with the current frame pts,
1674 //as there is a offset of audio latency from alsa.
1675 // handle audio gap 0.5~5 s
1676 unsigned two_frame_gap = (unsigned)llabs(out->last_apts_from_header - pts);
1677 if (two_frame_gap > APTS_DISCONTINUE_THRESHOLD_MIN && two_frame_gap < APTS_DISCONTINUE_THRESHOLD_MAX) {
1678 /* if (abs(pts -apts) > APTS_DISCONTINUE_THRESHOLD_MIN && abs(pts -apts) < APTS_DISCONTINUE_THRESHOLD_MAX) { */
1679 ALOGI("HW sync PTS discontinue, 0x%llx->0x%llx(from header) diff %d,last apts %llx(from header)",
1680 apts, pts, two_frame_gap, out->last_apts_from_header);
1681 //here handle the audio gap and insert zero to the alsa
1682 uint insert_size = 0;
1683 uint insert_size_total = 0;
1684 uint once_write_size = 0;
1685 insert_size = two_frame_gap/*abs(pts -apts) */ / 90 * 48 * 4;
1686 insert_size = insert_size & (~63);
1687 insert_size_total = insert_size;
1688 ALOGI("audio gap %d ms ,need insert pcm size %d\n", two_frame_gap/*abs(pts -apts) */ / 90, insert_size);
1689 char *insert_buf = (char*)malloc(8192);
1690 if (insert_buf == NULL) {
1691 ALOGE("malloc size failed \n");
1692 pthread_mutex_unlock(&adev->lock);
1693 goto exit;
1694 }
1695 memset(insert_buf, 0, 8192);
1696 if (need_mix) {
1697 mix_buf = malloc(once_write_size);
1698 if (mix_buf == NULL) {
1699 ALOGE("mix_buf malloc failed\n");
1700 free(insert_buf);
1701 pthread_mutex_unlock(&adev->lock);
1702 goto exit;
1703 }
1704 }
1705 while (insert_size > 0) {
1706 once_write_size = insert_size > 8192 ? 8192 : insert_size;
1707 if (need_mix) {
1708 pthread_mutex_lock(&adev->lock);
1709 aml_hal_mixer_read(&adev->hal_mixer, mix_buf, once_write_size);
1710 pthread_mutex_unlock(&adev->lock);
1711 memcpy(insert_buf, mix_buf, once_write_size);
1712 }
1713#if 1
1714 if (enable_dump) {
1715 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1716 if (fp1) {
1717 int flen = fwrite((char *)insert_buf, 1, once_write_size, fp1);
1718 fclose(fp1);
1719 }
1720 }
1721#endif
1722 pthread_mutex_lock(&adev->pcm_write_lock);
1723 ret = pcm_write(out->pcm, (void *) insert_buf, once_write_size);
1724 pthread_mutex_unlock(&adev->pcm_write_lock);
1725 if (ret != 0) {
1726 ALOGE("pcm write failed\n");
1727 free(insert_buf);
1728 if (mix_buf) {
1729 free(mix_buf);
1730 }
1731 pthread_mutex_unlock(&adev->lock);
1732 goto exit;
1733 }
1734 insert_size -= once_write_size;
1735 }
1736 if (mix_buf) {
1737 free(mix_buf);
1738 }
1739 mix_buf = NULL;
1740 free(insert_buf);
1741 // insert end
1742 //adev->first_apts = pts;
1743 out->frame_write_sum += insert_size_total / frame_size;
1744#if 0
1745 sprintf(buf, "AUDIO_TSTAMP_DISCONTINUITY:0x%lx", pts);
1746 if (sysfs_set_sysfs_str(TSYNC_EVENT, buf) == -1) {
1747 ALOGE("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
1748 }
1749#endif
1750 } else {
1751 int pcr = 0;
1752 if (get_sysfs_int16(TSYNC_PCRSCR, &pcr) == 0) {
1753 int32_t apts_cal = apts & 0xffffffff;
1754 if (abs(pcr - apts_cal) < SYSTIME_CORRECTION_THRESHOLD) {
1755 // do nothing
1756 } else {
1757 sprintf(buf, "0x%x", apts_cal);
1758 ALOGI("tsync -> reset pcrscr 0x%x -> 0x%x, diff %d ms,frame pts %llx,latency pts %d", pcr, apts_cal, (int)(apts_cal - pcr) / 90, pts, latency);
1759 int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, buf);
1760 if (ret_val == -1) {
1761 ALOGE("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
1762 }
1763 }
1764 }
1765 }
1766 out->last_apts_from_header = pts;
1767 }
1768#endif
1769
1770 //ALOGI("get header body_cnt = %d, pts = %lld", out->hw_sync_body_cnt, pts);
1771 }
1772 continue;
1773 } else if (out->hw_sync_state == HW_SYNC_STATE_BODY) {
1774 uint align;
1775 uint m = (out->hw_sync_body_cnt < remain) ? out->hw_sync_body_cnt : remain;
1776
1777 //ALOGI("m = %d", m);
1778
1779 // process m bytes, upto end of hw_sync_body_cnt or end of remaining our_write bytes.
1780 // within m bytes, there is no hw_sync header and all are body bytes.
1781 if (out->body_align_cnt) {
1782 // clear fragment first for alignment limitation on ALSA driver, which
1783 // requires each pcm_writing aligned at 16 frame boundaries
1784 // assuming data are always PCM16 based, so aligned at 64 bytes unit.
1785 if ((m + out->body_align_cnt) < 64) {
1786 // merge only
1787 memcpy(&out->body_align[out->body_align_cnt], p, m);
1788 p += m;
1789 remain -= m;
1790 out->body_align_cnt += m;
1791 out->hw_sync_body_cnt -= m;
1792 if (out->hw_sync_body_cnt == 0) {
1793 // end of body, research for HW SYNC header
1794 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1795 out->hw_sync_header_cnt = 0;
1796 continue;
1797 }
1798 //ALOGI("align cache add %d, cnt = %d", remain, out->body_align_cnt);
1799 break;
1800 } else {
1801 // merge-submit-continue
1802 memcpy(&out->body_align[out->body_align_cnt], p, 64 - out->body_align_cnt);
1803 p += 64 - out->body_align_cnt;
1804 remain -= 64 - out->body_align_cnt;
1805 //ALOGI("pcm_write 64, out remain %d", remain);
1806
1807 short *w_buf = (short*)&out->body_align[0];
1808
1809 if (need_mix) {
1810 short mix_buf[32];
1811 pthread_mutex_lock(&adev->lock);
1812 aml_hal_mixer_read(&adev->hal_mixer, mix_buf, 64);
1813 pthread_mutex_unlock(&adev->lock);
1814
1815 for (i = 0; i < 64 / 2 / 2; i++) {
1816 int r;
1817 r = w_buf[2 * i] * out->volume_l + mix_buf[2 * i];
1818 w_buf[2 * i] = CLIP(r);
1819 r = w_buf[2 * i + 1] * out->volume_r + mix_buf[2 * i + 1];
1820 w_buf[2 * i + 1] = CLIP(r);
1821 }
1822 } else {
1823 for (i = 0; i < 64 / 2 / 2; i++) {
1824 int r;
1825 r = w_buf[2 * i] * out->volume_l;
1826 w_buf[2 * i] = CLIP(r);
1827 r = w_buf[2 * i + 1] * out->volume_r;
1828 w_buf[2 * i + 1] = CLIP(r);
1829 }
1830 }
1831#if 1
1832 if (enable_dump) {
1833 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1834 if (fp1) {
1835 int flen = fwrite((char *)w_buf, 1, 64, fp1);
1836 fclose(fp1);
1837 }
1838 }
1839#endif
1840 pthread_mutex_lock(&adev->pcm_write_lock);
1841 ret = pcm_write(out->pcm, w_buf, 64);
1842 pthread_mutex_unlock(&adev->pcm_write_lock);
1843 out->frame_write_sum += 64 / frame_size;
1844 out->hw_sync_body_cnt -= 64 - out->body_align_cnt;
1845 out->body_align_cnt = 0;
1846 if (out->hw_sync_body_cnt == 0) {
1847 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1848 out->hw_sync_header_cnt = 0;
1849 }
1850 continue;
1851 }
1852 }
1853
1854 // process m bytes body with an empty fragment for alignment
1855 align = m & 63;
1856 if ((m - align) > 0) {
1857 short *w_buf = (short*)p;
1858 mix_buf = (short *)malloc(m - align);
1859 if (mix_buf == NULL) {
1860 ALOGE("!!!fatal err,malloc %d bytes fail\n", m - align);
1861 ret = -1;
1862 goto exit;
1863 }
1864 if (need_mix) {
1865 pthread_mutex_lock(&adev->lock);
1866 aml_hal_mixer_read(&adev->hal_mixer, mix_buf, m - align);
1867 pthread_mutex_unlock(&adev->lock);
1868 for (i = 0; i < (m - align) / 2 / 2; i++) {
1869 int r;
1870 r = w_buf[2 * i] * out->volume_l + mix_buf[2 * i];
1871 mix_buf[2 * i] = CLIP(r);
1872 r = w_buf[2 * i + 1] * out->volume_r + mix_buf[2 * i + 1];
1873 mix_buf[2 * i + 1] = CLIP(r);
1874 }
1875 } else {
1876 for (i = 0; i < (m - align) / 2 / 2; i++) {
1877
1878 int r;
1879 r = w_buf[2 * i] * out->volume_l;
1880 mix_buf[2 * i] = CLIP(r);
1881 r = w_buf[2 * i + 1] * out->volume_r;
1882 mix_buf[2 * i + 1] = CLIP(r);
1883 }
1884 }
1885#if 1
1886 if (enable_dump) {
1887 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1888 if (fp1) {
1889 int flen = fwrite((char *)mix_buf, 1, m - align, fp1);
1890 fclose(fp1);
1891 }
1892 }
1893#endif
1894 pthread_mutex_lock(&adev->pcm_write_lock);
1895 ret = pcm_write(out->pcm, mix_buf, m - align);
1896 pthread_mutex_unlock(&adev->pcm_write_lock);
1897 free(mix_buf);
1898 out->frame_write_sum += (m - align) / frame_size;
1899
1900 p += m - align;
1901 remain -= m - align;
1902 //ALOGI("pcm_write %d, remain %d", m - align, remain);
1903
1904 out->hw_sync_body_cnt -= (m - align);
1905 if (out->hw_sync_body_cnt == 0) {
1906 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1907 out->hw_sync_header_cnt = 0;
1908 continue;
1909 }
1910 }
1911
1912 if (align) {
1913 memcpy(&out->body_align[0], p, align);
1914 p += align;
1915 remain -= align;
1916 out->body_align_cnt = align;
1917 //ALOGI("align cache add %d, cnt = %d, remain = %d", align, out->body_align_cnt, remain);
1918
1919 out->hw_sync_body_cnt -= align;
1920 if (out->hw_sync_body_cnt == 0) {
1921 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1922 out->hw_sync_header_cnt = 0;
1923 continue;
1924 }
1925 }
1926 }
1927 }
1928
1929 } else {
1930 struct aml_hal_mixer *mixer = &adev->hal_mixer;
1931 pthread_mutex_lock(&adev->pcm_write_lock);
1932 if (aml_hal_mixer_get_content(mixer) > 0) {
1933 pthread_mutex_lock(&mixer->lock);
1934 if (mixer->wp > mixer->rp) {
1935 pcm_write(out->pcm, mixer->start_buf + mixer->rp, mixer->wp - mixer->rp);
1936 } else {
1937 pcm_write(out->pcm, mixer->start_buf + mixer->wp, mixer->buf_size - mixer->rp);
1938 pcm_write(out->pcm, mixer->start_buf, mixer->wp);
1939 }
1940 mixer->rp = mixer->wp = 0;
1941 pthread_mutex_unlock(&mixer->lock);
1942 }
1943 ret = pcm_write(out->pcm, out_buffer, out_frames * frame_size);
1944 pthread_mutex_unlock(&adev->pcm_write_lock);
1945 out->frame_write_sum += out_frames;
1946 }
1947 }
1948
1949exit:
1950 latency_frames = out_get_latency(out) * out->config.rate / 1000;
1951 if (out->frame_write_sum >= latency_frames) {
1952 out->last_frames_postion = out->frame_write_sum - latency_frames;
1953 } else {
1954 out->last_frames_postion = out->frame_write_sum;
1955 }
1956 pthread_mutex_unlock(&out->lock);
1957 if (ret != 0) {
1958 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
1959 out_get_sample_rate(&stream->common) * 15 / 16);
1960 }
1961
1962 if (force_input_standby) {
1963 pthread_mutex_lock(&adev->lock);
1964 if (adev->active_input) {
1965 in = adev->active_input;
1966 pthread_mutex_lock(&in->lock);
1967 do_input_standby(in);
1968 pthread_mutex_unlock(&in->lock);
1969 }
1970 pthread_mutex_unlock(&adev->lock);
1971 }
1972 return oldBytes;
1973}
1974
1975static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
1976 size_t bytes)
1977{
1978 int ret = 0;
1979 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1980 struct aml_audio_device *adev = out->dev;
1981 size_t frame_size = audio_stream_out_frame_size(stream);
1982 size_t in_frames = bytes / frame_size;
1983 size_t out_frames;
1984 bool force_input_standby = false;
1985 int16_t *in_buffer = (int16_t *)buffer;
1986 struct aml_stream_in *in;
1987 uint ouput_len;
1988 char *data, *data_dst;
1989 volatile char *data_src;
1990 uint i, total_len;
1991 int codec_type = 0;
1992 int samesource_flag = 0;
1993 uint32_t latency_frames = 0;
1994 int need_mix = 0;
1995 short *mix_buf = NULL;
1996 unsigned char enable_dump = getprop_bool("media.audiohal.outdump");
1997
1998 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
1999 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
2000 * mutex
2001 */
2002 pthread_mutex_lock(&adev->lock);
2003 pthread_mutex_lock(&out->lock);
2004
2005#if 1
2006 if (enable_dump && out->hw_sync_mode == 0) {
2007 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
2008 if (fp1) {
2009 int flen = fwrite((char *)buffer, 1, bytes, fp1);
2010 fclose(fp1);
2011 }
2012 }
2013#endif
2014
2015 if (out->standby) {
2016 ret = start_output_stream(out);
2017 if (ret != 0) {
2018 pthread_mutex_unlock(&adev->lock);
2019 ALOGE("start_output_stream failed");
2020 goto exit;
2021 }
2022 out->standby = false;
2023 /* a change in output device may change the microphone selection */
2024 if (adev->active_input &&
2025 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
2026 force_input_standby = true;
2027 }
2028 }
2029 pthread_mutex_unlock(&adev->lock);
2030#if 1
2031 /* Reduce number of channels, if necessary */
2032 if (popcount(out_get_channels(&stream->common)) >
2033 (int)out->config.channels) {
2034 unsigned int i;
2035
2036 /* Discard right channel */
2037 for (i = 1; i < in_frames; i++) {
2038 in_buffer[i] = in_buffer[i * 2];
2039 }
2040
2041 /* The frame size is now half */
2042 frame_size /= 2;
2043 }
2044#endif
2045 /* only use resampler if required */
2046 if (out->config.rate != out_get_sample_rate(&stream->common)) {
2047 out_frames = out->buffer_frames;
2048 out->resampler->resample_from_input(out->resampler,
2049 in_buffer, &in_frames,
2050 (int16_t*)out->buffer, &out_frames);
2051 in_buffer = (int16_t*)out->buffer;
2052 } else {
2053 out_frames = in_frames;
2054 }
2055 if (out->echo_reference != NULL) {
2056
2057 struct echo_reference_buffer b;
2058 b.raw = (void *)buffer;
2059 b.frame_count = in_frames;
2060 get_playback_delay(out, out_frames, &b);
2061 out->echo_reference->write(out->echo_reference, &b);
2062 }
2063
2064#if 1
2065 if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
2066 codec_type = get_sysfs_int("/sys/class/audiodsp/digital_codec");
2067 samesource_flag = get_sysfs_int("/sys/class/audiodsp/audio_samesource");
2068 if (samesource_flag == 0 && codec_type == 0) {
2069 ALOGI("to enable same source,need reset alsa,type %d,same source flag %d \n",
2070 codec_type, samesource_flag);
2071 pcm_stop(out->pcm);
2072 }
2073 }
2074#endif
2075
2076 struct aml_hal_mixer *mixer = &adev->hal_mixer;
2077 pthread_mutex_lock(&adev->pcm_write_lock);
2078 if (aml_hal_mixer_get_content(mixer) > 0) {
2079 pthread_mutex_lock(&mixer->lock);
2080 if (mixer->wp > mixer->rp) {
2081 pcm_write(out->pcm, mixer->start_buf + mixer->rp, mixer->wp - mixer->rp);
2082 } else {
2083 pcm_write(out->pcm, mixer->start_buf + mixer->wp, mixer->buf_size - mixer->rp);
2084 pcm_write(out->pcm, mixer->start_buf, mixer->wp);
2085 }
2086 mixer->rp = mixer->wp = 0;
2087 pthread_mutex_unlock(&mixer->lock);
2088 }
2089 ret = pcm_write(out->pcm, in_buffer, out_frames * frame_size);
2090 pthread_mutex_unlock(&adev->pcm_write_lock);
2091 out->frame_write_sum += out_frames;
2092
2093exit:
2094 latency_frames = out_get_latency(out) * out->config.rate / 1000;
2095 if (out->frame_write_sum >= latency_frames) {
2096 out->last_frames_postion = out->frame_write_sum - latency_frames;
2097 } else {
2098 out->last_frames_postion = out->frame_write_sum;
2099 }
2100 pthread_mutex_unlock(&out->lock);
2101 if (ret != 0) {
2102 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
2103 out_get_sample_rate(&stream->common) * 15 / 16);
2104 }
2105
2106 if (force_input_standby) {
2107 pthread_mutex_lock(&adev->lock);
2108 if (adev->active_input) {
2109 in = adev->active_input;
2110 pthread_mutex_lock(&in->lock);
2111 do_input_standby(in);
2112 pthread_mutex_unlock(&in->lock);
2113 }
2114 pthread_mutex_unlock(&adev->lock);
2115 }
2116 return bytes;
2117}
2118
2119static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buffer,
2120 size_t bytes)
2121{
2122 int ret = 0;
2123 struct aml_stream_out *out = (struct aml_stream_out *) stream;
2124 struct aml_audio_device *adev = out->dev;
2125 size_t frame_size = audio_stream_out_frame_size(stream);
2126 size_t in_frames = bytes / frame_size;
2127 bool force_input_standby = false;
2128 size_t out_frames = 0;
2129 void *buf;
2130 uint i, total_len;
2131 char prop[PROPERTY_VALUE_MAX];
2132 int codec_type = out->codec_type;
2133 int samesource_flag = 0;
2134 uint32_t latency_frames;
2135 uint64_t total_frame = 0;
2136 audio_hwsync_t *p_hwsync = &adev->hwsync;
2137 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
2138 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
2139 * mutex
2140 */
2141 out->bytes_write_total += bytes;
2142 ALOGV("out %p,dev %p out_write total size %lld\n", out, adev, out->bytes_write_total);
2143 pthread_mutex_lock(&adev->lock);
2144 pthread_mutex_lock(&out->lock);
2145 if (out->pause_status == true) {
2146 pthread_mutex_unlock(&adev->lock);
2147 pthread_mutex_unlock(&out->lock);
2148 ALOGI("call out_write when pause status,size %d,(%p)\n", bytes, out);
2149 return 0;
2150 }
2151 if ((out->standby) && adev->hw_sync_mode) {
2152 /*
2153 there are two types of raw data come to hdmi audio hal
2154 1) compressed audio data without IEC61937 wrapped
2155 2) compressed audio data with IEC61937 wrapped (typically from amlogic amadec source)
2156 we use the AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO to distiguwish the two cases.
2157 */
2158 if ((codec_type == TYPE_AC3 || codec_type == TYPE_EAC3) && (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
2159 spdifenc_init(out->pcm, out->hal_format);
2160 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
2161 }
2162 // todo: check timestamp header PTS discontinue for new sync point after seek
2163 aml_audio_hwsync_clear_status(out);
2164 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
2165 }
2166 if (out->standby) {
2167 ret = start_output_stream_direct(out);
2168 if (ret != 0) {
2169 pthread_mutex_unlock(&adev->lock);
2170 goto exit;
2171 }
2172 out->standby = 0;
2173 /* a change in output device may change the microphone selection */
2174 if (adev->active_input &&
2175 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
2176 force_input_standby = true;
2177 }
2178 }
2179 void *write_buf = NULL;
2180 int hwsync_cost_bytes = 0;
2181 if (adev->hw_sync_mode == 1) {
2182 int64_t cur_pts = 0xffffffff;
2183 int outsize = 0;
2184 char tempbuf[128];
2185 ALOGV("before aml_audio_hwsync_find_frame bytes %d\n", bytes);
2186 hwsync_cost_bytes = aml_audio_hwsync_find_frame(out, buffer, bytes, &cur_pts, &outsize);
2187 ALOGV("after aml_audio_hwsync_find_frame bytes remain %d,cost %d,outsize %d,pts %llx\n",
2188 bytes - hwsync_cost_bytes, hwsync_cost_bytes, outsize, cur_pts);
2189 //TODO,skip 3 frames after flush, to tmp fix seek pts discontinue issue.need dig more
2190 // to find out why seek ppint pts frame is remained after flush.WTF.
2191 if (out->skip_frame > 0) {
2192 out->skip_frame--;
2193 ALOGI("skip pts@%llx,cur frame size %d,cost size %d\n", cur_pts, outsize, hwsync_cost_bytes);
2194 pthread_mutex_unlock(&adev->lock);
2195 pthread_mutex_unlock(&out->lock);
2196 return hwsync_cost_bytes;
2197 }
2198 if (cur_pts != 0xffffffff && outsize > 0) {
2199 // if we got the frame body,which means we get a complete frame.
2200 //we take this frame pts as the first apts.
2201 //this can fix the seek discontinue,we got a fake frame,which maybe cached before the seek
2202 if (p_hwsync->first_apts_flag == false) {
2203 p_hwsync->first_apts_flag = true;
2204 p_hwsync->first_apts = cur_pts;
2205 sprintf(tempbuf, "AUDIO_START:0x%llx", cur_pts & 0xffffffff);
2206 ALOGI("tsync -> %s,frame size %d", tempbuf, outsize);
2207 if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
2208 ALOGE("set AUDIO_START failed \n");
2209 }
2210 } else {
2211 long apts;
2212 unsigned long latency = out_get_latency(out) * 90;
2213 // check PTS discontinue, which may happen when audio track switching
2214 // discontinue means PTS calculated based on first_apts and frame_write_sum
2215 // does not match the timestamp of next audio samples
2216 if (cur_pts > latency) {
2217 apts = (unsigned long)cur_pts - latency;
2218 } else {
2219 apts = 0;
2220 }
2221 if (0) { //abs(cur_pts -apts) > APTS_DISCONTINUE_THRESHOLD) {
2222 ALOGI("HW sync PTS discontinue, 0x%lx->0x%llx(from header) diff %llx,last apts %llx(from header)",
2223 apts, cur_pts, llabs(cur_pts - apts), p_hwsync->last_apts_from_header);
2224 p_hwsync->first_apts = cur_pts;
2225 sprintf(tempbuf, "AUDIO_TSTAMP_DISCONTINUITY:0x%llx", cur_pts);
2226 if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
2227 ALOGE("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
2228 }
2229 } else {
2230 long pcr = 0;
2231 if (get_sysfs_int16(TSYNC_PCRSCR, &pcr) == 0) {
2232 uint32_t apts_cal = apts & 0xffffffff;
2233 if (abs(pcr - apts) < SYSTIME_CORRECTION_THRESHOLD) {
2234 // do nothing
2235 }
2236 // limit the gap handle to 0.5~5 s.
2237 else if ((apts - pcr) > APTS_DISCONTINUE_THRESHOLD_MIN && (apts - pcr) < APTS_DISCONTINUE_THRESHOLD_MAX) {
2238 int insert_size = 0;
2239 int once_write_size = 0;
2240 if (out->codec_type == TYPE_EAC3) {
2241 insert_size = abs(apts - pcr) / 90 * 48 * 4 * 4;
2242 } else {
2243 insert_size = abs(apts - pcr) / 90 * 48 * 4;
2244 }
2245 insert_size = insert_size & (~63);
2246 ALOGI("audio gap %d ms ,need insert data %d\n", abs(apts - pcr) / 90, insert_size);
2247 char *insert_buf = (char*)malloc(8192);
2248 if (insert_buf == NULL) {
2249 ALOGE("malloc size failed \n");
2250 pthread_mutex_unlock(&adev->lock);
2251 goto exit;
2252 }
2253 memset(insert_buf, 0, 8192);
2254 while (insert_size > 0) {
2255 once_write_size = insert_size > 8192 ? 8192 : insert_size;
2256 ret = pcm_write(out->pcm, (void *) insert_buf, once_write_size);
2257 if (ret != 0) {
2258 ALOGE("pcm write failed\n");
2259 free(insert_buf);
2260 pthread_mutex_unlock(&adev->lock);
2261 goto exit;
2262 }
2263 insert_size -= once_write_size;
2264 }
2265 free(insert_buf);
2266 }
2267 //audio pts smaller than pcr,need skip frame.
2268 else if ((pcr - apts) > APTS_DISCONTINUE_THRESHOLD_MIN && (pcr - apts) < APTS_DISCONTINUE_THRESHOLD_MAX) {
2269 //we assume one frame duration is 32 ms for DD+(6 blocks X 1536 frames,48K sample rate)
2270 if (out->codec_type == TYPE_EAC3 && outsize > 0) {
2271 ALOGI("audio slow 0x%lx,skip frame @pts 0x%llx,pcr 0x%lx,cur apts 0x%lx\n", (pcr - apts), cur_pts, pcr, apts);
2272 out->frame_skip_sum += 1536;
2273 bytes = outsize;
2274 pthread_mutex_unlock(&adev->lock);
2275 goto exit;
2276 }
2277 } else {
2278 sprintf(tempbuf, "0x%lx", apts);
2279 ALOGI("tsync -> reset pcrscr 0x%lx -> 0x%lx, %s big,diff %d ms", pcr, apts, apts > pcr ? "apts" : "pcr", abs(apts - pcr) / 90);
2280#if 0
2281 int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, tempbuf);
2282 if (ret_val == -1) {
2283 ALOGE("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
2284 }
2285#endif
2286 }
2287 }
2288 }
2289 }
2290 }
2291 if (outsize > 0) {
2292 in_frames = outsize / frame_size;
2293 write_buf = p_hwsync->hw_sync_body_buf;
2294 } else {
2295 bytes = hwsync_cost_bytes;
2296 pthread_mutex_unlock(&adev->lock);
2297 goto exit;
2298 }
2299 } else {
2300 write_buf = (void *) buffer;
2301 }
2302 pthread_mutex_unlock(&adev->lock);
2303 out_frames = in_frames;
2304 buf = (void *) write_buf;
2305 if (getprop_bool("media.hdmihal.outdump")) {
2306 FILE *fp1 = fopen("/data/tmp/hdmi_audio_out.pcm", "a+");
2307 if (fp1) {
2308 int flen = fwrite((char *)buffer, 1, out_frames * frame_size, fp1);
2309 LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size);
2310 fclose(fp1);
2311 } else {
2312 LOGFUNC("could not open file:/data/hdmi_audio_out.pcm");
2313 }
2314 }
2315 if (codec_type_is_raw_data(out->codec_type) && !(out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
2316 //here to do IEC61937 pack
2317 ALOGV("IEC61937 write size %d,hw_sync_mode %d,flag %x\n", out_frames * frame_size, adev->hw_sync_mode, out->flags);
2318 if (out->codec_type > 0) {
2319 // compressed audio DD/DD+
2320 bytes = spdifenc_write((void *) buf, out_frames * frame_size);
2321 //need return actual size of this burst write
2322 if (adev->hw_sync_mode == 1) {
2323 bytes = hwsync_cost_bytes;
2324 }
2325 ALOGV("spdifenc_write return %d\n", bytes);
2326 if (out->codec_type == TYPE_EAC3) {
2327 out->frame_write_sum = spdifenc_get_total() / 16 + out->spdif_enc_init_frame_write_sum;
2328 } else {
2329 out->frame_write_sum = spdifenc_get_total() / 4 + out->spdif_enc_init_frame_write_sum;
2330 }
2331 ALOGV("out %p,spdifenc_get_total() / 4 %lld\n", out, spdifenc_get_total() / 16);
2332 }
2333 goto exit;
2334 }
2335 if (!out->standby) {
2336 if (out->multich == 8) {
2337 int *p32 = NULL;
2338 short *p16 = (short *) buf;
2339 short *p16_temp;
2340 int i, NumSamps;
2341 NumSamps = out_frames * frame_size / sizeof(short);
2342 p32 = malloc(NumSamps * sizeof(int));
2343 if (p32 != NULL) {
2344 //here to swap the channnl data here
2345 //actual now:L,missing,R,RS,RRS,,LS,LRS,missing
2346 //expect L,C,R,RS,RRS,LRS,LS,LFE (LFE comes from to center)
2347 //actual audio data layout L,R,C,none/LFE,LRS,RRS,LS,RS
2348 p16_temp = (short *) p32;
2349 for (i = 0; i < NumSamps; i = i + 8) {
2350 p16_temp[0 + i]/*L*/ = p16[0 + i];
2351 p16_temp[1 + i]/*R*/ = p16[1 + i];
2352 p16_temp[2 + i] /*LFE*/ = p16[3 + i];
2353 p16_temp[3 + i] /*C*/ = p16[2 + i];
2354 p16_temp[4 + i] /*LS*/ = p16[6 + i];
2355 p16_temp[5 + i] /*RS*/ = p16[7 + i];
2356 p16_temp[6 + i] /*LRS*/ = p16[4 + i];
2357 p16_temp[7 + i]/*RRS*/ = p16[5 + i];
2358 }
2359 memcpy(p16, p16_temp, NumSamps * sizeof(short));
2360 for (i = 0; i < NumSamps; i++) { //suppose 16bit/8ch PCM
2361 p32[i] = p16[i] << 16;
2362 }
2363 ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
2364 free(p32);
2365 }
2366 } else if (out->multich == 6) {
2367 int *p32 = NULL;
2368 short *p16 = (short *) buf;
2369 short *p16_temp;
2370 int i, j, NumSamps, real_samples;
2371 real_samples = out_frames * frame_size / sizeof(short);
2372 NumSamps = real_samples * 8 / 6;
2373 //ALOGI("6ch to 8 ch real %d, to %d,bytes %d,frame size %d\n",real_samples,NumSamps,bytes,frame_size);
2374 p32 = malloc(NumSamps * sizeof(int));
2375 if (p32 != NULL) {
2376 p16_temp = (short *) p32;
2377 for (i = 0; i < real_samples; i = i + 6) {
2378 p16_temp[0 + i]/*L*/ = p16[0 + i];
2379 p16_temp[1 + i]/*R*/ = p16[1 + i];
2380 p16_temp[2 + i] /*LFE*/ = p16[3 + i];
2381 p16_temp[3 + i] /*C*/ = p16[2 + i];
2382 p16_temp[4 + i] /*LS*/ = p16[4 + i];
2383 p16_temp[5 + i] /*RS*/ = p16[5 + i];
2384 }
2385 memcpy(p16, p16_temp, real_samples * sizeof(short));
2386 memset(p32, 0, NumSamps * sizeof(int));
2387 for (i = 0, j = 0; j < NumSamps; i = i + 6, j = j + 8) { //suppose 16bit/8ch PCM
2388 p32[j] = p16[i] << 16;
2389 p32[j + 1] = p16[i + 1] << 16;
2390 p32[j + 2] = p16[i + 2] << 16;
2391 p32[j + 3] = p16[i + 3] << 16;
2392 p32[j + 4] = p16[i + 4] << 16;
2393 p32[j + 5] = p16[i + 5] << 16;
2394 }
2395 ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
2396 free(p32);
2397 }
2398 } else {
2399#if 0
2400 codec_type =
2401 get_sysfs_int("/sys/class/audiodsp/digital_codec");
2402 samesource_flag =
2403 get_sysfs_int("/sys/class/audiodsp/audio_samesource");
2404 if (out->last_codec_type > 0 && codec_type != out->last_codec_type) {
2405 samesource_flag = 1;
2406 }
2407 if (samesource_flag == 1 && codec_type) {
2408 ALOGI
2409 ("to disable same source,need reset alsa,last %d,type %d,same source flag %d ,\n",
2410 out->last_codec_type, codec_type, samesource_flag);
2411 out->last_codec_type = codec_type;
2412 pcm_stop(out->pcm);
2413 }
2414#endif
2415 ALOGV("write size %d\n", out_frames * frame_size);
2416 ret = pcm_write(out->pcm, (void *) buf, out_frames * frame_size);
2417 if (ret == 0) {
2418 out->frame_write_sum += out_frames;
2419 }
2420 }
2421 }
2422exit:
2423 total_frame = out->frame_write_sum + out->frame_skip_sum;
2424 latency_frames = out_get_latency(out) * out->config.rate / 1000;
2425 if (total_frame >= latency_frames) {
2426 out->last_frames_postion = total_frame - latency_frames;
2427 } else {
2428 out->last_frames_postion = total_frame;
2429 }
2430 pthread_mutex_unlock(&out->lock);
2431 if (ret != 0) {
2432 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
2433 out_get_sample_rate(&stream->common));
2434 }
2435 return bytes;
2436}
2437
2438static ssize_t out_write_tv(struct audio_stream_out *stream, const void* buffer,
2439 size_t bytes)
2440{
2441 // TV temporarily use legacy out write.
2442 /* TODO: add TV platform specific write here */
2443 return out_write_legacy(stream, buffer, bytes);
2444}
2445
2446static int out_get_render_position(const struct audio_stream_out *stream,
2447 uint32_t *dsp_frames)
2448{
2449 struct aml_stream_out *out = (struct aml_stream_out *)stream;
2450 uint64_t dsp_frame_int64 = 0;
2451 *dsp_frames = out->last_frames_postion;
2452 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
2453 dsp_frame_int64 = out->last_frames_postion / out->raw_61937_frame_size;
2454 *dsp_frames = (uint32_t)(dsp_frame_int64 & 0xffffffff);
2455 if (out->last_dsp_frame > *dsp_frames) {
2456 ALOGI("maybe uint32_t wraparound,print something,last %u,now %u", out->last_dsp_frame, *dsp_frames);
2457 ALOGI("wraparound,out_get_render_position return %u,playback time %llu ms,sr %d\n", *dsp_frames,
2458 out->last_frames_postion * 1000 / out->raw_61937_frame_size / out->config.rate, out->config.rate);
2459
2460 }
2461 }
2462 ALOGV("out_get_render_position %d\n", *dsp_frames);
2463 return 0;
2464}
2465
2466static int out_add_audio_effect(const struct audio_stream *stream __unused, effect_handle_t effect __unused)
2467{
2468 return 0;
2469}
2470
2471static int out_remove_audio_effect(const struct audio_stream *stream __unused, effect_handle_t effect __unused)
2472{
2473 return 0;
2474}
2475static int out_get_next_write_timestamp(const struct audio_stream_out *stream __unused,
2476 int64_t *timestamp __unused)
2477{
2478 return -EINVAL;
2479}
2480
2481//actually maybe it be not useful now except pass CTS_TEST:
2482// run cts -c android.media.cts.AudioTrackTest -m testGetTimestamp
2483static int out_get_presentation_position(const struct audio_stream_out *stream, uint64_t *frames, struct timespec *timestamp)
2484{
2485 struct aml_stream_out *out = (struct aml_stream_out *)stream;
2486 if (frames != NULL) {
2487 *frames = out->last_frames_postion;
2488 }
2489
2490 if (timestamp != NULL) {
2491 clock_gettime(CLOCK_MONOTONIC, timestamp);
2492 }
2493 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
2494 *frames = out->last_frames_postion / out->raw_61937_frame_size;
2495 }
2496 ALOGV("out_get_presentation_position %lld\n", *frames);
2497
2498 return 0;
2499}
2500static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
2501 struct resampler_buffer* buffer);
2502static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2503 struct resampler_buffer* buffer);
2504
2505
2506/** audio_stream_in implementation **/
2507
2508/* must be called with hw device and input stream mutexes locked */
2509static int start_input_stream(struct aml_stream_in *in)
2510{
2511 int ret = 0;
2512 unsigned int card = CARD_AMLOGIC_BOARD;
2513 unsigned int port = PORT_I2S;
2514
2515 struct aml_audio_device *adev = in->dev;
2516 LOGFUNC("%s(need_echo_reference=%d, channels=%d, rate=%d, requested_rate=%d, mode= %d)",
2517 __FUNCTION__, in->need_echo_reference, in->config.channels, in->config.rate, in->requested_rate, adev->mode);
2518 adev->active_input = in;
2519
2520 if (adev->mode != AUDIO_MODE_IN_CALL) {
2521 adev->in_device &= ~AUDIO_DEVICE_IN_ALL;
2522 adev->in_device |= in->device;
2523 select_devices(adev);
2524 }
2525 card = get_aml_card();
2526
2527 ALOGV("%s(in->requested_rate=%d, in->config.rate=%d)",
2528 __FUNCTION__, in->requested_rate, in->config.rate);
2529 if (adev->in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2530 port = PORT_PCM;
2531 } else if (getprop_bool("sys.hdmiIn.Capture")) {
2532 port = PORT_SPDIF;
2533 } else {
2534 port = PORT_I2S;
2535 }
2536 LOGFUNC("*%s, open card(%d) port(%d)-------", __FUNCTION__, card, port);
2537 in->config.period_size = CAPTURE_PERIOD_SIZE;
2538 if (in->need_echo_reference && in->echo_reference == NULL) {
2539 in->echo_reference = get_echo_reference(adev,
2540 AUDIO_FORMAT_PCM_16_BIT,
2541 in->config.channels,
2542 in->requested_rate);
2543 LOGFUNC("%s(after get_echo_ref.... now in->echo_reference = %p)", __FUNCTION__, in->echo_reference);
2544 }
2545 /* this assumes routing is done previously */
2546 in->pcm = pcm_open(card, port, PCM_IN, &in->config);
2547 if (!pcm_is_ready(in->pcm)) {
2548 ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm));
2549 pcm_close(in->pcm);
2550 adev->active_input = NULL;
2551 return -ENOMEM;
2552 }
2553 ALOGD("pcm_open in: card(%d), port(%d)", card, port);
2554
2555 /* if no supported sample rate is available, use the resampler */
2556 if (in->resampler) {
2557 in->resampler->reset(in->resampler);
2558 in->frames_in = 0;
2559 }
2560 return 0;
2561}
2562
2563static uint32_t in_get_sample_rate(const struct audio_stream *stream)
2564{
2565 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2566
2567 return in->requested_rate;
2568}
2569
2570static int in_set_sample_rate(struct audio_stream *stream __unused, uint32_t rate __unused)
2571{
2572 return 0;
2573}
2574
2575static size_t in_get_buffer_size(const struct audio_stream *stream)
2576{
2577 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2578
2579 return get_input_buffer_size(in->config.period_size, in->config.rate,
2580 AUDIO_FORMAT_PCM_16_BIT,
2581 in->config.channels);
2582}
2583
2584static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
2585{
2586 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2587
2588 if (in->config.channels == 1) {
2589 return AUDIO_CHANNEL_IN_MONO;
2590 } else {
2591 return AUDIO_CHANNEL_IN_STEREO;
2592 }
2593}
2594
2595static audio_format_t in_get_format(const struct audio_stream *stream __unused)
2596{
2597 return AUDIO_FORMAT_PCM_16_BIT;
2598}
2599
2600static int in_set_format(struct audio_stream *stream __unused, audio_format_t format __unused)
2601{
2602 return 0;
2603}
2604
2605/* must be called with hw device and input stream mutexes locked */
2606static int do_input_standby(struct aml_stream_in *in)
2607{
2608 struct aml_audio_device *adev = in->dev;
2609
2610 LOGFUNC("%s(%p)", __FUNCTION__, in);
2611 if (!in->standby) {
2612 pcm_close(in->pcm);
2613 in->pcm = NULL;
2614
2615 adev->active_input = 0;
2616 if (adev->mode != AUDIO_MODE_IN_CALL) {
2617 adev->in_device &= ~AUDIO_DEVICE_IN_ALL;
2618 //select_input_device(adev);
2619 }
2620
2621 if (in->echo_reference != NULL) {
2622 /* stop reading from echo reference */
2623 in->echo_reference->read(in->echo_reference, NULL);
2624 put_echo_reference(adev, in->echo_reference);
2625 in->echo_reference = NULL;
2626 }
2627
2628 in->standby = 1;
2629#if 0
2630 LOGFUNC("%s : output_standby=%d,input_standby=%d",
2631 __FUNCTION__, output_standby, input_standby);
2632 if (output_standby && input_standby) {
2633 reset_mixer_state(adev->ar);
2634 update_mixer_state(adev->ar);
2635 }
2636#endif
2637 }
2638 return 0;
2639}
2640static int in_standby(struct audio_stream *stream)
2641{
2642 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2643 int status;
2644 LOGFUNC("%s(%p)", __FUNCTION__, stream);
2645
2646 pthread_mutex_lock(&in->dev->lock);
2647 pthread_mutex_lock(&in->lock);
2648 status = do_input_standby(in);
2649 pthread_mutex_unlock(&in->lock);
2650 pthread_mutex_unlock(&in->dev->lock);
2651 return status;
2652}
2653
2654static int in_dump(const struct audio_stream *stream __unused, int fd __unused)
2655{
2656 return 0;
2657}
2658
2659static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
2660{
2661 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2662 struct aml_audio_device *adev = in->dev;
2663 struct str_parms *parms;
2664 char *str;
2665 char value[32];
2666 int ret, val = 0;
2667 bool do_standby = false;
2668
2669 LOGFUNC("%s(%p, %s)", __FUNCTION__, stream, kvpairs);
2670 parms = str_parms_create_str(kvpairs);
2671
2672 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
2673
2674 pthread_mutex_lock(&adev->lock);
2675 pthread_mutex_lock(&in->lock);
2676 if (ret >= 0) {
2677 val = atoi(value);
2678 /* no audio source uses val == 0 */
2679 if ((in->source != val) && (val != 0)) {
2680 in->source = val;
2681 do_standby = true;
2682 }
2683 }
2684
2685 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2686 if (ret >= 0) {
2687 val = atoi(value) & ~AUDIO_DEVICE_BIT_IN;
2688 if ((in->device != val) && (val != 0)) {
2689 in->device = val;
2690 do_standby = true;
2691 }
2692 }
2693
2694 if (do_standby) {
2695 do_input_standby(in);
2696 }
2697 pthread_mutex_unlock(&in->lock);
2698 pthread_mutex_unlock(&adev->lock);
2699
2700 int framesize = 0;
2701 ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_FRAME_COUNT, &framesize);
2702
2703 if (ret >= 0) {
2704 if (framesize > 0) {
2705 ALOGI("Reset audio input hw frame size from %d to %d\n",
2706 in->config.period_size * in->config.period_count, framesize);
2707 in->config.period_size = framesize / in->config.period_count;
2708 pthread_mutex_lock(&adev->lock);
2709 pthread_mutex_lock(&in->lock);
2710
2711 if (!in->standby && (in == adev->active_input)) {
2712 do_input_standby(in);
2713 start_input_stream(in);
2714 in->standby = 0;
2715 }
2716
2717 pthread_mutex_unlock(&in->lock);
2718 pthread_mutex_unlock(&adev->lock);
2719 }
2720 }
2721
2722 str_parms_destroy(parms);
2723 return ret;
2724}
2725
2726static char * in_get_parameters(const struct audio_stream *stream __unused,
2727 const char *keys __unused)
2728{
2729 return strdup("");
2730}
2731
2732static int in_set_gain(struct audio_stream_in *stream __unused, float gain __unused)
2733{
2734 return 0;
2735}
2736
2737static void get_capture_delay(struct aml_stream_in *in,
2738 size_t frames __unused,
2739 struct echo_reference_buffer *buffer)
2740{
2741 /* read frames available in kernel driver buffer */
2742 size_t kernel_frames;
2743 struct timespec tstamp;
2744 long buf_delay;
2745 long rsmp_delay;
2746 long kernel_delay;
2747 long delay_ns;
2748 int rsmp_mul = in->config.rate / VX_NB_SAMPLING_RATE;
2749 if (pcm_get_htimestamp(in->pcm, &kernel_frames, &tstamp) < 0) {
2750 buffer->time_stamp.tv_sec = 0;
2751 buffer->time_stamp.tv_nsec = 0;
2752 buffer->delay_ns = 0;
2753 ALOGW("read get_capture_delay(): pcm_htimestamp error");
2754 return;
2755 }
2756
2757 /* read frames available in audio HAL input buffer
2758 * add number of frames being read as we want the capture time of first sample
2759 * in current buffer */
2760 buf_delay = (long)(((int64_t)(in->frames_in + in->proc_frames_in * rsmp_mul) * 1000000000)
2761 / in->config.rate);
2762 /* add delay introduced by resampler */
2763 rsmp_delay = 0;
2764 if (in->resampler) {
2765 rsmp_delay = in->resampler->delay_ns(in->resampler);
2766 }
2767
2768 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
2769
2770 delay_ns = kernel_delay + buf_delay + rsmp_delay;
2771
2772 buffer->time_stamp = tstamp;
2773 buffer->delay_ns = delay_ns;
2774 /*ALOGV("get_capture_delay time_stamp = [%ld].[%ld], delay_ns: [%d],"
2775 " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], "
2776 "in->frames_in:[%d], in->proc_frames_in:[%d], frames:[%d]",
2777 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns,
2778 kernel_delay, buf_delay, rsmp_delay, kernel_frames,
2779 in->frames_in, in->proc_frames_in, frames);*/
2780
2781}
2782
2783static int32_t update_echo_reference(struct aml_stream_in *in, size_t frames)
2784{
2785 struct echo_reference_buffer b;
2786 b.delay_ns = 0;
2787
2788 ALOGV("update_echo_reference, frames = [%d], in->ref_frames_in = [%d], "
2789 "b.frame_count = [%d]", frames, in->ref_frames_in, frames - in->ref_frames_in);
2790 if (in->ref_frames_in < frames) {
2791 if (in->ref_buf_size < frames) {
2792 in->ref_buf_size = frames;
2793 in->ref_buf = (int16_t *)realloc(in->ref_buf,
2794 in->ref_buf_size * in->config.channels * sizeof(int16_t));
2795 }
2796
2797 b.frame_count = frames - in->ref_frames_in;
2798 b.raw = (void *)(in->ref_buf + in->ref_frames_in * in->config.channels);
2799
2800 get_capture_delay(in, frames, &b);
2801 LOGFUNC("update_echo_reference return ::b.delay_ns=%d", b.delay_ns);
2802
2803 if (in->echo_reference->read(in->echo_reference, &b) == 0) {
2804 in->ref_frames_in += b.frame_count;
2805 ALOGV("update_echo_reference: in->ref_frames_in:[%d], "
2806 "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]",
2807 in->ref_frames_in, in->ref_buf_size, frames, b.frame_count);
2808 }
2809 } else {
2810 ALOGW("update_echo_reference: NOT enough frames to read ref buffer");
2811 }
2812 return b.delay_ns;
2813}
2814
2815static int set_preprocessor_param(effect_handle_t handle,
2816 effect_param_t *param)
2817{
2818 uint32_t size = sizeof(int);
2819 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
2820 param->vsize;
2821
2822 int status = (*handle)->command(handle,
2823 EFFECT_CMD_SET_PARAM,
2824 sizeof(effect_param_t) + psize,
2825 param,
2826 &size,
2827 &param->status);
2828 if (status == 0) {
2829 status = param->status;
2830 }
2831
2832 return status;
2833}
2834
2835static int set_preprocessor_echo_delay(effect_handle_t handle,
2836 int32_t delay_us)
2837{
2838 uint32_t buf[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
2839 effect_param_t *param = (effect_param_t *)buf;
2840
2841 param->psize = sizeof(uint32_t);
2842 param->vsize = sizeof(uint32_t);
2843 *(uint32_t *)param->data = AEC_PARAM_ECHO_DELAY;
2844 *((int32_t *)param->data + 1) = delay_us;
2845
2846 return set_preprocessor_param(handle, param);
2847}
2848
2849static void push_echo_reference(struct aml_stream_in *in, size_t frames)
2850{
2851 /* read frames from echo reference buffer and update echo delay
2852 * in->ref_frames_in is updated with frames available in in->ref_buf */
2853 int32_t delay_us = update_echo_reference(in, frames) / 1000;
2854 int i;
2855 audio_buffer_t buf;
2856
2857 if (in->ref_frames_in < frames) {
2858 frames = in->ref_frames_in;
2859 }
2860
2861 buf.frameCount = frames;
2862 buf.raw = in->ref_buf;
2863
2864 for (i = 0; i < in->num_preprocessors; i++) {
2865 if ((*in->preprocessors[i])->process_reverse == NULL) {
2866 continue;
2867 }
2868
2869 (*in->preprocessors[i])->process_reverse(in->preprocessors[i],
2870 &buf,
2871 NULL);
2872 set_preprocessor_echo_delay(in->preprocessors[i], delay_us);
2873 }
2874
2875 in->ref_frames_in -= buf.frameCount;
2876 if (in->ref_frames_in) {
2877 memcpy(in->ref_buf,
2878 in->ref_buf + buf.frameCount * in->config.channels,
2879 in->ref_frames_in * in->config.channels * sizeof(int16_t));
2880 }
2881}
2882
2883static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
2884 struct resampler_buffer* buffer)
2885{
2886 struct aml_stream_in *in;
2887
2888 if (buffer_provider == NULL || buffer == NULL) {
2889 return -EINVAL;
2890 }
2891
2892 in = (struct aml_stream_in *)((char *)buffer_provider -
2893 offsetof(struct aml_stream_in, buf_provider));
2894
2895 if (in->pcm == NULL) {
2896 buffer->raw = NULL;
2897 buffer->frame_count = 0;
2898 in->read_status = -ENODEV;
2899 return -ENODEV;
2900 }
2901
2902 if (in->frames_in == 0) {
2903 in->read_status = pcm_read(in->pcm, (void*)in->buffer,
2904 in->config.period_size * audio_stream_in_frame_size(&in->stream));
2905 if (in->read_status != 0) {
2906 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
2907 buffer->raw = NULL;
2908 buffer->frame_count = 0;
2909 return in->read_status;
2910 }
2911 in->frames_in = in->config.period_size;
2912 }
2913
2914 buffer->frame_count = (buffer->frame_count > in->frames_in) ?
2915 in->frames_in : buffer->frame_count;
2916 buffer->i16 = in->buffer + (in->config.period_size - in->frames_in) *
2917 in->config.channels;
2918
2919 return in->read_status;
2920
2921}
2922
2923static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2924 struct resampler_buffer* buffer)
2925{
2926 struct aml_stream_in *in;
2927
2928 if (buffer_provider == NULL || buffer == NULL) {
2929 return;
2930 }
2931
2932 in = (struct aml_stream_in *)((char *)buffer_provider -
2933 offsetof(struct aml_stream_in, buf_provider));
2934
2935 in->frames_in -= buffer->frame_count;
2936}
2937
2938/* read_frames() reads frames from kernel driver, down samples to capture rate
2939 * if necessary and output the number of frames requested to the buffer specified */
2940static ssize_t read_frames(struct aml_stream_in *in, void *buffer, ssize_t frames)
2941{
2942 ssize_t frames_wr = 0;
2943
2944 while (frames_wr < frames) {
2945 size_t frames_rd = frames - frames_wr;
2946 if (in->resampler != NULL) {
2947 in->resampler->resample_from_provider(in->resampler,
2948 (int16_t *)((char *)buffer +
2949 frames_wr * audio_stream_in_frame_size(&in->stream)),
2950 &frames_rd);
2951 } else {
2952 struct resampler_buffer buf = {
2953 { .raw = NULL, },
2954 .frame_count = frames_rd,
2955 };
2956 get_next_buffer(&in->buf_provider, &buf);
2957 if (buf.raw != NULL) {
2958 memcpy((char *)buffer +
2959 frames_wr * audio_stream_in_frame_size(&in->stream),
2960 buf.raw,
2961 buf.frame_count * audio_stream_in_frame_size(&in->stream));
2962 frames_rd = buf.frame_count;
2963 }
2964 release_buffer(&in->buf_provider, &buf);
2965 }
2966 /* in->read_status is updated by getNextBuffer() also called by
2967 * in->resampler->resample_from_provider() */
2968 if (in->read_status != 0) {
2969 return in->read_status;
2970 }
2971
2972 frames_wr += frames_rd;
2973 }
2974 return frames_wr;
2975}
2976
2977/* process_frames() reads frames from kernel driver (via read_frames()),
2978 * calls the active audio pre processings and output the number of frames requested
2979 * to the buffer specified */
2980static ssize_t process_frames(struct aml_stream_in *in, void* buffer, ssize_t frames)
2981{
2982 ssize_t frames_wr = 0;
2983 audio_buffer_t in_buf;
2984 audio_buffer_t out_buf;
2985 int i;
2986
2987 //LOGFUNC("%s(%d, %p, %ld)", __FUNCTION__, in->num_preprocessors, buffer, frames);
2988 while (frames_wr < frames) {
2989 /* first reload enough frames at the end of process input buffer */
2990 if (in->proc_frames_in < (size_t)frames) {
2991 ssize_t frames_rd;
2992
2993 if (in->proc_buf_size < (size_t)frames) {
2994 in->proc_buf_size = (size_t)frames;
2995 in->proc_buf = (int16_t *)realloc(in->proc_buf,
2996 in->proc_buf_size *
2997 in->config.channels * sizeof(int16_t));
2998 ALOGV("process_frames(): in->proc_buf %p size extended to %d frames",
2999 in->proc_buf, in->proc_buf_size);
3000 }
3001 frames_rd = read_frames(in,
3002 in->proc_buf +
3003 in->proc_frames_in * in->config.channels,
3004 frames - in->proc_frames_in);
3005 if (frames_rd < 0) {
3006 frames_wr = frames_rd;
3007 break;
3008 }
3009 in->proc_frames_in += frames_rd;
3010 }
3011
3012 if (in->echo_reference != NULL) {
3013 push_echo_reference(in, in->proc_frames_in);
3014 }
3015
3016 /* in_buf.frameCount and out_buf.frameCount indicate respectively
3017 * the maximum number of frames to be consumed and produced by process() */
3018 in_buf.frameCount = in->proc_frames_in;
3019 in_buf.s16 = in->proc_buf;
3020 out_buf.frameCount = frames - frames_wr;
3021 out_buf.s16 = (int16_t *)buffer + frames_wr * in->config.channels;
3022
3023 for (i = 0; i < in->num_preprocessors; i++)
3024 (*in->preprocessors[i])->process(in->preprocessors[i],
3025 &in_buf,
3026 &out_buf);
3027
3028 /* process() has updated the number of frames consumed and produced in
3029 * in_buf.frameCount and out_buf.frameCount respectively
3030 * move remaining frames to the beginning of in->proc_buf */
3031 in->proc_frames_in -= in_buf.frameCount;
3032 if (in->proc_frames_in) {
3033 memcpy(in->proc_buf,
3034 in->proc_buf + in_buf.frameCount * in->config.channels,
3035 in->proc_frames_in * in->config.channels * sizeof(int16_t));
3036 }
3037
3038 /* if not enough frames were passed to process(), read more and retry. */
3039 if (out_buf.frameCount == 0) {
3040 continue;
3041 }
3042
3043 frames_wr += out_buf.frameCount;
3044 }
3045 return frames_wr;
3046}
3047
3048static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
3049 size_t bytes)
3050{
3051 int ret = 0;
3052 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3053 struct aml_audio_device *adev = in->dev;
3054 size_t frames_rq = bytes / audio_stream_in_frame_size(&in->stream);
3055
3056 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
3057 * on the input stream mutex - e.g. executing select_mode() while holding the hw device
3058 * mutex
3059 */
3060 pthread_mutex_lock(&adev->lock);
3061 pthread_mutex_lock(&in->lock);
3062 if (in->standby) {
3063 ret = start_input_stream(in);
3064 if (ret == 0) {
3065 in->standby = 0;
3066 }
3067 }
3068 pthread_mutex_unlock(&adev->lock);
3069
3070 if (ret < 0) {
3071 goto exit;
3072 }
3073
3074 if (in->num_preprocessors != 0) {
3075 ret = process_frames(in, buffer, frames_rq);
3076 } else if (in->resampler != NULL) {
3077 ret = read_frames(in, buffer, frames_rq);
3078 } else {
3079 ret = pcm_read(in->pcm, buffer, bytes);
3080 }
3081
3082 if (ret > 0) {
3083 ret = 0;
3084 }
3085
3086 if (ret == 0 && adev->mic_mute) {
3087 memset(buffer, 0, bytes);
3088 }
3089
3090#if 0
3091 FILE *dump_fp = NULL;
3092
3093 dump_fp = fopen("/data/audio_in.pcm", "a+");
3094 if (dump_fp != NULL) {
3095 fwrite(buffer, bytes, 1, dump_fp);
3096 fclose(dump_fp);
3097 } else {
3098 ALOGW("[Error] Can't write to /data/dump_in.pcm");
3099 }
3100#endif
3101
3102exit:
3103 if (ret < 0)
3104 usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
3105 in_get_sample_rate(&stream->common));
3106
3107 pthread_mutex_unlock(&in->lock);
3108 return bytes;
3109
3110}
3111
3112static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream __unused)
3113{
3114 return 0;
3115}
3116
3117static int in_add_audio_effect(const struct audio_stream *stream,
3118 effect_handle_t effect)
3119{
3120 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3121 int status;
3122 effect_descriptor_t desc;
3123
3124 pthread_mutex_lock(&in->dev->lock);
3125 pthread_mutex_lock(&in->lock);
3126 if (in->num_preprocessors >= MAX_PREPROCESSORS) {
3127 status = -ENOSYS;
3128 goto exit;
3129 }
3130
3131 status = (*effect)->get_descriptor(effect, &desc);
3132 if (status != 0) {
3133 goto exit;
3134 }
3135
3136 in->preprocessors[in->num_preprocessors++] = effect;
3137
3138 if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3139 in->need_echo_reference = true;
3140 do_input_standby(in);
3141 }
3142
3143exit:
3144
3145 pthread_mutex_unlock(&in->lock);
3146 pthread_mutex_unlock(&in->dev->lock);
3147 return status;
3148}
3149
3150static int in_remove_audio_effect(const struct audio_stream *stream,
3151 effect_handle_t effect)
3152{
3153 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3154 int i;
3155 int status = -EINVAL;
3156 bool found = false;
3157 effect_descriptor_t desc;
3158
3159 pthread_mutex_lock(&in->dev->lock);
3160 pthread_mutex_lock(&in->lock);
3161 if (in->num_preprocessors <= 0) {
3162 status = -ENOSYS;
3163 goto exit;
3164 }
3165
3166 for (i = 0; i < in->num_preprocessors; i++) {
3167 if (found) {
3168 in->preprocessors[i - 1] = in->preprocessors[i];
3169 continue;
3170 }
3171 if (in->preprocessors[i] == effect) {
3172 in->preprocessors[i] = NULL;
3173 status = 0;
3174 found = true;
3175 }
3176 }
3177
3178 if (status != 0) {
3179 goto exit;
3180 }
3181
3182 in->num_preprocessors--;
3183
3184 status = (*effect)->get_descriptor(effect, &desc);
3185 if (status != 0) {
3186 goto exit;
3187 }
3188 if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3189 in->need_echo_reference = false;
3190 do_input_standby(in);
3191 }
3192
3193exit:
3194
3195 pthread_mutex_unlock(&in->lock);
3196 pthread_mutex_unlock(&in->dev->lock);
3197 return status;
3198}
3199
3200static int adev_open_output_stream(struct audio_hw_device *dev,
3201 audio_io_handle_t handle __unused,
3202 audio_devices_t devices,
3203 audio_output_flags_t flags,
3204 struct audio_config *config,
3205 struct audio_stream_out **stream_out,
3206 const char *address __unused)
3207{
3208 struct aml_audio_device *ladev = (struct aml_audio_device *)dev;
3209 struct aml_stream_out *out;
3210 int channel_count = popcount(config->channel_mask);
3211 int digital_codec;
3212 bool direct = false;
3213 int ret;
3214 bool hwsync_lpcm = false;
3215 ALOGI("**enter %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d, flags=0x%x)", __FUNCTION__, devices,
3216 config->format, config->channel_mask, config->sample_rate, flags);
3217
3218 out = (struct aml_stream_out *)calloc(1, sizeof(struct aml_stream_out));
3219 if (!out) {
3220 return -ENOMEM;
3221 }
3222
3223 out->flags = flags;
3224 if (getprop_bool("ro.platform.has.tvuimode")) {
3225 out->is_tv_platform = 1;
3226 }
3227 out->config = pcm_config_out;
3228 //hwsync with LPCM still goes to out_write_legacy
3229 hwsync_lpcm = (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(config->format));
3230 ALOGI("hwsync_lpcm %d\n", hwsync_lpcm);
3231 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY || hwsync_lpcm) {
3232 out->stream.common.get_channels = out_get_channels;
3233 out->stream.common.get_format = out_get_format;
3234 out->stream.write = out_write_legacy;
3235 out->stream.common.standby = out_standby;
3236
3237 out->hal_rate = out->config.rate;
3238 out->hal_format = config->format;
3239 config->format = out_get_format(&out->stream.common);
3240 config->channel_mask = out_get_channels(&out->stream.common);
3241 config->sample_rate = out_get_sample_rate(&out->stream.common);
3242 } else if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
3243 out->stream.common.get_channels = out_get_channels_direct;
3244 out->stream.common.get_format = out_get_format_direct;
3245 out->stream.write = out_write_direct;
3246 out->stream.common.standby = out_standby_direct;
3247 //out->config = pcm_config_out_direct;
3248 out->hal_channel_mask = config->channel_mask;
3249 if (config->sample_rate == 0) {
3250 config->sample_rate = 48000;
3251 }
3252 out->config.rate = out->hal_rate = config->sample_rate;
3253 out->hal_format = config->format;
3254 out->raw_61937_frame_size = 1;
3255 digital_codec = get_codec_type(config->format);
3256 if (digital_codec == TYPE_EAC3) {
3257 out->raw_61937_frame_size = 4;
3258 out->config.period_size = pcm_config_out.period_size * 2;
3259 } else if (digital_codec == TYPE_TRUE_HD || digital_codec == TYPE_DTS_HD) {
3260 out->config.period_size = pcm_config_out.period_size * 4 * 2;
3261 out->raw_61937_frame_size = 16;
3262 }
3263 else if (digital_codec == TYPE_AC3 || digital_codec == TYPE_DTS)
3264 out->raw_61937_frame_size = 4;
3265
3266 if (channel_count > 2) {
3267 ALOGI("[adev_open_output_stream]: out/%p channel/%d\n", out,
3268 channel_count);
3269 out->multich = channel_count;
3270 out->config.channels = channel_count;
3271 }
3272 if (codec_type_is_raw_data(digital_codec)) {
3273 ALOGI("for raw audio output,force alsa stereo output\n");
3274 out->config.channels = 2;
3275 out->multich = 2;
3276 }
3277 } else if (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) {
3278 // TODO: add hwsync write here
3279 //out->stream.write = out_write_hwsync;
3280 }
3281
3282 out->stream.common.get_sample_rate = out_get_sample_rate;
3283 out->stream.common.set_sample_rate = out_set_sample_rate;
3284 out->stream.common.get_buffer_size = out_get_buffer_size;
3285 out->stream.common.set_format = out_set_format;
3286 //out->stream.common.standby = out_standby;
3287 out->stream.common.dump = out_dump;
3288 out->stream.common.set_parameters = out_set_parameters;
3289 out->stream.common.get_parameters = out_get_parameters;
3290 out->stream.common.add_audio_effect = out_add_audio_effect;
3291 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3292 out->stream.get_latency = out_get_latency;
3293 out->stream.set_volume = out_set_volume;
3294 out->stream.get_render_position = out_get_render_position;
3295 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3296 out->stream.get_presentation_position = out_get_presentation_position;
3297 out->stream.pause = out_pause;
3298 out->stream.resume = out_resume;
3299 out->stream.flush = out_flush;
3300 out->volume_l = 1.0;
3301 out->volume_r = 1.0;
3302 out->dev = ladev;
3303 out->standby = true;
3304 out->frame_write_sum = 0;
3305 out->hw_sync_mode = false;
3306 out->first_apts_flag = false;
3307 //out->hal_rate = out->config.rate;
3308 if (0/*flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC*/) {
3309 out->hw_sync_mode = true;
3310 ALOGI("Output stream open with AUDIO_OUTPUT_FLAG_HW_AV_SYNC");
3311 }
3312 /* FIXME: when we support multiple output devices, we will want to
3313 * do the following:
3314 * adev->devices &= ~AUDIO_DEVICE_OUT_ALL;
3315 * adev->devices |= out->device;
3316 * select_output_device(adev);
3317 * This is because out_set_parameters() with a route is not
3318 * guaranteed to be called after an output stream is opened.
3319 */
3320
3321 LOGFUNC("**leave %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d)", __FUNCTION__, devices,
3322 config->format, config->channel_mask, config->sample_rate);
3323
3324 *stream_out = &out->stream;
3325
3326 if (out->is_tv_platform && !(flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
3327 out->config.channels = 8;
3328 out->config.format = PCM_FORMAT_S32_LE;
3329 out->tmp_buffer_8ch = malloc(out->config.period_size * 4 * 8);
3330 if (out->tmp_buffer_8ch == NULL) {
3331 ALOGE("cannot malloc memory for out->tmp_buffer_8ch");
3332 return -ENOMEM;
3333 }
3334 out->audioeffect_tmp_buffer = malloc(out->config.period_size * 6);
3335 if (out->audioeffect_tmp_buffer == NULL) {
3336 ALOGE("cannot malloc memory for audioeffect_tmp_buffer");
3337 return -ENOMEM;
3338 }
3339 //EQ lib load and init EQ
3340 ret = load_EQ_lib();
3341 if (ret < 0) {
3342 ALOGE("%s, Load EQ lib fail!\n", __FUNCTION__);
3343 out->has_EQ_lib = 0;
3344 } else {
3345 ret = HPEQ_init();
3346 if (ret < 0) {
3347 out->has_EQ_lib = 0;
3348 } else {
3349 out->has_EQ_lib = 1;
3350 }
3351 HPEQ_enable(1);
3352 }
3353 //load srs lib and init it.
3354 ret = load_SRS_lib();
3355 if (ret < 0) {
3356 ALOGE("%s, Load SRS lib fail!\n", __FUNCTION__);
3357 out->has_SRS_lib = 0;
3358 } else {
3359 ret = srs_init(48000);
3360 if (ret < 0) {
3361 out->has_SRS_lib = 0;
3362 } else {
3363 out->has_SRS_lib = 1;
3364 }
3365 }
3366 //load aml_IIR lib
3367 ret = load_aml_IIR_lib();
3368 if (ret < 0) {
3369 ALOGE("%s, Load aml_IIR lib fail!\n", __FUNCTION__);
3370 out->has_aml_IIR_lib = 0;
3371 } else {
3372 char value[PROPERTY_VALUE_MAX];
3373 int paramter = 0;
3374 if (property_get("media.audio.LFP.paramter", value, NULL) > 0) {
3375 paramter = atoi(value);
3376 }
3377 aml_IIR_init(paramter);
3378 out->has_aml_IIR_lib = 1;
3379 }
3380 }
3381 return 0;
3382
3383err_open:
3384 free(out);
3385 *stream_out = NULL;
3386 return ret;
3387}
3388
3389static void adev_close_output_stream(struct audio_hw_device *dev,
3390 struct audio_stream_out *stream)
3391{
3392 struct aml_stream_out *out = (struct aml_stream_out *)stream;
3393 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3394 bool hwsync_lpcm = false;
3395 LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream);
3396 if (out->is_tv_platform == 1) {
3397 free(out->tmp_buffer_8ch);
3398 free(out->audioeffect_tmp_buffer);
3399 }
3400
3401 hwsync_lpcm = (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(out->hal_format));
3402 if (out->flags & AUDIO_OUTPUT_FLAG_PRIMARY || hwsync_lpcm) {
3403 out_standby(&stream->common);
3404 } else if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
3405 out_standby_direct(&stream->common);
3406 }
3407 if (adev->hwsync_output == out) {
3408 ALOGI("clear hwsync output when close stream\n");
3409 adev->hwsync_output = NULL;
3410 }
3411 free(stream);
3412}
3413
3414static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3415{
3416 LOGFUNC("%s(%p, %s)", __FUNCTION__, dev, kvpairs);
3417
3418 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3419 struct str_parms *parms;
3420 char *str;
3421 char value[32];
3422 int ret;
3423 parms = str_parms_create_str(kvpairs);
3424 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3425 if (ret >= 0) {
3426 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
3427 adev->low_power = false;
3428 } else {
3429 adev->low_power = true;
3430 }
3431 }
3432 str_parms_destroy(parms);
3433 return ret;
3434}
3435
3436static char * adev_get_parameters(const struct audio_hw_device *dev __unused,
3437 const char *keys __unused)
3438{
3439 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3440 if (!strcmp(keys, AUDIO_PARAMETER_HW_AV_SYNC)) {
3441 ALOGI("get hwsync id\n");
3442 return strdup("hw_av_sync=12345678");
3443 }
3444 return strdup("");
3445}
3446
3447static int adev_init_check(const struct audio_hw_device *dev __unused)
3448{
3449 return 0;
3450}
3451
3452static int adev_set_voice_volume(struct audio_hw_device *dev __unused, float volume __unused)
3453{
3454 return 0;
3455}
3456
3457static int adev_set_master_volume(struct audio_hw_device *dev __unused, float volume __unused)
3458{
3459 return -ENOSYS;
3460}
3461
3462static int adev_get_master_volume(struct audio_hw_device *dev __unused,
3463 float *volume __unused)
3464{
3465 return -ENOSYS;
3466}
3467
3468static int adev_set_master_mute(struct audio_hw_device *dev __unused, bool muted __unused)
3469{
3470 return -ENOSYS;
3471}
3472
3473static int adev_get_master_mute(struct audio_hw_device *dev __unused, bool *muted __unused)
3474{
3475 return -ENOSYS;
3476}
3477static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
3478{
3479 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3480 LOGFUNC("%s(%p, %d)", __FUNCTION__, dev, mode);
3481
3482 pthread_mutex_lock(&adev->lock);
3483 if (adev->mode != mode) {
3484 adev->mode = mode;
3485 select_mode(adev);
3486 }
3487 pthread_mutex_unlock(&adev->lock);
3488
3489 return 0;
3490}
3491
3492static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
3493{
3494 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3495
3496 adev->mic_mute = state;
3497
3498 return 0;
3499}
3500
3501static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
3502{
3503 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3504
3505 *state = adev->mic_mute;
3506
3507 return 0;
3508
3509}
3510
3511static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
3512 const struct audio_config *config)
3513{
3514 size_t size;
3515 int channel_count = popcount(config->channel_mask);
3516
3517 LOGFUNC("%s(%p, %d, %d, %d)", __FUNCTION__, dev, config->sample_rate,
3518 config->format, channel_count);
3519 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
3520 return 0;
3521 }
3522
3523 return get_input_buffer_size(config->frame_count, config->sample_rate,
3524 config->format, channel_count);
3525
3526}
3527
3528static int adev_open_input_stream(struct audio_hw_device *dev,
3529 audio_io_handle_t handle __unused,
3530 audio_devices_t devices,
3531 struct audio_config *config,
3532 struct audio_stream_in **stream_in,
3533 audio_input_flags_t flags __unused,
3534 const char *address __unused,
3535 audio_source_t source __unused)
3536{
3537 struct aml_audio_device *ladev = (struct aml_audio_device *)dev;
3538 struct aml_stream_in *in;
3539 int ret;
3540 int channel_count = popcount(config->channel_mask);
3541 LOGFUNC("%s(%#x, %d, 0x%04x, %d)", __FUNCTION__,
3542 devices, config->format, config->channel_mask, config->sample_rate);
3543 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
3544 return -EINVAL;
3545 }
3546
3547 in = (struct aml_stream_in *)calloc(1, sizeof(struct aml_stream_in));
3548 if (!in) {
3549 return -ENOMEM;
3550 }
3551
3552 in->stream.common.get_sample_rate = in_get_sample_rate;
3553 in->stream.common.set_sample_rate = in_set_sample_rate;
3554 in->stream.common.get_buffer_size = in_get_buffer_size;
3555 in->stream.common.get_channels = in_get_channels;
3556 in->stream.common.get_format = in_get_format;
3557 in->stream.common.set_format = in_set_format;
3558 in->stream.common.standby = in_standby;
3559 in->stream.common.dump = in_dump;
3560 in->stream.common.set_parameters = in_set_parameters;
3561 in->stream.common.get_parameters = in_get_parameters;
3562 in->stream.common.add_audio_effect = in_add_audio_effect;
3563 in->stream.common.remove_audio_effect = in_remove_audio_effect;
3564 in->stream.set_gain = in_set_gain;
3565 in->stream.read = in_read;
3566 in->stream.get_input_frames_lost = in_get_input_frames_lost;
3567
3568 in->requested_rate = config->sample_rate;
3569
3570 in->device = devices & ~AUDIO_DEVICE_BIT_IN;
3571 if (in->device & AUDIO_DEVICE_IN_ALL_SCO) {
3572 memcpy(&in->config, &pcm_config_bt, sizeof(pcm_config_bt));
3573 } else {
3574 memcpy(&in->config, &pcm_config_in, sizeof(pcm_config_in));
3575 }
3576
3577 if (in->config.channels == 1) {
3578 config->channel_mask = AUDIO_CHANNEL_IN_MONO;
3579 } else if (in->config.channels == 2) {
3580 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
3581 } else {
3582 ALOGE("Bad value of channel count : %d", in->config.channels);
3583 }
3584 in->buffer = malloc(in->config.period_size *
3585 audio_stream_in_frame_size(&in->stream));
3586 if (!in->buffer) {
3587 ret = -ENOMEM;
3588 goto err_open;
3589 }
3590
3591 if (in->requested_rate != in->config.rate) {
3592 LOGFUNC("%s(in->requested_rate=%d, in->config.rate=%d)",
3593 __FUNCTION__, in->requested_rate, in->config.rate);
3594 in->buf_provider.get_next_buffer = get_next_buffer;
3595 in->buf_provider.release_buffer = release_buffer;
3596 ret = create_resampler(in->config.rate,
3597 in->requested_rate,
3598 in->config.channels,
3599 RESAMPLER_QUALITY_DEFAULT,
3600 &in->buf_provider,
3601 &in->resampler);
3602
3603 if (ret != 0) {
3604 ret = -EINVAL;
3605 goto err_open;
3606 }
3607 }
3608
3609 in->dev = ladev;
3610 in->standby = 1;
3611 *stream_in = &in->stream;
3612 return 0;
3613
3614err_open:
3615 if (in->resampler) {
3616 release_resampler(in->resampler);
3617 }
3618
3619 free(in);
3620 *stream_in = NULL;
3621 return ret;
3622}
3623
3624static void adev_close_input_stream(struct audio_hw_device *dev,
3625 struct audio_stream_in *stream)
3626{
3627 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3628
3629 LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream);
3630 in_standby(&stream->common);
3631
3632 if (in->resampler) {
3633 free(in->buffer);
3634 release_resampler(in->resampler);
3635 }
3636 if (in->proc_buf) {
3637 free(in->proc_buf);
3638 }
3639 if (in->ref_buf) {
3640 free(in->ref_buf);
3641 }
3642
3643 free(stream);
3644
3645 return;
3646}
3647
3648static int adev_dump(const audio_hw_device_t *device __unused, int fd __unused)
3649{
3650 return 0;
3651}
3652
3653static int adev_close(hw_device_t *device)
3654{
3655 struct aml_audio_device *adev = (struct aml_audio_device *)device;
3656
3657 audio_route_free(adev->ar);
3658 free(device);
3659 return 0;
3660}
3661
3662static int adev_open(const hw_module_t* module, const char* name,
3663 hw_device_t** device)
3664{
3665 struct aml_audio_device *adev;
3666 int card = CARD_AMLOGIC_BOARD;
3667 int ret;
3668 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
3669 return -EINVAL;
3670 }
3671
3672 adev = calloc(1, sizeof(struct aml_audio_device));
3673 if (!adev) {
3674 return -ENOMEM;
3675 }
3676
3677 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
3678 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
3679 adev->hw_device.common.module = (struct hw_module_t *) module;
3680 adev->hw_device.common.close = adev_close;
3681
3682 adev->hw_device.init_check = adev_init_check;
3683 adev->hw_device.set_voice_volume = adev_set_voice_volume;
3684 adev->hw_device.set_master_volume = adev_set_master_volume;
3685 adev->hw_device.get_master_volume = adev_get_master_volume;
3686 adev->hw_device.set_master_mute = adev_set_master_mute;
3687 adev->hw_device.get_master_mute = adev_get_master_mute;
3688 adev->hw_device.set_mode = adev_set_mode;
3689 adev->hw_device.set_mic_mute = adev_set_mic_mute;
3690 adev->hw_device.get_mic_mute = adev_get_mic_mute;
3691 adev->hw_device.set_parameters = adev_set_parameters;
3692 adev->hw_device.get_parameters = adev_get_parameters;
3693 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
3694 adev->hw_device.open_output_stream = adev_open_output_stream;
3695 adev->hw_device.close_output_stream = adev_close_output_stream;
3696 adev->hw_device.open_input_stream = adev_open_input_stream;
3697 adev->hw_device.close_input_stream = adev_close_input_stream;
3698 adev->hw_device.dump = adev_dump;
3699 card = get_aml_card();
3700 if ((card < 0) || (card > 7)) {
3701 ALOGE("error to get audio card");
3702 return -EINVAL;
3703 }
3704
3705 adev->card = card;
3706 adev->ar = audio_route_init(adev->card, MIXER_XML_PATH);
3707
3708 /* Set the default route before the PCM stream is opened */
3709 adev->mode = AUDIO_MODE_NORMAL;
3710 adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
3711 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
3712
3713 select_devices(adev);
3714
3715 *device = &adev->hw_device.common;
3716 return 0;
3717}
3718
3719static struct hw_module_methods_t hal_module_methods = {
3720 .open = adev_open,
3721};
3722
3723struct audio_module HAL_MODULE_INFO_SYM = {
3724 .common = {
3725 .tag = HARDWARE_MODULE_TAG,
3726 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
3727 .hal_api_version = HARDWARE_HAL_API_VERSION,
3728 .id = AUDIO_HARDWARE_MODULE_ID,
3729 .name = "aml audio HW HAL",
3730 .author = "amlogic, Corp.",
3731 .methods = &hal_module_methods,
3732 },
3733};
3734