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