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