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