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