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