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