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