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