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