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