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