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