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