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