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