summaryrefslogtreecommitdiff
path: root/audio_hw.c (plain)
blob: ea885aabebdf1f21dc6fc108cb00b10cfeff7b84
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 bool hwsync_lpcm = (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(out->hal_format));
1049 do_standby_func standy_func = NULL;
1050 if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT && !hwsync_lpcm) {
1051 standy_func = do_output_standby_direct;
1052 } else {
1053 standy_func = do_output_standby;
1054 }
1055 pthread_mutex_lock(&adev->lock);
1056 pthread_mutex_lock(&out->lock);
1057 standy_func(out);
1058 out->frame_write_sum = 0;
1059 out->last_frames_postion = 0;
1060 pthread_mutex_unlock(&adev->lock);
1061 pthread_mutex_unlock(&out->lock);
1062 return 0;
1063}
1064static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
1065{
1066 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1067 struct aml_audio_device *adev = out->dev;
1068 struct aml_stream_in *in;
1069 struct str_parms *parms;
1070 char *str;
1071 char value[32];
1072 int ret;
1073 uint val = 0;
1074 bool force_input_standby = false;
1075 bool hwsync_lpcm = (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(out->hal_format));
1076 do_standby_func standy_func = NULL;
1077 do_startup_func startup_func = NULL;
1078 if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT && !hwsync_lpcm) {
1079 standy_func = do_output_standby_direct;
1080 startup_func = start_output_stream_direct;
1081 } else {
1082 standy_func = do_output_standby;
1083 startup_func = start_output_stream;
1084 }
1085 LOGFUNC("%s(kvpairs(%s), out_device=%#x)", __FUNCTION__, kvpairs, adev->out_device);
1086 parms = str_parms_create_str(kvpairs);
1087
1088 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
1089 if (ret >= 0) {
1090 val = atoi(value);
1091 pthread_mutex_lock(&adev->lock);
1092 pthread_mutex_lock(&out->lock);
1093 if (((adev->out_device & AUDIO_DEVICE_OUT_ALL) != val) && (val != 0)) {
1094 if (1/* out == adev->active_output[0]*/) {
1095 ALOGI("audio hw select device!\n");
1096 standy_func(out);
1097 /* a change in output device may change the microphone selection */
1098 if (adev->active_input &&
1099 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1100 force_input_standby = true;
1101 }
1102 /* force standby if moving to/from HDMI */
1103 if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^
1104 (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) ||
1105 ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^
1106 (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET))) {
1107 standy_func(out);
1108 }
1109 }
1110 adev->out_device &= ~AUDIO_DEVICE_OUT_ALL;
1111 adev->out_device |= val;
1112 select_devices(adev);
1113 }
1114 pthread_mutex_unlock(&out->lock);
1115 if (force_input_standby) {
1116 in = adev->active_input;
1117 pthread_mutex_lock(&in->lock);
1118 do_input_standby(in);
1119 pthread_mutex_unlock(&in->lock);
1120 }
1121 pthread_mutex_unlock(&adev->lock);
1122 goto exit;
1123 }
1124 int sr = 0;
1125 ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_SAMPLING_RATE, &sr);
1126 if (ret >= 0) {
1127 if (sr > 0) {
1128 struct pcm_config *config = &out->config;
1129 ALOGI("audio hw sampling_rate change from %d to %d \n", config->rate, sr);
1130 config->rate = sr;
1131 pthread_mutex_lock(&adev->lock);
1132 pthread_mutex_lock(&out->lock);
1133 if (!out->standby) {
1134 standy_func(out);
1135 startup_func(out);
1136 out->standby = 0;
1137 }
1138 pthread_mutex_unlock(&adev->lock);
1139 pthread_mutex_unlock(&out->lock);
1140 }
1141 goto exit;
1142 }
1143 int frame_size = 0;
1144 ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_FRAME_COUNT, &frame_size);
1145 if (ret >= 0) {
1146 if (frame_size > 0) {
1147 struct pcm_config *config = &out->config;
1148 ALOGI("audio hw frame size change from %d to %d \n", config->period_size, frame_size);
1149 config->period_size = frame_size;
1150 pthread_mutex_lock(&adev->lock);
1151 pthread_mutex_lock(&out->lock);
1152 if (!out->standby) {
1153 standy_func(out);
1154 startup_func(out);
1155 out->standby = 0;
1156 }
1157 pthread_mutex_unlock(&adev->lock);
1158 pthread_mutex_unlock(&out->lock);
1159 }
1160 goto exit;
1161 }
1162 int EQ_parameters[5] = {0, 0, 0, 0, 0};
1163 char tmp[2];
1164 int data = 0, i = 0;
1165 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_EQ, value, sizeof(value));
1166 //ALOGI("audio effect EQ parameters are %s\n", value);
1167 if (ret >= 0) {
1168 for (i; i < 5; i++) {
1169 tmp[0] = value[2 * i];
1170 tmp[1] = value[2 * i + 1];
1171 data = atoi(tmp);
1172 EQ_parameters[i] = data - 10;
1173 }
1174 ALOGI("audio effect EQ parameters are %d,%d,%d,%d,%d\n", EQ_parameters[0],
1175 EQ_parameters[1], EQ_parameters[2], EQ_parameters[3], EQ_parameters[4]);
1176 ret = 0;
1177 HPEQ_setParameter(EQ_parameters[0], EQ_parameters[1],
1178 EQ_parameters[2], EQ_parameters[3], EQ_parameters[4]);
1179 goto exit;
1180 }
1181 int SRS_parameters[5] = {0, 0, 0, 0, 0};
1182 char tmp1[3];
1183 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_SRS, value, sizeof(value));
1184 //ALOGI("audio effect SRS parameters are %s\n", value);
1185 if (ret >= 0) {
1186 for (i; i < 5; i++) {
1187 tmp1[0] = value[3 * i];
1188 tmp1[1] = value[3 * i + 1];
1189 tmp1[2] = value[3 * i + 2];
1190 SRS_parameters[i] = atoi(tmp1);
1191 }
1192 ALOGI("audio effect SRS parameters are %d,%d,%d,%d,%d\n", SRS_parameters[0],
1193 SRS_parameters[1], SRS_parameters[2], SRS_parameters[3], SRS_parameters[4]);
1194 ret = 0;
1195 srs_setParameter(SRS_parameters);
1196 goto exit;
1197 }
1198 int SRS_gain[2] = {0, 0};
1199 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_SRS_GAIN, value, sizeof(value));
1200 if (ret >= 0) {
1201 for (i; i < 2; i++) {
1202 tmp1[0] = value[3 * i];
1203 tmp1[1] = value[3 * i + 1];
1204 tmp1[2] = value[3 * i + 2];
1205 SRS_gain[i] = atoi(tmp1);
1206 }
1207 ALOGI("audio effect SRS input/output gain are %d,%d\n", SRS_gain[0], SRS_gain[1]);
1208 ret = 0;
1209 srs_set_gain(SRS_gain[0], SRS_gain[1]);
1210 goto exit;
1211 }
1212 int SRS_switch[3] = {0, 0, 0};
1213 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_SRS_SWITCH, value, sizeof(value));
1214 if (ret >= 0) {
1215 for (i; i < 3; i++) {
1216 tmp[0] = value[2 * i];
1217 tmp[1] = value[2 * i + 1];
1218 SRS_switch[i] = atoi(tmp);
1219 }
1220 ALOGI("audio effect SRS switch %d, %d, %d\n", SRS_switch[0], SRS_switch[1], SRS_switch[2]);
1221 ret = 0;
1222 srs_surround_enable(SRS_switch[0]);
1223 srs_dialogclarity_enable(SRS_switch[1]);
1224 srs_truebass_enable(SRS_switch[2]);
1225 goto exit;
1226 }
1227 ret = str_parms_get_str(parms, "hw_av_sync", value, sizeof(value));
1228 if (ret >= 0) {
1229 int hw_sync_id = atoi(value);
1230 unsigned char sync_enable = (hw_sync_id == 12345678) ? 1 : 0;
1231 ALOGI("(%p)set hw_sync_id %d,%s hw sync mode\n",
1232 out, hw_sync_id, sync_enable ? "enable" : "disable");
1233 out->hw_sync_mode = sync_enable;
1234 out->first_apts_flag = false;
1235 pthread_mutex_lock(&adev->lock);
1236 pthread_mutex_lock(&out->lock);
1237 out->frame_write_sum = 0;
1238 out->last_frames_postion = 0;
1239 /* clear up previous playback output status */
1240 if (!out->standby) {
1241 standy_func(out);
1242 }
1243 //adev->hwsync_output = sync_enable?out:NULL;
1244 if (sync_enable) {
1245 ALOGI("init hal mixer when hwsync\n");
1246 aml_hal_mixer_init(&adev->hal_mixer);
1247 }
1248 pthread_mutex_unlock(&out->lock);
1249 pthread_mutex_unlock(&adev->lock);
1250 ret = 0;
1251 goto exit;
1252 }
1253exit:
1254 str_parms_destroy(parms);
1255 return ret;
1256}
1257
1258static char * out_get_parameters(const struct audio_stream *stream __unused, const char *keys __unused)
1259{
1260 return strdup("");
1261}
1262
1263static uint32_t out_get_latency(const struct audio_stream_out *stream)
1264{
1265 const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
1266 uint32_t whole_latency;
1267 int ret = 0;
1268 snd_pcm_sframes_t frames = 0;
1269 whole_latency = (out->config.period_size * out->config.period_count * 1000) / out->config.rate;
1270 if (!out->pcm || !pcm_is_ready(out->pcm)) {
1271 return whole_latency;
1272 }
1273 ret = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_DELAY, &frames);
1274 if (ret < 0) {
1275 return whole_latency;
1276 }
1277 return (frames * 1000) / out->config.rate/* (out->pcm->config.rate)*/;
1278}
1279
1280static int out_set_volume(struct audio_stream_out *stream, float left, float right)
1281{
1282 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1283 out->volume_l = left;
1284 out->volume_r = right;
1285 return 0;
1286}
1287
1288static int out_pause(struct audio_stream_out *stream)
1289{
1290 LOGFUNC("out_pause(%p)\n", stream);
1291
1292 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1293 struct aml_audio_device *adev = out->dev;
1294 int r = 0;
1295 pthread_mutex_lock(&adev->lock);
1296 pthread_mutex_lock(&out->lock);
1297 if (out->standby || out->pause_status == true) {
1298 goto exit;
1299 }
1300 if (out->hw_sync_mode) {
1301 adev->hwsync_output = NULL;
1302 if (adev->active_output_count > 1) {
1303 ALOGI("more than one active stream,skip alsa hw pause\n");
1304 goto exit1;
1305 }
1306 }
1307 if (pcm_is_ready(out->pcm)) {
1308 r = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_PAUSE, 1);
1309 if (r < 0) {
1310 ALOGE("cannot pause channel\n");
1311 } else {
1312 r = 0;
1313 }
1314 }
1315exit1:
1316 if (out->hw_sync_mode) {
1317 sysfs_set_sysfs_str(TSYNC_EVENT, "AUDIO_PAUSE");
1318 }
1319 out->pause_status = true;
1320exit:
1321 pthread_mutex_unlock(&adev->lock);
1322 pthread_mutex_unlock(&out->lock);
1323 return r;
1324}
1325
1326static int out_resume(struct audio_stream_out *stream)
1327{
1328 LOGFUNC("out_resume (%p)\n", stream);
1329 struct aml_stream_out *out = (struct aml_stream_out *) stream;
1330 struct aml_audio_device *adev = out->dev;
1331 int r = 0;
1332 pthread_mutex_lock(&adev->lock);
1333 pthread_mutex_lock(&out->lock);
1334 if (out->standby || out->pause_status == false) {
1335 goto exit;
1336 }
1337 if (pcm_is_ready(out->pcm)) {
1338 r = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_PAUSE, 0);
1339 if (r < 0) {
1340 ALOGE("cannot resume channel\n");
1341 } else {
1342 r = 0;
1343 }
1344 }
1345 if (out->hw_sync_mode) {
1346 ALOGI("init hal mixer when hwsync resume\n");
1347 adev->hwsync_output = out;
1348 aml_hal_mixer_init(&adev->hal_mixer);
1349 sysfs_set_sysfs_str(TSYNC_EVENT, "AUDIO_RESUME");
1350 }
1351 out->pause_status = false;
1352exit:
1353 pthread_mutex_unlock(&adev->lock);
1354 pthread_mutex_unlock(&out->lock);
1355 return r;
1356}
1357
1358
1359static int audio_effect_process(struct audio_stream_out *stream,
1360 short* buffer, int frame_size)
1361{
1362 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1363 int output_size = frame_size << 2;
1364
1365 if (out->has_SRS_lib) {
1366 output_size = srs_process(buffer, buffer, frame_size);
1367 }
1368 if (out->has_EQ_lib) {
1369 HPEQ_process(buffer, buffer, frame_size);
1370 }
1371 if (out->has_aml_IIR_lib) {
1372 short *ptr = buffer;
1373 short data;
1374 int i;
1375 for (i = 0; i < frame_size; i++) {
1376 data = (short)aml_IIR_process((int)(*ptr), 0);
1377 *ptr++ = data;
1378 data = (short)aml_IIR_process((int)(*ptr), 1);
1379 *ptr++ = data;
1380 }
1381 }
1382 return output_size;
1383}
1384
1385static ssize_t out_write_legacy(struct audio_stream_out *stream, const void* buffer,
1386 size_t bytes)
1387{
1388 int ret = 0;
1389 size_t oldBytes = bytes;
1390 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1391 struct aml_audio_device *adev = out->dev;
1392 size_t frame_size = audio_stream_out_frame_size(stream);
1393 size_t in_frames = bytes / frame_size;
1394 size_t out_frames;
1395 bool force_input_standby = false;
1396 int16_t *in_buffer = (int16_t *)buffer;
1397 int16_t *out_buffer = in_buffer;
1398 struct aml_stream_in *in;
1399 uint ouput_len;
1400 char *data, *data_dst;
1401 volatile char *data_src;
1402 uint i, total_len;
1403 int codec_type = 0;
1404 int samesource_flag = 0;
1405 uint32_t latency_frames = 0;
1406 int need_mix = 0;
1407 short *mix_buf = NULL;
1408 unsigned char enable_dump = getprop_bool("media.audiohal.outdump");
1409 // limit HAL mixer buffer level within 200ms
1410 while ((adev->hwsync_output != NULL && adev->hwsync_output != out) &&
1411 (aml_hal_mixer_get_content(&adev->hal_mixer) > 200 * 48 * 4)) {
1412 usleep(20000);
1413 }
1414 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
1415 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
1416 * mutex
1417 */
1418 pthread_mutex_lock(&adev->lock);
1419 pthread_mutex_lock(&out->lock);
1420 //here to check whether hwsync out stream and other stream are enabled at the same time.
1421 //if that we need do the hal mixer of the two out stream.
1422 if (out->hw_sync_mode == 1) {
1423 int content_size = aml_hal_mixer_get_content(&adev->hal_mixer);
1424 //ALOGI("content_size %d\n",content_size);
1425 if (content_size > 0) {
1426 if (adev->hal_mixer.need_cache_flag == 0) {
1427 //ALOGI("need do hal mixer\n");
1428 need_mix = 1;
1429 } else if (content_size < 80 * 48 * 4) { //80 ms
1430 //ALOGI("hal mixed cached size %d\n", content_size);
1431 } else {
1432 ALOGI("start enable mix,cached size %d\n", content_size);
1433 adev->hal_mixer.need_cache_flag = 0;
1434 }
1435
1436 } else {
1437 // ALOGI("content size %d,duration %d ms\n",content_size,content_size/48/4);
1438 }
1439 }
1440 /* if hwsync output stream are enabled,write other output to a mixe buffer and sleep for the pcm duration time */
1441 if (adev->hwsync_output != NULL && adev->hwsync_output != out) {
1442 //ALOGI("dev hwsync enable,hwsync %p) cur (%p),size %d\n",adev->hwsync_output,out,bytes);
1443 // out->frame_write_sum += in_frames;
1444#if 0
1445 if (!out->standby) {
1446 do_output_standby(out);
1447 }
1448#endif
1449 if (out->standby) {
1450 ret = start_output_stream(out);
1451 if (ret != 0) {
1452 pthread_mutex_unlock(&adev->lock);
1453 ALOGE("start_output_stream failed");
1454 goto exit;
1455 }
1456 out->standby = false;
1457 }
1458 ret = -1;
1459 aml_hal_mixer_write(&adev->hal_mixer, buffer, bytes);
1460 pthread_mutex_unlock(&adev->lock);
1461 goto exit;
1462 }
1463 if (out->pause_status == true) {
1464 pthread_mutex_unlock(&adev->lock);
1465 pthread_mutex_unlock(&out->lock);
1466 ALOGI("call out_write when pause status (%p)\n", stream);
1467 return 0;
1468 }
1469 if ((out->standby) && (out->hw_sync_mode == 1)) {
1470 // todo: check timestamp header PTS discontinue for new sync point after seek
1471 out->first_apts_flag = false;
1472 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1473 out->hw_sync_header_cnt = 0;
1474 }
1475
1476#if 1
1477 if (enable_dump && out->hw_sync_mode == 0) {
1478 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1479 if (fp1) {
1480 int flen = fwrite((char *)buffer, 1, bytes, fp1);
1481 fclose(fp1);
1482 }
1483 }
1484#endif
1485
1486 if (out->hw_sync_mode == 1) {
1487 char buf[64] = {0};
1488 unsigned char *header;
1489
1490 if (out->hw_sync_state == HW_SYNC_STATE_RESYNC) {
1491 uint i = 0;
1492 uint8_t *p = (uint8_t *)buffer;
1493 while (i < bytes) {
1494 if (hwsync_header_valid(p)) {
1495 ALOGI("HWSYNC resync.%p", out);
1496 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1497 out->hw_sync_header_cnt = 0;
1498 out->first_apts_flag = false;
1499 bytes -= i;
1500 buffer += i;
1501 in_frames = bytes / frame_size;
1502 ALOGI("in_frames = %d", in_frames);
1503 in_buffer = (int16_t *)buffer;
1504 break;
1505 } else {
1506 i += 4;
1507 p += 4;
1508 }
1509 }
1510
1511 if (out->hw_sync_state == HW_SYNC_STATE_RESYNC) {
1512 ALOGI("Keep searching for HWSYNC header.%p", out);
1513 pthread_mutex_unlock(&adev->lock);
1514 goto exit;
1515 }
1516 }
1517
1518 header = (unsigned char *)buffer;
1519 }
1520 if (out->standby) {
1521 ret = start_output_stream(out);
1522 if (ret != 0) {
1523 pthread_mutex_unlock(&adev->lock);
1524 ALOGE("start_output_stream failed");
1525 goto exit;
1526 }
1527 out->standby = false;
1528 /* a change in output device may change the microphone selection */
1529 if (adev->active_input &&
1530 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1531 force_input_standby = true;
1532 }
1533 }
1534 pthread_mutex_unlock(&adev->lock);
1535#if 1
1536 /* Reduce number of channels, if necessary */
1537 if (popcount(out_get_channels(&stream->common)) >
1538 (int)out->config.channels) {
1539 unsigned int i;
1540
1541 /* Discard right channel */
1542 for (i = 1; i < in_frames; i++) {
1543 in_buffer[i] = in_buffer[i * 2];
1544 }
1545
1546 /* The frame size is now half */
1547 frame_size /= 2;
1548 }
1549#endif
1550 /* only use resampler if required */
1551 if (out->config.rate != out_get_sample_rate(&stream->common)) {
1552 out_frames = out->buffer_frames;
1553 out->resampler->resample_from_input(out->resampler,
1554 in_buffer, &in_frames,
1555 (int16_t*)out->buffer, &out_frames);
1556 in_buffer = (int16_t*)out->buffer;
1557 out_buffer = in_buffer;
1558 } else {
1559 out_frames = in_frames;
1560 }
1561 if (out->echo_reference != NULL) {
1562
1563 struct echo_reference_buffer b;
1564 b.raw = (void *)buffer;
1565 b.frame_count = in_frames;
1566 get_playback_delay(out, out_frames, &b);
1567 out->echo_reference->write(out->echo_reference, &b);
1568 }
1569
1570#if 0
1571 if (enable_dump && out->hw_sync_mode == 1) {
1572 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1573 if (fp1) {
1574 int flen = fwrite((char *)in_buffer, 1, out_frames * frame_size, fp1);
1575 LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size);
1576 fclose(fp1);
1577 } else {
1578 LOGFUNC("could not open file:/data/i2s_audio_out.pcm");
1579 }
1580 }
1581#endif
1582#if 1
1583if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
1584 codec_type = get_sysfs_int("/sys/class/audiodsp/digital_codec");
1585 //samesource_flag = get_sysfs_int("/sys/class/audiodsp/audio_samesource");
1586 if (codec_type != out->last_codec_type/*samesource_flag == 0*/ && codec_type == 0) {
1587 ALOGI("to enable same source,need reset alsa,type %d,same source flag %d \n", codec_type, samesource_flag);
1588 pcm_stop(out->pcm);
1589 }
1590 out->last_codec_type = codec_type;
1591}
1592#endif
1593 if (out->is_tv_platform == 1) {
1594 int16_t *tmp_buffer = (int16_t *)out->audioeffect_tmp_buffer;
1595 memcpy((void *)tmp_buffer, (void *)in_buffer, out_frames * 4);
1596 audio_effect_process(stream, tmp_buffer, out_frames);
1597 for (i = 0; i < out_frames; i ++) {
1598 out->tmp_buffer_8ch[8 * i] = ((int32_t)(in_buffer[2 * i])) << 16;
1599 out->tmp_buffer_8ch[8 * i + 1] = ((int32_t)(in_buffer[2 * i + 1])) << 16;
1600 out->tmp_buffer_8ch[8 * i + 2] = ((int32_t)(tmp_buffer[2 * i])) << 16;
1601 out->tmp_buffer_8ch[8 * i + 3] = ((int32_t)(tmp_buffer[2 * i + 1])) << 16;
1602 out->tmp_buffer_8ch[8 * i + 4] = 0;
1603 out->tmp_buffer_8ch[8 * i + 5] = 0;
1604 out->tmp_buffer_8ch[8 * i + 6] = 0;
1605 out->tmp_buffer_8ch[8 * i + 7] = 0;
1606 }
1607 /*if (out->frame_count < 5*1024) {
1608 memset(out->tmp_buffer_8ch, 0, out_frames * frame_size * 8);
1609 }*/
1610 ret = pcm_write(out->pcm, out->tmp_buffer_8ch, out_frames * frame_size * 8);
1611 out->frame_write_sum += out_frames;
1612 } else {
1613 if (out->hw_sync_mode) {
1614
1615 int remain = out_frames * frame_size;
1616 uint8_t *p = buffer;
1617
1618 //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);
1619
1620 while (remain > 0) {
1621 if (out->hw_sync_state == HW_SYNC_STATE_HEADER) {
1622 //ALOGI("Add to header buffer [%d], 0x%x", out->hw_sync_header_cnt, *p);
1623 out->hw_sync_header[out->hw_sync_header_cnt++] = *p++;
1624 remain--;
1625 if (out->hw_sync_header_cnt == 16) {
1626 int64_t pts;
1627 if (!hwsync_header_valid(&out->hw_sync_header[0])) {
1628 ALOGE("hwsync header out of sync! Resync.");
1629 out->hw_sync_state = HW_SYNC_STATE_RESYNC;
1630 break;
1631 }
1632 out->hw_sync_state = HW_SYNC_STATE_BODY;
1633 out->hw_sync_body_cnt = hwsync_header_get_size(&out->hw_sync_header[0]);
1634 out->body_align_cnt = 0;
1635 pts = hwsync_header_get_pts(&out->hw_sync_header[0]);
1636 pts = pts * 90 / 1000000;
1637#if 1
1638 char buf[64] = {0};
1639 if (out->first_apts_flag == false) {
1640 uint32_t apts_cal;
1641 ALOGI("HW SYNC new first APTS %lld,body size %d", pts, out->hw_sync_body_cnt);
1642 out->first_apts_flag = true;
1643 out->first_apts = pts;
1644 out->frame_write_sum = 0;
1645 out->last_apts_from_header = pts;
1646 sprintf(buf, "AUDIO_START:0x%llx", pts & 0xffffffff);
1647 ALOGI("tsync -> %s", buf);
1648 if (sysfs_set_sysfs_str(TSYNC_EVENT, buf) == -1) {
1649 ALOGE("set AUDIO_START failed \n");
1650 }
1651 } else {
1652 int64_t apts;
1653 uint32_t latency = out_get_latency(out) * 90;
1654 apts = (uint64_t)out->frame_write_sum * 90000 / DEFAULT_OUT_SAMPLING_RATE;
1655 apts += out->first_apts;
1656 // check PTS discontinue, which may happen when audio track switching
1657 // discontinue means PTS calculated based on first_apts and frame_write_sum
1658 // does not match the timestamp of next audio samples
1659 apts -= latency;
1660 if (apts < 0) {
1661 apts = 0;
1662 }
1663 // here we use acutal audio frame gap,not use the differece of caculated current apts with the current frame pts,
1664 //as there is a offset of audio latency from alsa.
1665 // handle audio gap 0.5~5 s
1666 unsigned two_frame_gap = (unsigned)llabs(out->last_apts_from_header - pts);
1667 if (two_frame_gap > APTS_DISCONTINUE_THRESHOLD_MIN && two_frame_gap < APTS_DISCONTINUE_THRESHOLD_MAX) {
1668 /* if (abs(pts -apts) > APTS_DISCONTINUE_THRESHOLD_MIN && abs(pts -apts) < APTS_DISCONTINUE_THRESHOLD_MAX) { */
1669 ALOGI("HW sync PTS discontinue, 0x%llx->0x%llx(from header) diff %d,last apts %llx(from header)",
1670 apts, pts, two_frame_gap, out->last_apts_from_header);
1671 //here handle the audio gap and insert zero to the alsa
1672 uint insert_size = 0;
1673 uint insert_size_total = 0;
1674 uint once_write_size = 0;
1675 insert_size = two_frame_gap/*abs(pts -apts) */ / 90 * 48 * 4;
1676 insert_size = insert_size & (~63);
1677 insert_size_total = insert_size;
1678 ALOGI("audio gap %d ms ,need insert pcm size %d\n", two_frame_gap/*abs(pts -apts) */ / 90, insert_size);
1679 char *insert_buf = (char*)malloc(8192);
1680 if (insert_buf == NULL) {
1681 ALOGE("malloc size failed \n");
1682 pthread_mutex_unlock(&adev->lock);
1683 goto exit;
1684 }
1685 memset(insert_buf, 0, 8192);
1686 if (need_mix) {
1687 mix_buf = malloc(once_write_size);
1688 if (mix_buf == NULL) {
1689 ALOGE("mix_buf malloc failed\n");
1690 free(insert_buf);
1691 pthread_mutex_unlock(&adev->lock);
1692 goto exit;
1693 }
1694 }
1695 while (insert_size > 0) {
1696 once_write_size = insert_size > 8192 ? 8192 : insert_size;
1697 if (need_mix) {
1698 pthread_mutex_lock(&adev->lock);
1699 aml_hal_mixer_read(&adev->hal_mixer, mix_buf, once_write_size);
1700 pthread_mutex_unlock(&adev->lock);
1701 memcpy(insert_buf, mix_buf, once_write_size);
1702 }
1703#if 1
1704 if (enable_dump) {
1705 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1706 if (fp1) {
1707 int flen = fwrite((char *)insert_buf, 1, once_write_size, fp1);
1708 fclose(fp1);
1709 }
1710 }
1711#endif
1712 pthread_mutex_lock(&adev->pcm_write_lock);
1713 ret = pcm_write(out->pcm, (void *) insert_buf, once_write_size);
1714 pthread_mutex_unlock(&adev->pcm_write_lock);
1715 if (ret != 0) {
1716 ALOGE("pcm write failed\n");
1717 free(insert_buf);
1718 if (mix_buf) {
1719 free(mix_buf);
1720 }
1721 pthread_mutex_unlock(&adev->lock);
1722 goto exit;
1723 }
1724 insert_size -= once_write_size;
1725 }
1726 if (mix_buf) {
1727 free(mix_buf);
1728 }
1729 mix_buf = NULL;
1730 free(insert_buf);
1731 // insert end
1732 //adev->first_apts = pts;
1733 out->frame_write_sum += insert_size_total / frame_size;
1734#if 0
1735 sprintf(buf, "AUDIO_TSTAMP_DISCONTINUITY:0x%lx", pts);
1736 if (sysfs_set_sysfs_str(TSYNC_EVENT, buf) == -1) {
1737 ALOGE("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
1738 }
1739#endif
1740 } else {
1741 int pcr = 0;
1742 if (get_sysfs_int16(TSYNC_PCRSCR, &pcr) == 0) {
1743 int32_t apts_cal = apts & 0xffffffff;
1744 if (abs(pcr - apts_cal) < SYSTIME_CORRECTION_THRESHOLD) {
1745 // do nothing
1746 } else {
1747 sprintf(buf, "0x%x", apts_cal);
1748 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);
1749 int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, buf);
1750 if (ret_val == -1) {
1751 ALOGE("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
1752 }
1753 }
1754 }
1755 }
1756 out->last_apts_from_header = pts;
1757 }
1758#endif
1759
1760 //ALOGI("get header body_cnt = %d, pts = %lld", out->hw_sync_body_cnt, pts);
1761 }
1762 continue;
1763 } else if (out->hw_sync_state == HW_SYNC_STATE_BODY) {
1764 uint align;
1765 uint m = (out->hw_sync_body_cnt < remain) ? out->hw_sync_body_cnt : remain;
1766
1767 //ALOGI("m = %d", m);
1768
1769 // process m bytes, upto end of hw_sync_body_cnt or end of remaining our_write bytes.
1770 // within m bytes, there is no hw_sync header and all are body bytes.
1771 if (out->body_align_cnt) {
1772 // clear fragment first for alignment limitation on ALSA driver, which
1773 // requires each pcm_writing aligned at 16 frame boundaries
1774 // assuming data are always PCM16 based, so aligned at 64 bytes unit.
1775 if ((m + out->body_align_cnt) < 64) {
1776 // merge only
1777 memcpy(&out->body_align[out->body_align_cnt], p, m);
1778 p += m;
1779 remain -= m;
1780 out->body_align_cnt += m;
1781 out->hw_sync_body_cnt -= m;
1782 if (out->hw_sync_body_cnt == 0) {
1783 // end of body, research for HW SYNC header
1784 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1785 out->hw_sync_header_cnt = 0;
1786 continue;
1787 }
1788 //ALOGI("align cache add %d, cnt = %d", remain, out->body_align_cnt);
1789 break;
1790 } else {
1791 // merge-submit-continue
1792 memcpy(&out->body_align[out->body_align_cnt], p, 64 - out->body_align_cnt);
1793 p += 64 - out->body_align_cnt;
1794 remain -= 64 - out->body_align_cnt;
1795 //ALOGI("pcm_write 64, out remain %d", remain);
1796
1797 short *w_buf = (short*)&out->body_align[0];
1798
1799 if (need_mix) {
1800 short mix_buf[32];
1801 pthread_mutex_lock(&adev->lock);
1802 aml_hal_mixer_read(&adev->hal_mixer, mix_buf, 64);
1803 pthread_mutex_unlock(&adev->lock);
1804
1805 for (i = 0; i < 64 / 2 / 2; i++) {
1806 int r;
1807 r = w_buf[2 * i] * out->volume_l + mix_buf[2 * i];
1808 w_buf[2 * i] = CLIP(r);
1809 r = w_buf[2 * i + 1] * out->volume_r + mix_buf[2 * i + 1];
1810 w_buf[2 * i + 1] = CLIP(r);
1811 }
1812 } else {
1813 for (i = 0; i < 64 / 2 / 2; i++) {
1814 int r;
1815 r = w_buf[2 * i] * out->volume_l;
1816 w_buf[2 * i] = CLIP(r);
1817 r = w_buf[2 * i + 1] * out->volume_r;
1818 w_buf[2 * i + 1] = CLIP(r);
1819 }
1820 }
1821#if 1
1822 if (enable_dump) {
1823 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1824 if (fp1) {
1825 int flen = fwrite((char *)w_buf, 1, 64, fp1);
1826 fclose(fp1);
1827 }
1828 }
1829#endif
1830 pthread_mutex_lock(&adev->pcm_write_lock);
1831 ret = pcm_write(out->pcm, w_buf, 64);
1832 pthread_mutex_unlock(&adev->pcm_write_lock);
1833 out->frame_write_sum += 64 / frame_size;
1834 out->hw_sync_body_cnt -= 64 - out->body_align_cnt;
1835 out->body_align_cnt = 0;
1836 if (out->hw_sync_body_cnt == 0) {
1837 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1838 out->hw_sync_header_cnt = 0;
1839 }
1840 continue;
1841 }
1842 }
1843
1844 // process m bytes body with an empty fragment for alignment
1845 align = m & 63;
1846 if ((m - align) > 0) {
1847 short *w_buf = (short*)p;
1848 mix_buf = (short *)malloc(m - align);
1849 if (mix_buf == NULL) {
1850 ALOGE("!!!fatal err,malloc %d bytes fail\n", m - align);
1851 ret = -1;
1852 goto exit;
1853 }
1854 if (need_mix) {
1855 pthread_mutex_lock(&adev->lock);
1856 aml_hal_mixer_read(&adev->hal_mixer, mix_buf, m - align);
1857 pthread_mutex_unlock(&adev->lock);
1858 for (i = 0; i < (m - align) / 2 / 2; i++) {
1859 int r;
1860 r = w_buf[2 * i] * out->volume_l + mix_buf[2 * i];
1861 mix_buf[2 * i] = CLIP(r);
1862 r = w_buf[2 * i + 1] * out->volume_r + mix_buf[2 * i + 1];
1863 mix_buf[2 * i + 1] = CLIP(r);
1864 }
1865 } else {
1866 for (i = 0; i < (m - align) / 2 / 2; i++) {
1867
1868 int r;
1869 r = w_buf[2 * i] * out->volume_l;
1870 mix_buf[2 * i] = CLIP(r);
1871 r = w_buf[2 * i + 1] * out->volume_r;
1872 mix_buf[2 * i + 1] = CLIP(r);
1873 }
1874 }
1875#if 1
1876 if (enable_dump) {
1877 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1878 if (fp1) {
1879 int flen = fwrite((char *)mix_buf, 1, m - align, fp1);
1880 fclose(fp1);
1881 }
1882 }
1883#endif
1884 pthread_mutex_lock(&adev->pcm_write_lock);
1885 ret = pcm_write(out->pcm, mix_buf, m - align);
1886 pthread_mutex_unlock(&adev->pcm_write_lock);
1887 free(mix_buf);
1888 out->frame_write_sum += (m - align) / frame_size;
1889
1890 p += m - align;
1891 remain -= m - align;
1892 //ALOGI("pcm_write %d, remain %d", m - align, remain);
1893
1894 out->hw_sync_body_cnt -= (m - align);
1895 if (out->hw_sync_body_cnt == 0) {
1896 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1897 out->hw_sync_header_cnt = 0;
1898 continue;
1899 }
1900 }
1901
1902 if (align) {
1903 memcpy(&out->body_align[0], p, align);
1904 p += align;
1905 remain -= align;
1906 out->body_align_cnt = align;
1907 //ALOGI("align cache add %d, cnt = %d, remain = %d", align, out->body_align_cnt, remain);
1908
1909 out->hw_sync_body_cnt -= align;
1910 if (out->hw_sync_body_cnt == 0) {
1911 out->hw_sync_state = HW_SYNC_STATE_HEADER;
1912 out->hw_sync_header_cnt = 0;
1913 continue;
1914 }
1915 }
1916 }
1917 }
1918
1919 } else {
1920 struct aml_hal_mixer *mixer = &adev->hal_mixer;
1921 pthread_mutex_lock(&adev->pcm_write_lock);
1922 if (aml_hal_mixer_get_content(mixer) > 0) {
1923 pthread_mutex_lock(&mixer->lock);
1924 if (mixer->wp > mixer->rp) {
1925 pcm_write(out->pcm, mixer->start_buf + mixer->rp, mixer->wp - mixer->rp);
1926 } else {
1927 pcm_write(out->pcm, mixer->start_buf + mixer->wp, mixer->buf_size - mixer->rp);
1928 pcm_write(out->pcm, mixer->start_buf, mixer->wp);
1929 }
1930 mixer->rp = mixer->wp = 0;
1931 pthread_mutex_unlock(&mixer->lock);
1932 }
1933 ret = pcm_write(out->pcm, out_buffer, out_frames * frame_size);
1934 pthread_mutex_unlock(&adev->pcm_write_lock);
1935 out->frame_write_sum += out_frames;
1936 }
1937 }
1938
1939exit:
1940 latency_frames = out_get_latency(out) * out->config.rate / 1000;
1941 if (out->frame_write_sum >= latency_frames) {
1942 out->last_frames_postion = out->frame_write_sum - latency_frames;
1943 } else {
1944 out->last_frames_postion = out->frame_write_sum;
1945 }
1946 pthread_mutex_unlock(&out->lock);
1947 if (ret != 0) {
1948 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
1949 out_get_sample_rate(&stream->common) * 15 / 16);
1950 }
1951
1952 if (force_input_standby) {
1953 pthread_mutex_lock(&adev->lock);
1954 if (adev->active_input) {
1955 in = adev->active_input;
1956 pthread_mutex_lock(&in->lock);
1957 do_input_standby(in);
1958 pthread_mutex_unlock(&in->lock);
1959 }
1960 pthread_mutex_unlock(&adev->lock);
1961 }
1962 return oldBytes;
1963}
1964
1965static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
1966 size_t bytes)
1967{
1968 int ret = 0;
1969 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1970 struct aml_audio_device *adev = out->dev;
1971 size_t frame_size = audio_stream_out_frame_size(stream);
1972 size_t in_frames = bytes / frame_size;
1973 size_t out_frames;
1974 bool force_input_standby = false;
1975 int16_t *in_buffer = (int16_t *)buffer;
1976 struct aml_stream_in *in;
1977 uint ouput_len;
1978 char *data, *data_dst;
1979 volatile char *data_src;
1980 uint i, total_len;
1981 int codec_type = 0;
1982 int samesource_flag = 0;
1983 uint32_t latency_frames = 0;
1984 int need_mix = 0;
1985 short *mix_buf = NULL;
1986 unsigned char enable_dump = getprop_bool("media.audiohal.outdump");
1987
1988 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
1989 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
1990 * mutex
1991 */
1992 pthread_mutex_lock(&adev->lock);
1993 pthread_mutex_lock(&out->lock);
1994
1995#if 1
1996 if (enable_dump && out->hw_sync_mode == 0) {
1997 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1998 if (fp1) {
1999 int flen = fwrite((char *)buffer, 1, bytes, fp1);
2000 fclose(fp1);
2001 }
2002 }
2003#endif
2004
2005 if (out->standby) {
2006 ret = start_output_stream(out);
2007 if (ret != 0) {
2008 pthread_mutex_unlock(&adev->lock);
2009 ALOGE("start_output_stream failed");
2010 goto exit;
2011 }
2012 out->standby = false;
2013 /* a change in output device may change the microphone selection */
2014 if (adev->active_input &&
2015 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
2016 force_input_standby = true;
2017 }
2018 }
2019 pthread_mutex_unlock(&adev->lock);
2020#if 1
2021 /* Reduce number of channels, if necessary */
2022 if (popcount(out_get_channels(&stream->common)) >
2023 (int)out->config.channels) {
2024 unsigned int i;
2025
2026 /* Discard right channel */
2027 for (i = 1; i < in_frames; i++) {
2028 in_buffer[i] = in_buffer[i * 2];
2029 }
2030
2031 /* The frame size is now half */
2032 frame_size /= 2;
2033 }
2034#endif
2035 /* only use resampler if required */
2036 if (out->config.rate != out_get_sample_rate(&stream->common)) {
2037 out_frames = out->buffer_frames;
2038 out->resampler->resample_from_input(out->resampler,
2039 in_buffer, &in_frames,
2040 (int16_t*)out->buffer, &out_frames);
2041 in_buffer = (int16_t*)out->buffer;
2042 } else {
2043 out_frames = in_frames;
2044 }
2045 if (out->echo_reference != NULL) {
2046
2047 struct echo_reference_buffer b;
2048 b.raw = (void *)buffer;
2049 b.frame_count = in_frames;
2050 get_playback_delay(out, out_frames, &b);
2051 out->echo_reference->write(out->echo_reference, &b);
2052 }
2053
2054#if 1
2055 if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
2056 codec_type = get_sysfs_int("/sys/class/audiodsp/digital_codec");
2057 samesource_flag = get_sysfs_int("/sys/class/audiodsp/audio_samesource");
2058 if (samesource_flag == 0 && codec_type == 0) {
2059 ALOGI("to enable same source,need reset alsa,type %d,same source flag %d \n",
2060 codec_type, samesource_flag);
2061 pcm_stop(out->pcm);
2062 }
2063 }
2064#endif
2065
2066 struct aml_hal_mixer *mixer = &adev->hal_mixer;
2067 pthread_mutex_lock(&adev->pcm_write_lock);
2068 if (aml_hal_mixer_get_content(mixer) > 0) {
2069 pthread_mutex_lock(&mixer->lock);
2070 if (mixer->wp > mixer->rp) {
2071 pcm_write(out->pcm, mixer->start_buf + mixer->rp, mixer->wp - mixer->rp);
2072 } else {
2073 pcm_write(out->pcm, mixer->start_buf + mixer->wp, mixer->buf_size - mixer->rp);
2074 pcm_write(out->pcm, mixer->start_buf, mixer->wp);
2075 }
2076 mixer->rp = mixer->wp = 0;
2077 pthread_mutex_unlock(&mixer->lock);
2078 }
2079 ret = pcm_write(out->pcm, in_buffer, out_frames * frame_size);
2080 pthread_mutex_unlock(&adev->pcm_write_lock);
2081 out->frame_write_sum += out_frames;
2082
2083exit:
2084 latency_frames = out_get_latency(out) * out->config.rate / 1000;
2085 if (out->frame_write_sum >= latency_frames) {
2086 out->last_frames_postion = out->frame_write_sum - latency_frames;
2087 } else {
2088 out->last_frames_postion = out->frame_write_sum;
2089 }
2090 pthread_mutex_unlock(&out->lock);
2091 if (ret != 0) {
2092 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
2093 out_get_sample_rate(&stream->common) * 15 / 16);
2094 }
2095
2096 if (force_input_standby) {
2097 pthread_mutex_lock(&adev->lock);
2098 if (adev->active_input) {
2099 in = adev->active_input;
2100 pthread_mutex_lock(&in->lock);
2101 do_input_standby(in);
2102 pthread_mutex_unlock(&in->lock);
2103 }
2104 pthread_mutex_unlock(&adev->lock);
2105 }
2106 return bytes;
2107}
2108
2109static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buffer,
2110 size_t bytes)
2111{
2112 int ret = 0;
2113 struct aml_stream_out *out = (struct aml_stream_out *) stream;
2114 struct aml_audio_device *adev = out->dev;
2115 size_t frame_size = audio_stream_out_frame_size(stream);
2116 size_t in_frames = bytes / frame_size;
2117 bool force_input_standby = false;
2118 size_t out_frames = 0;
2119 void *buf;
2120 uint i, total_len;
2121 char prop[PROPERTY_VALUE_MAX];
2122 int codec_type = out->codec_type;
2123 int samesource_flag = 0;
2124 uint32_t latency_frames;
2125 uint64_t total_frame = 0;
2126 audio_hwsync_t *p_hwsync = &adev->hwsync;
2127 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
2128 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
2129 * mutex
2130 */
2131 out->bytes_write_total += bytes;
2132 ALOGV("out %p,dev %p out_write total size %lld\n", out, adev, out->bytes_write_total);
2133 pthread_mutex_lock(&adev->lock);
2134 pthread_mutex_lock(&out->lock);
2135 if (out->pause_status == true) {
2136 pthread_mutex_unlock(&adev->lock);
2137 pthread_mutex_unlock(&out->lock);
2138 ALOGI("call out_write when pause status,size %d,(%p)\n", bytes, out);
2139 return 0;
2140 }
2141 if ((out->standby) && adev->hw_sync_mode) {
2142 /*
2143 there are two types of raw data come to hdmi audio hal
2144 1) compressed audio data without IEC61937 wrapped
2145 2) compressed audio data with IEC61937 wrapped (typically from amlogic amadec source)
2146 we use the AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO to distiguwish the two cases.
2147 */
2148 if ((codec_type == TYPE_AC3 || codec_type == TYPE_EAC3) && (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
2149 spdifenc_init(out->pcm, out->hal_format);
2150 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
2151 }
2152 // todo: check timestamp header PTS discontinue for new sync point after seek
2153 aml_audio_hwsync_clear_status(out);
2154 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
2155 }
2156 if (out->standby) {
2157 ret = start_output_stream_direct(out);
2158 if (ret != 0) {
2159 pthread_mutex_unlock(&adev->lock);
2160 goto exit;
2161 }
2162 out->standby = 0;
2163 /* a change in output device may change the microphone selection */
2164 if (adev->active_input &&
2165 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
2166 force_input_standby = true;
2167 }
2168 }
2169 void *write_buf = NULL;
2170 int hwsync_cost_bytes = 0;
2171 if (adev->hw_sync_mode == 1) {
2172 int64_t cur_pts = 0xffffffff;
2173 int outsize = 0;
2174 char tempbuf[128];
2175 ALOGV("before aml_audio_hwsync_find_frame bytes %d\n", bytes);
2176 hwsync_cost_bytes = aml_audio_hwsync_find_frame(out, buffer, bytes, &cur_pts, &outsize);
2177 ALOGV("after aml_audio_hwsync_find_frame bytes remain %d,cost %d,outsize %d,pts %llx\n",
2178 bytes - hwsync_cost_bytes, hwsync_cost_bytes, outsize, cur_pts);
2179 //TODO,skip 3 frames after flush, to tmp fix seek pts discontinue issue.need dig more
2180 // to find out why seek ppint pts frame is remained after flush.WTF.
2181 if (out->skip_frame > 0) {
2182 out->skip_frame--;
2183 ALOGI("skip pts@%llx,cur frame size %d,cost size %d\n", cur_pts, outsize, hwsync_cost_bytes);
2184 pthread_mutex_unlock(&adev->lock);
2185 pthread_mutex_unlock(&out->lock);
2186 return hwsync_cost_bytes;
2187 }
2188 if (cur_pts != 0xffffffff && outsize > 0) {
2189 // if we got the frame body,which means we get a complete frame.
2190 //we take this frame pts as the first apts.
2191 //this can fix the seek discontinue,we got a fake frame,which maybe cached before the seek
2192 if (p_hwsync->first_apts_flag == false) {
2193 p_hwsync->first_apts_flag = true;
2194 p_hwsync->first_apts = cur_pts;
2195 sprintf(tempbuf, "AUDIO_START:0x%llx", cur_pts & 0xffffffff);
2196 ALOGI("tsync -> %s,frame size %d", tempbuf, outsize);
2197 if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
2198 ALOGE("set AUDIO_START failed \n");
2199 }
2200 } else {
2201 long apts;
2202 unsigned long latency = out_get_latency(out) * 90;
2203 // check PTS discontinue, which may happen when audio track switching
2204 // discontinue means PTS calculated based on first_apts and frame_write_sum
2205 // does not match the timestamp of next audio samples
2206 if (cur_pts > latency) {
2207 apts = (unsigned long)cur_pts - latency;
2208 } else {
2209 apts = 0;
2210 }
2211 if (0) { //abs(cur_pts -apts) > APTS_DISCONTINUE_THRESHOLD) {
2212 ALOGI("HW sync PTS discontinue, 0x%lx->0x%llx(from header) diff %llx,last apts %llx(from header)",
2213 apts, cur_pts, llabs(cur_pts - apts), p_hwsync->last_apts_from_header);
2214 p_hwsync->first_apts = cur_pts;
2215 sprintf(tempbuf, "AUDIO_TSTAMP_DISCONTINUITY:0x%llx", cur_pts);
2216 if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
2217 ALOGE("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
2218 }
2219 } else {
2220 long pcr = 0;
2221 if (get_sysfs_int16(TSYNC_PCRSCR, &pcr) == 0) {
2222 uint32_t apts_cal = apts & 0xffffffff;
2223 if (abs(pcr - apts) < SYSTIME_CORRECTION_THRESHOLD) {
2224 // do nothing
2225 }
2226 // limit the gap handle to 0.5~5 s.
2227 else if ((apts - pcr) > APTS_DISCONTINUE_THRESHOLD_MIN && (apts - pcr) < APTS_DISCONTINUE_THRESHOLD_MAX) {
2228 int insert_size = 0;
2229 int once_write_size = 0;
2230 if (out->codec_type == TYPE_EAC3) {
2231 insert_size = abs(apts - pcr) / 90 * 48 * 4 * 4;
2232 } else {
2233 insert_size = abs(apts - pcr) / 90 * 48 * 4;
2234 }
2235 insert_size = insert_size & (~63);
2236 ALOGI("audio gap %d ms ,need insert data %d\n", abs(apts - pcr) / 90, insert_size);
2237 char *insert_buf = (char*)malloc(8192);
2238 if (insert_buf == NULL) {
2239 ALOGE("malloc size failed \n");
2240 pthread_mutex_unlock(&adev->lock);
2241 goto exit;
2242 }
2243 memset(insert_buf, 0, 8192);
2244 while (insert_size > 0) {
2245 once_write_size = insert_size > 8192 ? 8192 : insert_size;
2246 ret = pcm_write(out->pcm, (void *) insert_buf, once_write_size);
2247 if (ret != 0) {
2248 ALOGE("pcm write failed\n");
2249 free(insert_buf);
2250 pthread_mutex_unlock(&adev->lock);
2251 goto exit;
2252 }
2253 insert_size -= once_write_size;
2254 }
2255 free(insert_buf);
2256 }
2257 //audio pts smaller than pcr,need skip frame.
2258 else if ((pcr - apts) > APTS_DISCONTINUE_THRESHOLD_MIN && (pcr - apts) < APTS_DISCONTINUE_THRESHOLD_MAX) {
2259 //we assume one frame duration is 32 ms for DD+(6 blocks X 1536 frames,48K sample rate)
2260 if (out->codec_type == TYPE_EAC3 && outsize > 0) {
2261 ALOGI("audio slow 0x%lx,skip frame @pts 0x%llx,pcr 0x%lx,cur apts 0x%lx\n", (pcr - apts), cur_pts, pcr, apts);
2262 out->frame_skip_sum += 1536;
2263 bytes = outsize;
2264 pthread_mutex_unlock(&adev->lock);
2265 goto exit;
2266 }
2267 } else {
2268 sprintf(tempbuf, "0x%lx", apts);
2269 ALOGI("tsync -> reset pcrscr 0x%lx -> 0x%lx, %s big,diff %d ms", pcr, apts, apts > pcr ? "apts" : "pcr", abs(apts - pcr) / 90);
2270#if 0
2271 int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, tempbuf);
2272 if (ret_val == -1) {
2273 ALOGE("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
2274 }
2275#endif
2276 }
2277 }
2278 }
2279 }
2280 }
2281 if (outsize > 0) {
2282 in_frames = outsize / frame_size;
2283 write_buf = p_hwsync->hw_sync_body_buf;
2284 } else {
2285 bytes = hwsync_cost_bytes;
2286 pthread_mutex_unlock(&adev->lock);
2287 goto exit;
2288 }
2289 } else {
2290 write_buf = (void *) buffer;
2291 }
2292 pthread_mutex_unlock(&adev->lock);
2293 out_frames = in_frames;
2294 buf = (void *) write_buf;
2295 if (getprop_bool("media.hdmihal.outdump")) {
2296 FILE *fp1 = fopen("/data/tmp/hdmi_audio_out.pcm", "a+");
2297 if (fp1) {
2298 int flen = fwrite((char *)buffer, 1, out_frames * frame_size, fp1);
2299 LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size);
2300 fclose(fp1);
2301 } else {
2302 LOGFUNC("could not open file:/data/hdmi_audio_out.pcm");
2303 }
2304 }
2305 if (codec_type_is_raw_data(out->codec_type) && !(out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
2306 //here to do IEC61937 pack
2307 ALOGV("IEC61937 write size %d,hw_sync_mode %d,flag %x\n", out_frames * frame_size, adev->hw_sync_mode, out->flags);
2308 if (out->codec_type > 0) {
2309 // compressed audio DD/DD+
2310 bytes = spdifenc_write((void *) buf, out_frames * frame_size);
2311 //need return actual size of this burst write
2312 if (adev->hw_sync_mode == 1) {
2313 bytes = hwsync_cost_bytes;
2314 }
2315 ALOGV("spdifenc_write return %d\n", bytes);
2316 if (out->codec_type == TYPE_EAC3) {
2317 out->frame_write_sum = spdifenc_get_total() / 16 + out->spdif_enc_init_frame_write_sum;
2318 } else {
2319 out->frame_write_sum = spdifenc_get_total() / 4 + out->spdif_enc_init_frame_write_sum;
2320 }
2321 ALOGV("out %p,spdifenc_get_total() / 4 %lld\n", out, spdifenc_get_total() / 16);
2322 }
2323 goto exit;
2324 }
2325 if (!out->standby) {
2326 if (out->multich == 8) {
2327 int *p32 = NULL;
2328 short *p16 = (short *) buf;
2329 short *p16_temp;
2330 int i, NumSamps;
2331 NumSamps = out_frames * frame_size / sizeof(short);
2332 p32 = malloc(NumSamps * sizeof(int));
2333 if (p32 != NULL) {
2334 //here to swap the channnl data here
2335 //actual now:L,missing,R,RS,RRS,,LS,LRS,missing
2336 //expect L,C,R,RS,RRS,LRS,LS,LFE (LFE comes from to center)
2337 //actual audio data layout L,R,C,none/LFE,LRS,RRS,LS,RS
2338 p16_temp = (short *) p32;
2339 for (i = 0; i < NumSamps; i = i + 8) {
2340 p16_temp[0 + i]/*L*/ = p16[0 + i];
2341 p16_temp[1 + i]/*R*/ = p16[1 + i];
2342 p16_temp[2 + i] /*LFE*/ = p16[3 + i];
2343 p16_temp[3 + i] /*C*/ = p16[2 + i];
2344 p16_temp[4 + i] /*LS*/ = p16[6 + i];
2345 p16_temp[5 + i] /*RS*/ = p16[7 + i];
2346 p16_temp[6 + i] /*LRS*/ = p16[4 + i];
2347 p16_temp[7 + i]/*RRS*/ = p16[5 + i];
2348 }
2349 memcpy(p16, p16_temp, NumSamps * sizeof(short));
2350 for (i = 0; i < NumSamps; i++) { //suppose 16bit/8ch PCM
2351 p32[i] = p16[i] << 16;
2352 }
2353 ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
2354 free(p32);
2355 }
2356 } else if (out->multich == 6) {
2357 int *p32 = NULL;
2358 short *p16 = (short *) buf;
2359 short *p16_temp;
2360 int i, j, NumSamps, real_samples;
2361 real_samples = out_frames * frame_size / sizeof(short);
2362 NumSamps = real_samples * 8 / 6;
2363 //ALOGI("6ch to 8 ch real %d, to %d,bytes %d,frame size %d\n",real_samples,NumSamps,bytes,frame_size);
2364 p32 = malloc(NumSamps * sizeof(int));
2365 if (p32 != NULL) {
2366 p16_temp = (short *) p32;
2367 for (i = 0; i < real_samples; i = i + 6) {
2368 p16_temp[0 + i]/*L*/ = p16[0 + i];
2369 p16_temp[1 + i]/*R*/ = p16[1 + i];
2370 p16_temp[2 + i] /*LFE*/ = p16[3 + i];
2371 p16_temp[3 + i] /*C*/ = p16[2 + i];
2372 p16_temp[4 + i] /*LS*/ = p16[4 + i];
2373 p16_temp[5 + i] /*RS*/ = p16[5 + i];
2374 }
2375 memcpy(p16, p16_temp, real_samples * sizeof(short));
2376 memset(p32, 0, NumSamps * sizeof(int));
2377 for (i = 0, j = 0; j < NumSamps; i = i + 6, j = j + 8) { //suppose 16bit/8ch PCM
2378 p32[j] = p16[i] << 16;
2379 p32[j + 1] = p16[i + 1] << 16;
2380 p32[j + 2] = p16[i + 2] << 16;
2381 p32[j + 3] = p16[i + 3] << 16;
2382 p32[j + 4] = p16[i + 4] << 16;
2383 p32[j + 5] = p16[i + 5] << 16;
2384 }
2385 ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
2386 free(p32);
2387 }
2388 } else {
2389#if 0
2390 codec_type =
2391 get_sysfs_int("/sys/class/audiodsp/digital_codec");
2392 samesource_flag =
2393 get_sysfs_int("/sys/class/audiodsp/audio_samesource");
2394 if (out->last_codec_type > 0 && codec_type != out->last_codec_type) {
2395 samesource_flag = 1;
2396 }
2397 if (samesource_flag == 1 && codec_type) {
2398 ALOGI
2399 ("to disable same source,need reset alsa,last %d,type %d,same source flag %d ,\n",
2400 out->last_codec_type, codec_type, samesource_flag);
2401 out->last_codec_type = codec_type;
2402 pcm_stop(out->pcm);
2403 }
2404#endif
2405 ALOGV("write size %d\n", out_frames * frame_size);
2406 ret = pcm_write(out->pcm, (void *) buf, out_frames * frame_size);
2407 if (ret == 0) {
2408 out->frame_write_sum += out_frames;
2409 }
2410 }
2411 }
2412exit:
2413 total_frame = out->frame_write_sum + out->frame_skip_sum;
2414 latency_frames = out_get_latency(out) * out->config.rate / 1000;
2415 if (total_frame >= latency_frames) {
2416 out->last_frames_postion = total_frame - latency_frames;
2417 } else {
2418 out->last_frames_postion = total_frame;
2419 }
2420 pthread_mutex_unlock(&out->lock);
2421 if (ret != 0) {
2422 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
2423 out_get_sample_rate(&stream->common));
2424 }
2425 return bytes;
2426}
2427
2428static ssize_t out_write_tv(struct audio_stream_out *stream, const void* buffer,
2429 size_t bytes)
2430{
2431 // TV temporarily use legacy out write.
2432 /* TODO: add TV platform specific write here */
2433 return out_write_legacy(stream, buffer, bytes);
2434}
2435
2436static int out_get_render_position(const struct audio_stream_out *stream,
2437 uint32_t *dsp_frames)
2438{
2439 struct aml_stream_out *out = (struct aml_stream_out *)stream;
2440 uint64_t dsp_frame_int64 = 0;
2441 *dsp_frames = out->last_frames_postion;
2442 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
2443 dsp_frame_int64 = out->last_frames_postion / out->raw_61937_frame_size;
2444 *dsp_frames = (uint32_t)(dsp_frame_int64 & 0xffffffff);
2445 if (out->last_dsp_frame > *dsp_frames) {
2446 ALOGI("maybe uint32_t wraparound,print something,last %u,now %u", out->last_dsp_frame, *dsp_frames);
2447 ALOGI("wraparound,out_get_render_position return %u,playback time %llu ms,sr %d\n", *dsp_frames,
2448 out->last_frames_postion * 1000 / out->raw_61937_frame_size / out->config.rate, out->config.rate);
2449
2450 }
2451 }
2452 ALOGV("out_get_render_position %d\n", *dsp_frames);
2453 return 0;
2454}
2455
2456static int out_add_audio_effect(const struct audio_stream *stream __unused, effect_handle_t effect __unused)
2457{
2458 return 0;
2459}
2460
2461static int out_remove_audio_effect(const struct audio_stream *stream __unused, effect_handle_t effect __unused)
2462{
2463 return 0;
2464}
2465static int out_get_next_write_timestamp(const struct audio_stream_out *stream __unused,
2466 int64_t *timestamp __unused)
2467{
2468 return -EINVAL;
2469}
2470
2471//actually maybe it be not useful now except pass CTS_TEST:
2472// run cts -c android.media.cts.AudioTrackTest -m testGetTimestamp
2473static int out_get_presentation_position(const struct audio_stream_out *stream, uint64_t *frames, struct timespec *timestamp)
2474{
2475 struct aml_stream_out *out = (struct aml_stream_out *)stream;
2476 if (frames != NULL) {
2477 *frames = out->last_frames_postion;
2478 }
2479
2480 if (timestamp != NULL) {
2481 clock_gettime(CLOCK_MONOTONIC, timestamp);
2482 }
2483 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
2484 *frames = out->last_frames_postion / out->raw_61937_frame_size;
2485 }
2486 ALOGV("out_get_presentation_position %lld\n", *frames);
2487
2488 return 0;
2489}
2490static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
2491 struct resampler_buffer* buffer);
2492static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2493 struct resampler_buffer* buffer);
2494
2495
2496/** audio_stream_in implementation **/
2497
2498/* must be called with hw device and input stream mutexes locked */
2499static int start_input_stream(struct aml_stream_in *in)
2500{
2501 int ret = 0;
2502 unsigned int card = CARD_AMLOGIC_BOARD;
2503 unsigned int port = PORT_I2S;
2504
2505 struct aml_audio_device *adev = in->dev;
2506 LOGFUNC("%s(need_echo_reference=%d, channels=%d, rate=%d, requested_rate=%d, mode= %d)",
2507 __FUNCTION__, in->need_echo_reference, in->config.channels, in->config.rate, in->requested_rate, adev->mode);
2508 adev->active_input = in;
2509
2510 if (adev->mode != AUDIO_MODE_IN_CALL) {
2511 adev->in_device &= ~AUDIO_DEVICE_IN_ALL;
2512 adev->in_device |= in->device;
2513 select_devices(adev);
2514 }
2515 card = get_aml_card();
2516
2517 ALOGV("%s(in->requested_rate=%d, in->config.rate=%d)",
2518 __FUNCTION__, in->requested_rate, in->config.rate);
2519 if (adev->in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2520 port = PORT_PCM;
2521 } else if (getprop_bool("sys.hdmiIn.Capture")) {
2522 port = PORT_SPDIF;
2523 } else {
2524 port = PORT_I2S;
2525 }
2526 LOGFUNC("*%s, open card(%d) port(%d)-------", __FUNCTION__, card, port);
2527 in->config.period_size = CAPTURE_PERIOD_SIZE;
2528 if (in->need_echo_reference && in->echo_reference == NULL) {
2529 in->echo_reference = get_echo_reference(adev,
2530 AUDIO_FORMAT_PCM_16_BIT,
2531 in->config.channels,
2532 in->requested_rate);
2533 LOGFUNC("%s(after get_echo_ref.... now in->echo_reference = %p)", __FUNCTION__, in->echo_reference);
2534 }
2535 /* this assumes routing is done previously */
2536 in->pcm = pcm_open(card, port, PCM_IN, &in->config);
2537 if (!pcm_is_ready(in->pcm)) {
2538 ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm));
2539 pcm_close(in->pcm);
2540 adev->active_input = NULL;
2541 return -ENOMEM;
2542 }
2543 ALOGD("pcm_open in: card(%d), port(%d)", card, port);
2544
2545 /* if no supported sample rate is available, use the resampler */
2546 if (in->resampler) {
2547 in->resampler->reset(in->resampler);
2548 in->frames_in = 0;
2549 }
2550 return 0;
2551}
2552
2553static uint32_t in_get_sample_rate(const struct audio_stream *stream)
2554{
2555 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2556
2557 return in->requested_rate;
2558}
2559
2560static int in_set_sample_rate(struct audio_stream *stream __unused, uint32_t rate __unused)
2561{
2562 return 0;
2563}
2564
2565static size_t in_get_buffer_size(const struct audio_stream *stream)
2566{
2567 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2568
2569 return get_input_buffer_size(in->config.period_size, in->config.rate,
2570 AUDIO_FORMAT_PCM_16_BIT,
2571 in->config.channels);
2572}
2573
2574static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
2575{
2576 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2577
2578 if (in->config.channels == 1) {
2579 return AUDIO_CHANNEL_IN_MONO;
2580 } else {
2581 return AUDIO_CHANNEL_IN_STEREO;
2582 }
2583}
2584
2585static audio_format_t in_get_format(const struct audio_stream *stream __unused)
2586{
2587 return AUDIO_FORMAT_PCM_16_BIT;
2588}
2589
2590static int in_set_format(struct audio_stream *stream __unused, audio_format_t format __unused)
2591{
2592 return 0;
2593}
2594
2595/* must be called with hw device and input stream mutexes locked */
2596static int do_input_standby(struct aml_stream_in *in)
2597{
2598 struct aml_audio_device *adev = in->dev;
2599
2600 LOGFUNC("%s(%p)", __FUNCTION__, in);
2601 if (!in->standby) {
2602 pcm_close(in->pcm);
2603 in->pcm = NULL;
2604
2605 adev->active_input = 0;
2606 if (adev->mode != AUDIO_MODE_IN_CALL) {
2607 adev->in_device &= ~AUDIO_DEVICE_IN_ALL;
2608 //select_input_device(adev);
2609 }
2610
2611 if (in->echo_reference != NULL) {
2612 /* stop reading from echo reference */
2613 in->echo_reference->read(in->echo_reference, NULL);
2614 put_echo_reference(adev, in->echo_reference);
2615 in->echo_reference = NULL;
2616 }
2617
2618 in->standby = 1;
2619#if 0
2620 LOGFUNC("%s : output_standby=%d,input_standby=%d",
2621 __FUNCTION__, output_standby, input_standby);
2622 if (output_standby && input_standby) {
2623 reset_mixer_state(adev->ar);
2624 update_mixer_state(adev->ar);
2625 }
2626#endif
2627 }
2628 return 0;
2629}
2630static int in_standby(struct audio_stream *stream)
2631{
2632 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2633 int status;
2634 LOGFUNC("%s(%p)", __FUNCTION__, stream);
2635
2636 pthread_mutex_lock(&in->dev->lock);
2637 pthread_mutex_lock(&in->lock);
2638 status = do_input_standby(in);
2639 pthread_mutex_unlock(&in->lock);
2640 pthread_mutex_unlock(&in->dev->lock);
2641 return status;
2642}
2643
2644static int in_dump(const struct audio_stream *stream __unused, int fd __unused)
2645{
2646 return 0;
2647}
2648
2649static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
2650{
2651 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2652 struct aml_audio_device *adev = in->dev;
2653 struct str_parms *parms;
2654 char *str;
2655 char value[32];
2656 int ret, val = 0;
2657 bool do_standby = false;
2658
2659 LOGFUNC("%s(%p, %s)", __FUNCTION__, stream, kvpairs);
2660 parms = str_parms_create_str(kvpairs);
2661
2662 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
2663
2664 pthread_mutex_lock(&adev->lock);
2665 pthread_mutex_lock(&in->lock);
2666 if (ret >= 0) {
2667 val = atoi(value);
2668 /* no audio source uses val == 0 */
2669 if ((in->source != val) && (val != 0)) {
2670 in->source = val;
2671 do_standby = true;
2672 }
2673 }
2674
2675 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2676 if (ret >= 0) {
2677 val = atoi(value) & ~AUDIO_DEVICE_BIT_IN;
2678 if ((in->device != val) && (val != 0)) {
2679 in->device = val;
2680 do_standby = true;
2681 }
2682 }
2683
2684 if (do_standby) {
2685 do_input_standby(in);
2686 }
2687 pthread_mutex_unlock(&in->lock);
2688 pthread_mutex_unlock(&adev->lock);
2689
2690 int framesize = 0;
2691 ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_FRAME_COUNT, &framesize);
2692
2693 if (ret >= 0) {
2694 if (framesize > 0) {
2695 ALOGI("Reset audio input hw frame size from %d to %d\n",
2696 in->config.period_size * in->config.period_count, framesize);
2697 in->config.period_size = framesize / in->config.period_count;
2698 pthread_mutex_lock(&adev->lock);
2699 pthread_mutex_lock(&in->lock);
2700
2701 if (!in->standby && (in == adev->active_input)) {
2702 do_input_standby(in);
2703 start_input_stream(in);
2704 in->standby = 0;
2705 }
2706
2707 pthread_mutex_unlock(&in->lock);
2708 pthread_mutex_unlock(&adev->lock);
2709 }
2710 }
2711
2712 str_parms_destroy(parms);
2713 return ret;
2714}
2715
2716static char * in_get_parameters(const struct audio_stream *stream __unused,
2717 const char *keys __unused)
2718{
2719 return strdup("");
2720}
2721
2722static int in_set_gain(struct audio_stream_in *stream __unused, float gain __unused)
2723{
2724 return 0;
2725}
2726
2727static void get_capture_delay(struct aml_stream_in *in,
2728 size_t frames __unused,
2729 struct echo_reference_buffer *buffer)
2730{
2731 /* read frames available in kernel driver buffer */
2732 size_t kernel_frames;
2733 struct timespec tstamp;
2734 long buf_delay;
2735 long rsmp_delay;
2736 long kernel_delay;
2737 long delay_ns;
2738 int rsmp_mul = in->config.rate / VX_NB_SAMPLING_RATE;
2739 if (pcm_get_htimestamp(in->pcm, &kernel_frames, &tstamp) < 0) {
2740 buffer->time_stamp.tv_sec = 0;
2741 buffer->time_stamp.tv_nsec = 0;
2742 buffer->delay_ns = 0;
2743 ALOGW("read get_capture_delay(): pcm_htimestamp error");
2744 return;
2745 }
2746
2747 /* read frames available in audio HAL input buffer
2748 * add number of frames being read as we want the capture time of first sample
2749 * in current buffer */
2750 buf_delay = (long)(((int64_t)(in->frames_in + in->proc_frames_in * rsmp_mul) * 1000000000)
2751 / in->config.rate);
2752 /* add delay introduced by resampler */
2753 rsmp_delay = 0;
2754 if (in->resampler) {
2755 rsmp_delay = in->resampler->delay_ns(in->resampler);
2756 }
2757
2758 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
2759
2760 delay_ns = kernel_delay + buf_delay + rsmp_delay;
2761
2762 buffer->time_stamp = tstamp;
2763 buffer->delay_ns = delay_ns;
2764 /*ALOGV("get_capture_delay time_stamp = [%ld].[%ld], delay_ns: [%d],"
2765 " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], "
2766 "in->frames_in:[%d], in->proc_frames_in:[%d], frames:[%d]",
2767 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns,
2768 kernel_delay, buf_delay, rsmp_delay, kernel_frames,
2769 in->frames_in, in->proc_frames_in, frames);*/
2770
2771}
2772
2773static int32_t update_echo_reference(struct aml_stream_in *in, size_t frames)
2774{
2775 struct echo_reference_buffer b;
2776 b.delay_ns = 0;
2777
2778 ALOGV("update_echo_reference, frames = [%d], in->ref_frames_in = [%d], "
2779 "b.frame_count = [%d]", frames, in->ref_frames_in, frames - in->ref_frames_in);
2780 if (in->ref_frames_in < frames) {
2781 if (in->ref_buf_size < frames) {
2782 in->ref_buf_size = frames;
2783 in->ref_buf = (int16_t *)realloc(in->ref_buf,
2784 in->ref_buf_size * in->config.channels * sizeof(int16_t));
2785 }
2786
2787 b.frame_count = frames - in->ref_frames_in;
2788 b.raw = (void *)(in->ref_buf + in->ref_frames_in * in->config.channels);
2789
2790 get_capture_delay(in, frames, &b);
2791 LOGFUNC("update_echo_reference return ::b.delay_ns=%d", b.delay_ns);
2792
2793 if (in->echo_reference->read(in->echo_reference, &b) == 0) {
2794 in->ref_frames_in += b.frame_count;
2795 ALOGV("update_echo_reference: in->ref_frames_in:[%d], "
2796 "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]",
2797 in->ref_frames_in, in->ref_buf_size, frames, b.frame_count);
2798 }
2799 } else {
2800 ALOGW("update_echo_reference: NOT enough frames to read ref buffer");
2801 }
2802 return b.delay_ns;
2803}
2804
2805static int set_preprocessor_param(effect_handle_t handle,
2806 effect_param_t *param)
2807{
2808 uint32_t size = sizeof(int);
2809 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
2810 param->vsize;
2811
2812 int status = (*handle)->command(handle,
2813 EFFECT_CMD_SET_PARAM,
2814 sizeof(effect_param_t) + psize,
2815 param,
2816 &size,
2817 &param->status);
2818 if (status == 0) {
2819 status = param->status;
2820 }
2821
2822 return status;
2823}
2824
2825static int set_preprocessor_echo_delay(effect_handle_t handle,
2826 int32_t delay_us)
2827{
2828 uint32_t buf[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
2829 effect_param_t *param = (effect_param_t *)buf;
2830
2831 param->psize = sizeof(uint32_t);
2832 param->vsize = sizeof(uint32_t);
2833 *(uint32_t *)param->data = AEC_PARAM_ECHO_DELAY;
2834 *((int32_t *)param->data + 1) = delay_us;
2835
2836 return set_preprocessor_param(handle, param);
2837}
2838
2839static void push_echo_reference(struct aml_stream_in *in, size_t frames)
2840{
2841 /* read frames from echo reference buffer and update echo delay
2842 * in->ref_frames_in is updated with frames available in in->ref_buf */
2843 int32_t delay_us = update_echo_reference(in, frames) / 1000;
2844 int i;
2845 audio_buffer_t buf;
2846
2847 if (in->ref_frames_in < frames) {
2848 frames = in->ref_frames_in;
2849 }
2850
2851 buf.frameCount = frames;
2852 buf.raw = in->ref_buf;
2853
2854 for (i = 0; i < in->num_preprocessors; i++) {
2855 if ((*in->preprocessors[i])->process_reverse == NULL) {
2856 continue;
2857 }
2858
2859 (*in->preprocessors[i])->process_reverse(in->preprocessors[i],
2860 &buf,
2861 NULL);
2862 set_preprocessor_echo_delay(in->preprocessors[i], delay_us);
2863 }
2864
2865 in->ref_frames_in -= buf.frameCount;
2866 if (in->ref_frames_in) {
2867 memcpy(in->ref_buf,
2868 in->ref_buf + buf.frameCount * in->config.channels,
2869 in->ref_frames_in * in->config.channels * sizeof(int16_t));
2870 }
2871}
2872
2873static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
2874 struct resampler_buffer* buffer)
2875{
2876 struct aml_stream_in *in;
2877
2878 if (buffer_provider == NULL || buffer == NULL) {
2879 return -EINVAL;
2880 }
2881
2882 in = (struct aml_stream_in *)((char *)buffer_provider -
2883 offsetof(struct aml_stream_in, buf_provider));
2884
2885 if (in->pcm == NULL) {
2886 buffer->raw = NULL;
2887 buffer->frame_count = 0;
2888 in->read_status = -ENODEV;
2889 return -ENODEV;
2890 }
2891
2892 if (in->frames_in == 0) {
2893 in->read_status = pcm_read(in->pcm, (void*)in->buffer,
2894 in->config.period_size * audio_stream_in_frame_size(&in->stream));
2895 if (in->read_status != 0) {
2896 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
2897 buffer->raw = NULL;
2898 buffer->frame_count = 0;
2899 return in->read_status;
2900 }
2901 in->frames_in = in->config.period_size;
2902 }
2903
2904 buffer->frame_count = (buffer->frame_count > in->frames_in) ?
2905 in->frames_in : buffer->frame_count;
2906 buffer->i16 = in->buffer + (in->config.period_size - in->frames_in) *
2907 in->config.channels;
2908
2909 return in->read_status;
2910
2911}
2912
2913static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2914 struct resampler_buffer* buffer)
2915{
2916 struct aml_stream_in *in;
2917
2918 if (buffer_provider == NULL || buffer == NULL) {
2919 return;
2920 }
2921
2922 in = (struct aml_stream_in *)((char *)buffer_provider -
2923 offsetof(struct aml_stream_in, buf_provider));
2924
2925 in->frames_in -= buffer->frame_count;
2926}
2927
2928/* read_frames() reads frames from kernel driver, down samples to capture rate
2929 * if necessary and output the number of frames requested to the buffer specified */
2930static ssize_t read_frames(struct aml_stream_in *in, void *buffer, ssize_t frames)
2931{
2932 ssize_t frames_wr = 0;
2933
2934 while (frames_wr < frames) {
2935 size_t frames_rd = frames - frames_wr;
2936 if (in->resampler != NULL) {
2937 in->resampler->resample_from_provider(in->resampler,
2938 (int16_t *)((char *)buffer +
2939 frames_wr * audio_stream_in_frame_size(&in->stream)),
2940 &frames_rd);
2941 } else {
2942 struct resampler_buffer buf = {
2943 { .raw = NULL, },
2944 .frame_count = frames_rd,
2945 };
2946 get_next_buffer(&in->buf_provider, &buf);
2947 if (buf.raw != NULL) {
2948 memcpy((char *)buffer +
2949 frames_wr * audio_stream_in_frame_size(&in->stream),
2950 buf.raw,
2951 buf.frame_count * audio_stream_in_frame_size(&in->stream));
2952 frames_rd = buf.frame_count;
2953 }
2954 release_buffer(&in->buf_provider, &buf);
2955 }
2956 /* in->read_status is updated by getNextBuffer() also called by
2957 * in->resampler->resample_from_provider() */
2958 if (in->read_status != 0) {
2959 return in->read_status;
2960 }
2961
2962 frames_wr += frames_rd;
2963 }
2964 return frames_wr;
2965}
2966
2967/* process_frames() reads frames from kernel driver (via read_frames()),
2968 * calls the active audio pre processings and output the number of frames requested
2969 * to the buffer specified */
2970static ssize_t process_frames(struct aml_stream_in *in, void* buffer, ssize_t frames)
2971{
2972 ssize_t frames_wr = 0;
2973 audio_buffer_t in_buf;
2974 audio_buffer_t out_buf;
2975 int i;
2976
2977 //LOGFUNC("%s(%d, %p, %ld)", __FUNCTION__, in->num_preprocessors, buffer, frames);
2978 while (frames_wr < frames) {
2979 /* first reload enough frames at the end of process input buffer */
2980 if (in->proc_frames_in < (size_t)frames) {
2981 ssize_t frames_rd;
2982
2983 if (in->proc_buf_size < (size_t)frames) {
2984 in->proc_buf_size = (size_t)frames;
2985 in->proc_buf = (int16_t *)realloc(in->proc_buf,
2986 in->proc_buf_size *
2987 in->config.channels * sizeof(int16_t));
2988 ALOGV("process_frames(): in->proc_buf %p size extended to %d frames",
2989 in->proc_buf, in->proc_buf_size);
2990 }
2991 frames_rd = read_frames(in,
2992 in->proc_buf +
2993 in->proc_frames_in * in->config.channels,
2994 frames - in->proc_frames_in);
2995 if (frames_rd < 0) {
2996 frames_wr = frames_rd;
2997 break;
2998 }
2999 in->proc_frames_in += frames_rd;
3000 }
3001
3002 if (in->echo_reference != NULL) {
3003 push_echo_reference(in, in->proc_frames_in);
3004 }
3005
3006 /* in_buf.frameCount and out_buf.frameCount indicate respectively
3007 * the maximum number of frames to be consumed and produced by process() */
3008 in_buf.frameCount = in->proc_frames_in;
3009 in_buf.s16 = in->proc_buf;
3010 out_buf.frameCount = frames - frames_wr;
3011 out_buf.s16 = (int16_t *)buffer + frames_wr * in->config.channels;
3012
3013 for (i = 0; i < in->num_preprocessors; i++)
3014 (*in->preprocessors[i])->process(in->preprocessors[i],
3015 &in_buf,
3016 &out_buf);
3017
3018 /* process() has updated the number of frames consumed and produced in
3019 * in_buf.frameCount and out_buf.frameCount respectively
3020 * move remaining frames to the beginning of in->proc_buf */
3021 in->proc_frames_in -= in_buf.frameCount;
3022 if (in->proc_frames_in) {
3023 memcpy(in->proc_buf,
3024 in->proc_buf + in_buf.frameCount * in->config.channels,
3025 in->proc_frames_in * in->config.channels * sizeof(int16_t));
3026 }
3027
3028 /* if not enough frames were passed to process(), read more and retry. */
3029 if (out_buf.frameCount == 0) {
3030 continue;
3031 }
3032
3033 frames_wr += out_buf.frameCount;
3034 }
3035 return frames_wr;
3036}
3037
3038static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
3039 size_t bytes)
3040{
3041 int ret = 0;
3042 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3043 struct aml_audio_device *adev = in->dev;
3044 size_t frames_rq = bytes / audio_stream_in_frame_size(&in->stream);
3045
3046 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
3047 * on the input stream mutex - e.g. executing select_mode() while holding the hw device
3048 * mutex
3049 */
3050 pthread_mutex_lock(&adev->lock);
3051 pthread_mutex_lock(&in->lock);
3052 if (in->standby) {
3053 ret = start_input_stream(in);
3054 if (ret == 0) {
3055 in->standby = 0;
3056 }
3057 }
3058 pthread_mutex_unlock(&adev->lock);
3059
3060 if (ret < 0) {
3061 goto exit;
3062 }
3063
3064 if (in->num_preprocessors != 0) {
3065 ret = process_frames(in, buffer, frames_rq);
3066 } else if (in->resampler != NULL) {
3067 ret = read_frames(in, buffer, frames_rq);
3068 } else {
3069 ret = pcm_read(in->pcm, buffer, bytes);
3070 }
3071
3072 if (ret > 0) {
3073 ret = 0;
3074 }
3075
3076 if (ret == 0 && adev->mic_mute) {
3077 memset(buffer, 0, bytes);
3078 }
3079
3080#if 0
3081 FILE *dump_fp = NULL;
3082
3083 dump_fp = fopen("/data/audio_in.pcm", "a+");
3084 if (dump_fp != NULL) {
3085 fwrite(buffer, bytes, 1, dump_fp);
3086 fclose(dump_fp);
3087 } else {
3088 ALOGW("[Error] Can't write to /data/dump_in.pcm");
3089 }
3090#endif
3091
3092exit:
3093 if (ret < 0)
3094 usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
3095 in_get_sample_rate(&stream->common));
3096
3097 pthread_mutex_unlock(&in->lock);
3098 return bytes;
3099
3100}
3101
3102static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream __unused)
3103{
3104 return 0;
3105}
3106
3107static int in_add_audio_effect(const struct audio_stream *stream,
3108 effect_handle_t effect)
3109{
3110 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3111 int status;
3112 effect_descriptor_t desc;
3113
3114 pthread_mutex_lock(&in->dev->lock);
3115 pthread_mutex_lock(&in->lock);
3116 if (in->num_preprocessors >= MAX_PREPROCESSORS) {
3117 status = -ENOSYS;
3118 goto exit;
3119 }
3120
3121 status = (*effect)->get_descriptor(effect, &desc);
3122 if (status != 0) {
3123 goto exit;
3124 }
3125
3126 in->preprocessors[in->num_preprocessors++] = effect;
3127
3128 if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3129 in->need_echo_reference = true;
3130 do_input_standby(in);
3131 }
3132
3133exit:
3134
3135 pthread_mutex_unlock(&in->lock);
3136 pthread_mutex_unlock(&in->dev->lock);
3137 return status;
3138}
3139
3140static int in_remove_audio_effect(const struct audio_stream *stream,
3141 effect_handle_t effect)
3142{
3143 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3144 int i;
3145 int status = -EINVAL;
3146 bool found = false;
3147 effect_descriptor_t desc;
3148
3149 pthread_mutex_lock(&in->dev->lock);
3150 pthread_mutex_lock(&in->lock);
3151 if (in->num_preprocessors <= 0) {
3152 status = -ENOSYS;
3153 goto exit;
3154 }
3155
3156 for (i = 0; i < in->num_preprocessors; i++) {
3157 if (found) {
3158 in->preprocessors[i - 1] = in->preprocessors[i];
3159 continue;
3160 }
3161 if (in->preprocessors[i] == effect) {
3162 in->preprocessors[i] = NULL;
3163 status = 0;
3164 found = true;
3165 }
3166 }
3167
3168 if (status != 0) {
3169 goto exit;
3170 }
3171
3172 in->num_preprocessors--;
3173
3174 status = (*effect)->get_descriptor(effect, &desc);
3175 if (status != 0) {
3176 goto exit;
3177 }
3178 if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3179 in->need_echo_reference = false;
3180 do_input_standby(in);
3181 }
3182
3183exit:
3184
3185 pthread_mutex_unlock(&in->lock);
3186 pthread_mutex_unlock(&in->dev->lock);
3187 return status;
3188}
3189
3190static int adev_open_output_stream(struct audio_hw_device *dev,
3191 audio_io_handle_t handle __unused,
3192 audio_devices_t devices,
3193 audio_output_flags_t flags,
3194 struct audio_config *config,
3195 struct audio_stream_out **stream_out,
3196 const char *address __unused)
3197{
3198 struct aml_audio_device *ladev = (struct aml_audio_device *)dev;
3199 struct aml_stream_out *out;
3200 int channel_count = popcount(config->channel_mask);
3201 int digital_codec;
3202 bool direct = false;
3203 int ret;
3204 bool hwsync_lpcm = false;
3205 ALOGI("**enter %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d, flags=0x%x)", __FUNCTION__, devices,
3206 config->format, config->channel_mask, config->sample_rate, flags);
3207
3208 out = (struct aml_stream_out *)calloc(1, sizeof(struct aml_stream_out));
3209 if (!out) {
3210 return -ENOMEM;
3211 }
3212
3213 out->flags = flags;
3214 if (getprop_bool("ro.platform.has.tvuimode")) {
3215 out->is_tv_platform = 1;
3216 }
3217 out->config = pcm_config_out;
3218 //hwsync with LPCM still goes to out_write_legacy
3219 hwsync_lpcm = (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(config->format));
3220 ALOGI("hwsync_lpcm %d\n", hwsync_lpcm);
3221 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY || hwsync_lpcm) {
3222 out->stream.common.get_channels = out_get_channels;
3223 out->stream.common.get_format = out_get_format;
3224 out->stream.write = out_write_legacy;
3225 out->stream.common.standby = out_standby;
3226
3227 out->hal_rate = out->config.rate;
3228 out->hal_format = config->format;
3229 config->format = out_get_format(&out->stream.common);
3230 config->channel_mask = out_get_channels(&out->stream.common);
3231 config->sample_rate = out_get_sample_rate(&out->stream.common);
3232 } else if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
3233 out->stream.common.get_channels = out_get_channels_direct;
3234 out->stream.common.get_format = out_get_format_direct;
3235 out->stream.write = out_write_direct;
3236 out->stream.common.standby = out_standby_direct;
3237 //out->config = pcm_config_out_direct;
3238 out->hal_channel_mask = config->channel_mask;
3239 if (config->sample_rate == 0) {
3240 config->sample_rate = 48000;
3241 }
3242 out->config.rate = out->hal_rate = config->sample_rate;
3243 out->hal_format = config->format;
3244 out->raw_61937_frame_size = 1;
3245 digital_codec = get_codec_type(config->format);
3246 if (digital_codec == TYPE_EAC3) {
3247 out->raw_61937_frame_size = 16;
3248 out->config.period_size = pcm_config_out.period_size * 2;
3249 } else if (digital_codec == TYPE_TRUE_HD || digital_codec == TYPE_DTS_HD) {
3250 out->config.period_size = pcm_config_out.period_size * 4 * 2;
3251 out->raw_61937_frame_size = 16;
3252 }
3253 else if (digital_codec == TYPE_AC3 || digital_codec == TYPE_DTS)
3254 out->raw_61937_frame_size = 4;
3255
3256 if (channel_count > 2) {
3257 ALOGI("[adev_open_output_stream]: out/%p channel/%d\n", out,
3258 channel_count);
3259 out->multich = channel_count;
3260 out->config.channels = channel_count;
3261 }
3262 if (codec_type_is_raw_data(digital_codec)) {
3263 ALOGI("for raw audio output,force alsa stereo output\n");
3264 out->config.channels = 2;
3265 out->multich = 2;
3266 }
3267 } else if (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) {
3268 // TODO: add hwsync write here
3269 //out->stream.write = out_write_hwsync;
3270 }
3271
3272 out->stream.common.get_sample_rate = out_get_sample_rate;
3273 out->stream.common.set_sample_rate = out_set_sample_rate;
3274 out->stream.common.get_buffer_size = out_get_buffer_size;
3275 out->stream.common.set_format = out_set_format;
3276 //out->stream.common.standby = out_standby;
3277 out->stream.common.dump = out_dump;
3278 out->stream.common.set_parameters = out_set_parameters;
3279 out->stream.common.get_parameters = out_get_parameters;
3280 out->stream.common.add_audio_effect = out_add_audio_effect;
3281 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3282 out->stream.get_latency = out_get_latency;
3283 out->stream.set_volume = out_set_volume;
3284 out->stream.get_render_position = out_get_render_position;
3285 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3286 out->stream.get_presentation_position = out_get_presentation_position;
3287 out->stream.pause = out_pause;
3288 out->stream.resume = out_resume;
3289 out->stream.flush = out_flush;
3290 out->volume_l = 1.0;
3291 out->volume_r = 1.0;
3292 out->dev = ladev;
3293 out->standby = true;
3294 out->frame_write_sum = 0;
3295 out->hw_sync_mode = false;
3296 out->first_apts_flag = false;
3297 //out->hal_rate = out->config.rate;
3298 if (0/*flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC*/) {
3299 out->hw_sync_mode = true;
3300 ALOGI("Output stream open with AUDIO_OUTPUT_FLAG_HW_AV_SYNC");
3301 }
3302 /* FIXME: when we support multiple output devices, we will want to
3303 * do the following:
3304 * adev->devices &= ~AUDIO_DEVICE_OUT_ALL;
3305 * adev->devices |= out->device;
3306 * select_output_device(adev);
3307 * This is because out_set_parameters() with a route is not
3308 * guaranteed to be called after an output stream is opened.
3309 */
3310
3311 LOGFUNC("**leave %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d)", __FUNCTION__, devices,
3312 config->format, config->channel_mask, config->sample_rate);
3313
3314 *stream_out = &out->stream;
3315
3316 if (out->is_tv_platform) {
3317 out->config.channels = 8;
3318 out->config.format = PCM_FORMAT_S32_LE;
3319 out->tmp_buffer_8ch = malloc(out->config.period_size * 4 * 8);
3320 if (out->tmp_buffer_8ch == NULL) {
3321 ALOGE("cannot malloc memory for out->tmp_buffer_8ch");
3322 return -ENOMEM;
3323 }
3324 out->audioeffect_tmp_buffer = malloc(out->config.period_size * 6);
3325 if (out->audioeffect_tmp_buffer == NULL) {
3326 ALOGE("cannot malloc memory for audioeffect_tmp_buffer");
3327 return -ENOMEM;
3328 }
3329 //EQ lib load and init EQ
3330 ret = load_EQ_lib();
3331 if (ret < 0) {
3332 ALOGE("%s, Load EQ lib fail!\n", __FUNCTION__);
3333 out->has_EQ_lib = 0;
3334 } else {
3335 ret = HPEQ_init();
3336 if (ret < 0) {
3337 out->has_EQ_lib = 0;
3338 } else {
3339 out->has_EQ_lib = 1;
3340 }
3341 HPEQ_enable(1);
3342 }
3343 //load srs lib and init it.
3344 ret = load_SRS_lib();
3345 if (ret < 0) {
3346 ALOGE("%s, Load SRS lib fail!\n", __FUNCTION__);
3347 out->has_SRS_lib = 0;
3348 } else {
3349 ret = srs_init(48000);
3350 if (ret < 0) {
3351 out->has_SRS_lib = 0;
3352 } else {
3353 out->has_SRS_lib = 1;
3354 }
3355 }
3356 //load aml_IIR lib
3357 ret = load_aml_IIR_lib();
3358 if (ret < 0) {
3359 ALOGE("%s, Load aml_IIR lib fail!\n", __FUNCTION__);
3360 out->has_aml_IIR_lib = 0;
3361 } else {
3362 char value[PROPERTY_VALUE_MAX];
3363 int paramter = 0;
3364 if (property_get("media.audio.LFP.paramter", value, NULL) > 0) {
3365 paramter = atoi(value);
3366 }
3367 aml_IIR_init(paramter);
3368 out->has_aml_IIR_lib = 1;
3369 }
3370 }
3371 return 0;
3372
3373err_open:
3374 free(out);
3375 *stream_out = NULL;
3376 return ret;
3377}
3378
3379static void adev_close_output_stream(struct audio_hw_device *dev,
3380 struct audio_stream_out *stream)
3381{
3382 struct aml_stream_out *out = (struct aml_stream_out *)stream;
3383 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3384 LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream);
3385 if (out->is_tv_platform == 1) {
3386 free(out->tmp_buffer_8ch);
3387 free(out->audioeffect_tmp_buffer);
3388 }
3389 out_standby(&stream->common);
3390 if (adev->hwsync_output == out) {
3391 ALOGI("clear hwsync output when close stream\n");
3392 adev->hwsync_output = NULL;
3393 }
3394 free(stream);
3395}
3396
3397static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3398{
3399 LOGFUNC("%s(%p, %s)", __FUNCTION__, dev, kvpairs);
3400
3401 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3402 struct str_parms *parms;
3403 char *str;
3404 char value[32];
3405 int ret;
3406 parms = str_parms_create_str(kvpairs);
3407 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3408 if (ret >= 0) {
3409 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
3410 adev->low_power = false;
3411 } else {
3412 adev->low_power = true;
3413 }
3414 }
3415 str_parms_destroy(parms);
3416 return ret;
3417}
3418
3419static char * adev_get_parameters(const struct audio_hw_device *dev __unused,
3420 const char *keys __unused)
3421{
3422 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3423 if (!strcmp(keys, AUDIO_PARAMETER_HW_AV_SYNC)) {
3424 ALOGI("get hwsync id\n");
3425 return strdup("hw_av_sync=12345678");
3426 }
3427 return strdup("");
3428}
3429
3430static int adev_init_check(const struct audio_hw_device *dev __unused)
3431{
3432 return 0;
3433}
3434
3435static int adev_set_voice_volume(struct audio_hw_device *dev __unused, float volume __unused)
3436{
3437 return 0;
3438}
3439
3440static int adev_set_master_volume(struct audio_hw_device *dev __unused, float volume __unused)
3441{
3442 return -ENOSYS;
3443}
3444
3445static int adev_get_master_volume(struct audio_hw_device *dev __unused,
3446 float *volume __unused)
3447{
3448 return -ENOSYS;
3449}
3450
3451static int adev_set_master_mute(struct audio_hw_device *dev __unused, bool muted __unused)
3452{
3453 return -ENOSYS;
3454}
3455
3456static int adev_get_master_mute(struct audio_hw_device *dev __unused, bool *muted __unused)
3457{
3458 return -ENOSYS;
3459}
3460static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
3461{
3462 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3463 LOGFUNC("%s(%p, %d)", __FUNCTION__, dev, mode);
3464
3465 pthread_mutex_lock(&adev->lock);
3466 if (adev->mode != mode) {
3467 adev->mode = mode;
3468 select_mode(adev);
3469 }
3470 pthread_mutex_unlock(&adev->lock);
3471
3472 return 0;
3473}
3474
3475static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
3476{
3477 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3478
3479 adev->mic_mute = state;
3480
3481 return 0;
3482}
3483
3484static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
3485{
3486 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3487
3488 *state = adev->mic_mute;
3489
3490 return 0;
3491
3492}
3493
3494static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
3495 const struct audio_config *config)
3496{
3497 size_t size;
3498 int channel_count = popcount(config->channel_mask);
3499
3500 LOGFUNC("%s(%p, %d, %d, %d)", __FUNCTION__, dev, config->sample_rate,
3501 config->format, channel_count);
3502 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
3503 return 0;
3504 }
3505
3506 return get_input_buffer_size(config->frame_count, config->sample_rate,
3507 config->format, channel_count);
3508
3509}
3510
3511static int adev_open_input_stream(struct audio_hw_device *dev,
3512 audio_io_handle_t handle __unused,
3513 audio_devices_t devices,
3514 struct audio_config *config,
3515 struct audio_stream_in **stream_in,
3516 audio_input_flags_t flags __unused,
3517 const char *address __unused,
3518 audio_source_t source __unused)
3519{
3520 struct aml_audio_device *ladev = (struct aml_audio_device *)dev;
3521 struct aml_stream_in *in;
3522 int ret;
3523 int channel_count = popcount(config->channel_mask);
3524 LOGFUNC("%s(%#x, %d, 0x%04x, %d)", __FUNCTION__,
3525 devices, config->format, config->channel_mask, config->sample_rate);
3526 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
3527 return -EINVAL;
3528 }
3529
3530 in = (struct aml_stream_in *)calloc(1, sizeof(struct aml_stream_in));
3531 if (!in) {
3532 return -ENOMEM;
3533 }
3534
3535 in->stream.common.get_sample_rate = in_get_sample_rate;
3536 in->stream.common.set_sample_rate = in_set_sample_rate;
3537 in->stream.common.get_buffer_size = in_get_buffer_size;
3538 in->stream.common.get_channels = in_get_channels;
3539 in->stream.common.get_format = in_get_format;
3540 in->stream.common.set_format = in_set_format;
3541 in->stream.common.standby = in_standby;
3542 in->stream.common.dump = in_dump;
3543 in->stream.common.set_parameters = in_set_parameters;
3544 in->stream.common.get_parameters = in_get_parameters;
3545 in->stream.common.add_audio_effect = in_add_audio_effect;
3546 in->stream.common.remove_audio_effect = in_remove_audio_effect;
3547 in->stream.set_gain = in_set_gain;
3548 in->stream.read = in_read;
3549 in->stream.get_input_frames_lost = in_get_input_frames_lost;
3550
3551 in->requested_rate = config->sample_rate;
3552
3553 in->device = devices & ~AUDIO_DEVICE_BIT_IN;
3554 if (in->device & AUDIO_DEVICE_IN_ALL_SCO) {
3555 memcpy(&in->config, &pcm_config_bt, sizeof(pcm_config_bt));
3556 } else {
3557 memcpy(&in->config, &pcm_config_in, sizeof(pcm_config_in));
3558 }
3559
3560 if (in->config.channels == 1) {
3561 config->channel_mask = AUDIO_CHANNEL_IN_MONO;
3562 } else if (in->config.channels == 2) {
3563 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
3564 } else {
3565 ALOGE("Bad value of channel count : %d", in->config.channels);
3566 }
3567 in->buffer = malloc(in->config.period_size *
3568 audio_stream_in_frame_size(&in->stream));
3569 if (!in->buffer) {
3570 ret = -ENOMEM;
3571 goto err_open;
3572 }
3573
3574 if (in->requested_rate != in->config.rate) {
3575 LOGFUNC("%s(in->requested_rate=%d, in->config.rate=%d)",
3576 __FUNCTION__, in->requested_rate, in->config.rate);
3577 in->buf_provider.get_next_buffer = get_next_buffer;
3578 in->buf_provider.release_buffer = release_buffer;
3579 ret = create_resampler(in->config.rate,
3580 in->requested_rate,
3581 in->config.channels,
3582 RESAMPLER_QUALITY_DEFAULT,
3583 &in->buf_provider,
3584 &in->resampler);
3585
3586 if (ret != 0) {
3587 ret = -EINVAL;
3588 goto err_open;
3589 }
3590 }
3591
3592 in->dev = ladev;
3593 in->standby = 1;
3594 *stream_in = &in->stream;
3595 return 0;
3596
3597err_open:
3598 if (in->resampler) {
3599 release_resampler(in->resampler);
3600 }
3601
3602 free(in);
3603 *stream_in = NULL;
3604 return ret;
3605}
3606
3607static void adev_close_input_stream(struct audio_hw_device *dev,
3608 struct audio_stream_in *stream)
3609{
3610 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3611
3612 LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream);
3613 in_standby(&stream->common);
3614
3615 if (in->resampler) {
3616 free(in->buffer);
3617 release_resampler(in->resampler);
3618 }
3619 if (in->proc_buf) {
3620 free(in->proc_buf);
3621 }
3622 if (in->ref_buf) {
3623 free(in->ref_buf);
3624 }
3625
3626 free(stream);
3627
3628 return;
3629}
3630
3631static int adev_dump(const audio_hw_device_t *device __unused, int fd __unused)
3632{
3633 return 0;
3634}
3635
3636static int adev_close(hw_device_t *device)
3637{
3638 struct aml_audio_device *adev = (struct aml_audio_device *)device;
3639
3640 audio_route_free(adev->ar);
3641 free(device);
3642 return 0;
3643}
3644
3645static int adev_open(const hw_module_t* module, const char* name,
3646 hw_device_t** device)
3647{
3648 struct aml_audio_device *adev;
3649 int card = CARD_AMLOGIC_BOARD;
3650 int ret;
3651 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
3652 return -EINVAL;
3653 }
3654
3655 adev = calloc(1, sizeof(struct aml_audio_device));
3656 if (!adev) {
3657 return -ENOMEM;
3658 }
3659
3660 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
3661 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
3662 adev->hw_device.common.module = (struct hw_module_t *) module;
3663 adev->hw_device.common.close = adev_close;
3664
3665 adev->hw_device.init_check = adev_init_check;
3666 adev->hw_device.set_voice_volume = adev_set_voice_volume;
3667 adev->hw_device.set_master_volume = adev_set_master_volume;
3668 adev->hw_device.get_master_volume = adev_get_master_volume;
3669 adev->hw_device.set_master_mute = adev_set_master_mute;
3670 adev->hw_device.get_master_mute = adev_get_master_mute;
3671 adev->hw_device.set_mode = adev_set_mode;
3672 adev->hw_device.set_mic_mute = adev_set_mic_mute;
3673 adev->hw_device.get_mic_mute = adev_get_mic_mute;
3674 adev->hw_device.set_parameters = adev_set_parameters;
3675 adev->hw_device.get_parameters = adev_get_parameters;
3676 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
3677 adev->hw_device.open_output_stream = adev_open_output_stream;
3678 adev->hw_device.close_output_stream = adev_close_output_stream;
3679 adev->hw_device.open_input_stream = adev_open_input_stream;
3680 adev->hw_device.close_input_stream = adev_close_input_stream;
3681 adev->hw_device.dump = adev_dump;
3682 card = get_aml_card();
3683 if ((card < 0) || (card > 7)) {
3684 ALOGE("error to get audio card");
3685 return -EINVAL;
3686 }
3687
3688 adev->card = card;
3689 adev->ar = audio_route_init(adev->card, MIXER_XML_PATH);
3690
3691 /* Set the default route before the PCM stream is opened */
3692 adev->mode = AUDIO_MODE_NORMAL;
3693 adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
3694 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
3695
3696 select_devices(adev);
3697
3698 *device = &adev->hw_device.common;
3699 return 0;
3700}
3701
3702static struct hw_module_methods_t hal_module_methods = {
3703 .open = adev_open,
3704};
3705
3706struct audio_module HAL_MODULE_INFO_SYM = {
3707 .common = {
3708 .tag = HARDWARE_MODULE_TAG,
3709 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
3710 .hal_api_version = HARDWARE_HAL_API_VERSION,
3711 .id = AUDIO_HARDWARE_MODULE_ID,
3712 .name = "aml audio HW HAL",
3713 .author = "amlogic, Corp.",
3714 .methods = &hal_module_methods,
3715 },
3716};
3717