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