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