summaryrefslogtreecommitdiff
path: root/audio_hw.c (plain)
blob: 1f5e86680bee1248c1d13d6b7d7bb8fa1fcdd0a7
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 = get_pts_gap(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 uint pcr = 0;
1667 if (get_sysfs_uint(TSYNC_PCRSCR, &pcr) == 0) {
1668 uint apts_gap = 0;
1669 int32_t apts_cal = apts & 0xffffffff;
1670 apts_gap = get_pts_gap(pcr, apts);
1671 if (apts_gap < SYSTIME_CORRECTION_THRESHOLD) {
1672 // do nothing
1673 } else {
1674 sprintf(buf, "0x%x", apts_cal);
1675 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);
1676 int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, buf);
1677 if (ret_val == -1) {
1678 ALOGE("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
1679 }
1680 }
1681 }
1682 }
1683 hw_sync->last_apts_from_header = pts;
1684 }
1685#endif
1686
1687 //ALOGI("get header body_cnt = %d, pts = %lld", out->hw_sync_body_cnt, pts);
1688 }
1689 continue;
1690 } else if (hw_sync->hw_sync_state == HW_SYNC_STATE_BODY) {
1691 uint align;
1692 uint m = (hw_sync->hw_sync_body_cnt < remain) ? hw_sync->hw_sync_body_cnt : remain;
1693
1694 //ALOGI("m = %d", m);
1695
1696 // process m bytes, upto end of hw_sync_body_cnt or end of remaining our_write bytes.
1697 // within m bytes, there is no hw_sync header and all are body bytes.
1698 if (hw_sync->body_align_cnt) {
1699 // clear fragment first for alignment limitation on ALSA driver, which
1700 // requires each pcm_writing aligned at 16 frame boundaries
1701 // assuming data are always PCM16 based, so aligned at 64 bytes unit.
1702 if ((m + hw_sync->body_align_cnt) < 64) {
1703 // merge only
1704 memcpy(&hw_sync->body_align[hw_sync->body_align_cnt], p, m);
1705 p += m;
1706 remain -= m;
1707 hw_sync->body_align_cnt += m;
1708 hw_sync->hw_sync_body_cnt -= m;
1709 if (hw_sync->hw_sync_body_cnt == 0) {
1710 // end of body, research for HW SYNC header
1711 hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
1712 hw_sync->hw_sync_header_cnt = 0;
1713 continue;
1714 }
1715 //ALOGI("align cache add %d, cnt = %d", remain, out->body_align_cnt);
1716 break;
1717 } else {
1718 // merge-submit-continue
1719 memcpy(&hw_sync->body_align[hw_sync->body_align_cnt], p, 64 - hw_sync->body_align_cnt);
1720 p += 64 - hw_sync->body_align_cnt;
1721 remain -= 64 - hw_sync->body_align_cnt;
1722 //ALOGI("pcm_write 64, out remain %d", remain);
1723
1724 short *w_buf = (short*)&hw_sync->body_align[0];
1725
1726 if (need_mix) {
1727 short mix_buf[32];
1728 pthread_mutex_lock(&adev->lock);
1729 aml_hal_mixer_read(&adev->hal_mixer, mix_buf, 64);
1730 pthread_mutex_unlock(&adev->lock);
1731
1732 for (i = 0; i < 64 / 2 / 2; i++) {
1733 int r;
1734 r = w_buf[2 * i] * out->volume_l + mix_buf[2 * i];
1735 w_buf[2 * i] = CLIP(r);
1736 r = w_buf[2 * i + 1] * out->volume_r + mix_buf[2 * i + 1];
1737 w_buf[2 * i + 1] = CLIP(r);
1738 }
1739 } else {
1740 for (i = 0; i < 64 / 2 / 2; i++) {
1741 int r;
1742 r = w_buf[2 * i] * out->volume_l;
1743 w_buf[2 * i] = CLIP(r);
1744 r = w_buf[2 * i + 1] * out->volume_r;
1745 w_buf[2 * i + 1] = CLIP(r);
1746 }
1747 }
1748#if 1
1749 if (enable_dump) {
1750 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1751 if (fp1) {
1752 int flen = fwrite((char *)w_buf, 1, 64, fp1);
1753 fclose(fp1);
1754 }
1755 }
1756#endif
1757 pthread_mutex_lock(&adev->pcm_write_lock);
1758 ret = pcm_write(out->pcm, w_buf, 64);
1759 pthread_mutex_unlock(&adev->pcm_write_lock);
1760 out->frame_write_sum += 64 / frame_size;
1761 hw_sync->hw_sync_body_cnt -= 64 - hw_sync->body_align_cnt;
1762 hw_sync->body_align_cnt = 0;
1763 if (hw_sync->hw_sync_body_cnt == 0) {
1764 hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
1765 hw_sync->hw_sync_header_cnt = 0;
1766 }
1767 continue;
1768 }
1769 }
1770
1771 // process m bytes body with an empty fragment for alignment
1772 align = m & 63;
1773 if ((m - align) > 0) {
1774 short *w_buf = (short*)p;
1775 mix_buf = (short *)malloc(m - align);
1776 if (mix_buf == NULL) {
1777 ALOGE("!!!fatal err,malloc %d bytes fail\n", m - align);
1778 ret = -1;
1779 goto exit;
1780 }
1781 if (need_mix) {
1782 pthread_mutex_lock(&adev->lock);
1783 aml_hal_mixer_read(&adev->hal_mixer, mix_buf, m - align);
1784 pthread_mutex_unlock(&adev->lock);
1785 for (i = 0; i < (m - align) / 2 / 2; i++) {
1786 int r;
1787 r = w_buf[2 * i] * out->volume_l + mix_buf[2 * i];
1788 mix_buf[2 * i] = CLIP(r);
1789 r = w_buf[2 * i + 1] * out->volume_r + mix_buf[2 * i + 1];
1790 mix_buf[2 * i + 1] = CLIP(r);
1791 }
1792 } else {
1793 for (i = 0; i < (m - align) / 2 / 2; i++) {
1794
1795 int r;
1796 r = w_buf[2 * i] * out->volume_l;
1797 mix_buf[2 * i] = CLIP(r);
1798 r = w_buf[2 * i + 1] * out->volume_r;
1799 mix_buf[2 * i + 1] = CLIP(r);
1800 }
1801 }
1802#if 1
1803 if (enable_dump) {
1804 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1805 if (fp1) {
1806 int flen = fwrite((char *)mix_buf, 1, m - align, fp1);
1807 fclose(fp1);
1808 }
1809 }
1810#endif
1811 pthread_mutex_lock(&adev->pcm_write_lock);
1812 ret = pcm_write(out->pcm, mix_buf, m - align);
1813 pthread_mutex_unlock(&adev->pcm_write_lock);
1814 free(mix_buf);
1815 out->frame_write_sum += (m - align) / frame_size;
1816
1817 p += m - align;
1818 remain -= m - align;
1819 //ALOGI("pcm_write %d, remain %d", m - align, remain);
1820
1821 hw_sync->hw_sync_body_cnt -= (m - align);
1822 if (hw_sync->hw_sync_body_cnt == 0) {
1823 hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
1824 hw_sync->hw_sync_header_cnt = 0;
1825 continue;
1826 }
1827 }
1828
1829 if (align) {
1830 memcpy(&hw_sync->body_align[0], p, align);
1831 p += align;
1832 remain -= align;
1833 hw_sync->body_align_cnt = align;
1834 //ALOGI("align cache add %d, cnt = %d, remain = %d", align, out->body_align_cnt, remain);
1835
1836 hw_sync->hw_sync_body_cnt -= align;
1837 if (hw_sync->hw_sync_body_cnt == 0) {
1838 hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
1839 hw_sync->hw_sync_header_cnt = 0;
1840 continue;
1841 }
1842 }
1843 }
1844 }
1845
1846 } else {
1847 struct aml_hal_mixer *mixer = &adev->hal_mixer;
1848 pthread_mutex_lock(&adev->pcm_write_lock);
1849 if (aml_hal_mixer_get_content(mixer) > 0) {
1850 pthread_mutex_lock(&mixer->lock);
1851 if (mixer->wp > mixer->rp) {
1852 pcm_write(out->pcm, mixer->start_buf + mixer->rp, mixer->wp - mixer->rp);
1853 } else {
1854 pcm_write(out->pcm, mixer->start_buf + mixer->wp, mixer->buf_size - mixer->rp);
1855 pcm_write(out->pcm, mixer->start_buf, mixer->wp);
1856 }
1857 mixer->rp = mixer->wp = 0;
1858 pthread_mutex_unlock(&mixer->lock);
1859 }
1860 ret = pcm_write(out->pcm, out_buffer, out_frames * frame_size);
1861 pthread_mutex_unlock(&adev->pcm_write_lock);
1862 out->frame_write_sum += out_frames;
1863 }
1864 }
1865
1866exit:
1867 clock_gettime(CLOCK_MONOTONIC, &out->timestamp);
1868 latency_frames = out_get_latency_frames(stream);
1869 if (out->frame_write_sum >= latency_frames) {
1870 out->last_frames_postion = out->frame_write_sum - latency_frames;
1871 } else {
1872 out->last_frames_postion = out->frame_write_sum;
1873 }
1874 pthread_mutex_unlock(&out->lock);
1875 if (ret != 0) {
1876 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
1877 out_get_sample_rate(&stream->common) * 15 / 16);
1878 }
1879
1880 if (force_input_standby) {
1881 pthread_mutex_lock(&adev->lock);
1882 if (adev->active_input) {
1883 in = adev->active_input;
1884 pthread_mutex_lock(&in->lock);
1885 do_input_standby(in);
1886 pthread_mutex_unlock(&in->lock);
1887 }
1888 pthread_mutex_unlock(&adev->lock);
1889 }
1890 return oldBytes;
1891}
1892
1893static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
1894 size_t bytes)
1895{
1896 int ret = 0;
1897 struct aml_stream_out *out = (struct aml_stream_out *)stream;
1898 struct aml_audio_device *adev = out->dev;
1899 size_t frame_size = audio_stream_out_frame_size(stream);
1900 size_t in_frames = bytes / frame_size;
1901 size_t out_frames;
1902 bool force_input_standby = false;
1903 int16_t *in_buffer = (int16_t *)buffer;
1904 struct aml_stream_in *in;
1905 uint ouput_len;
1906 char *data, *data_dst;
1907 volatile char *data_src;
1908 uint i, total_len;
1909 int codec_type = 0;
1910 int samesource_flag = 0;
1911 uint32_t latency_frames = 0;
1912 int need_mix = 0;
1913 short *mix_buf = NULL;
1914 unsigned char enable_dump = getprop_bool("media.audiohal.outdump");
1915
1916 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
1917 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
1918 * mutex
1919 */
1920 pthread_mutex_lock(&adev->lock);
1921 pthread_mutex_lock(&out->lock);
1922
1923#if 1
1924 if (enable_dump && out->hw_sync_mode == 0) {
1925 FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
1926 if (fp1) {
1927 int flen = fwrite((char *)buffer, 1, bytes, fp1);
1928 fclose(fp1);
1929 }
1930 }
1931#endif
1932
1933 if (out->standby) {
1934 ret = start_output_stream(out);
1935 if (ret != 0) {
1936 pthread_mutex_unlock(&adev->lock);
1937 ALOGE("start_output_stream failed");
1938 goto exit;
1939 }
1940 out->standby = false;
1941 /* a change in output device may change the microphone selection */
1942 if (adev->active_input &&
1943 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1944 force_input_standby = true;
1945 }
1946 }
1947 pthread_mutex_unlock(&adev->lock);
1948#if 1
1949 /* Reduce number of channels, if necessary */
1950 if (popcount(out_get_channels(&stream->common)) >
1951 (int)out->config.channels) {
1952 unsigned int i;
1953
1954 /* Discard right channel */
1955 for (i = 1; i < in_frames; i++) {
1956 in_buffer[i] = in_buffer[i * 2];
1957 }
1958
1959 /* The frame size is now half */
1960 frame_size /= 2;
1961 }
1962#endif
1963 /* only use resampler if required */
1964 if (out->config.rate != out_get_sample_rate(&stream->common)) {
1965 out_frames = out->buffer_frames;
1966 out->resampler->resample_from_input(out->resampler,
1967 in_buffer, &in_frames,
1968 (int16_t*)out->buffer, &out_frames);
1969 in_buffer = (int16_t*)out->buffer;
1970 } else {
1971 out_frames = in_frames;
1972 }
1973 if (out->echo_reference != NULL) {
1974
1975 struct echo_reference_buffer b;
1976 b.raw = (void *)buffer;
1977 b.frame_count = in_frames;
1978 get_playback_delay(out, out_frames, &b);
1979 out->echo_reference->write(out->echo_reference, &b);
1980 }
1981
1982#if 1
1983 if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
1984 codec_type = get_sysfs_int("/sys/class/audiodsp/digital_codec");
1985 samesource_flag = get_sysfs_int("/sys/class/audiodsp/audio_samesource");
1986 if (samesource_flag == 0 && codec_type == 0) {
1987 ALOGI("to enable same source,need reset alsa,type %d,same source flag %d \n",
1988 codec_type, samesource_flag);
1989 pcm_stop(out->pcm);
1990 }
1991 }
1992#endif
1993
1994 struct aml_hal_mixer *mixer = &adev->hal_mixer;
1995 pthread_mutex_lock(&adev->pcm_write_lock);
1996 if (aml_hal_mixer_get_content(mixer) > 0) {
1997 pthread_mutex_lock(&mixer->lock);
1998 if (mixer->wp > mixer->rp) {
1999 pcm_write(out->pcm, mixer->start_buf + mixer->rp, mixer->wp - mixer->rp);
2000 } else {
2001 pcm_write(out->pcm, mixer->start_buf + mixer->wp, mixer->buf_size - mixer->rp);
2002 pcm_write(out->pcm, mixer->start_buf, mixer->wp);
2003 }
2004 mixer->rp = mixer->wp = 0;
2005 pthread_mutex_unlock(&mixer->lock);
2006 }
2007 ret = pcm_write(out->pcm, in_buffer, out_frames * frame_size);
2008 pthread_mutex_unlock(&adev->pcm_write_lock);
2009 out->frame_write_sum += out_frames;
2010
2011exit:
2012 latency_frames = out_get_latency(stream) * out->config.rate / 1000;
2013 if (out->frame_write_sum >= latency_frames) {
2014 out->last_frames_postion = out->frame_write_sum - latency_frames;
2015 } else {
2016 out->last_frames_postion = out->frame_write_sum;
2017 }
2018 pthread_mutex_unlock(&out->lock);
2019 if (ret != 0) {
2020 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
2021 out_get_sample_rate(&stream->common) * 15 / 16);
2022 }
2023
2024 if (force_input_standby) {
2025 pthread_mutex_lock(&adev->lock);
2026 if (adev->active_input) {
2027 in = adev->active_input;
2028 pthread_mutex_lock(&in->lock);
2029 do_input_standby(in);
2030 pthread_mutex_unlock(&in->lock);
2031 }
2032 pthread_mutex_unlock(&adev->lock);
2033 }
2034 return bytes;
2035}
2036
2037// insert bytes of zero data to pcm which makes A/V synchronization
2038static int insert_output_bytes(struct aml_stream_out *out, size_t size)
2039{
2040 int ret = 0;
2041 size_t insert_size = size;
2042 size_t once_write_size = 0;
2043 char *insert_buf = (char*)malloc(8192);
2044
2045 if (insert_buf == NULL) {
2046 ALOGE("malloc size failed \n");
2047 return -ENOMEM;
2048 }
2049
2050 memset(insert_buf, 0, 8192);
2051 while (insert_size > 0) {
2052 once_write_size = insert_size > 8192 ? 8192 : insert_size;
2053 ret = pcm_write(out->pcm, (void *)insert_buf, once_write_size);
2054 if (ret != 0) {
2055 ALOGE("pcm write failed\n");
2056 goto exit;
2057 }
2058 insert_size -= once_write_size;
2059 }
2060
2061exit:
2062 free(insert_buf);
2063 return 0;
2064}
2065
2066enum hwsync_status {
2067 CONTINUATION, // good sync condition
2068 ADJUSTMENT, // can be adjusted by discarding or padding data
2069 RESYNC, // pts need resync
2070};
2071
2072enum hwsync_status check_hwsync_status(uint apts_gap)
2073{
2074 enum hwsync_status sync_status;
2075
2076 if (apts_gap < APTS_DISCONTINUE_THRESHOLD_MIN)
2077 sync_status = CONTINUATION;
2078 else if (apts_gap > APTS_DISCONTINUE_THRESHOLD_MAX)
2079 sync_status = RESYNC;
2080 else
2081 sync_status = ADJUSTMENT;
2082
2083 return sync_status;
2084}
2085
2086static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buffer,
2087 size_t bytes)
2088{
2089 int ret = 0;
2090 struct aml_stream_out *out = (struct aml_stream_out *) stream;
2091 struct aml_audio_device *adev = out->dev;
2092 size_t frame_size = audio_stream_out_frame_size(stream);
2093 size_t in_frames = bytes / frame_size;
2094 bool force_input_standby = false;
2095 size_t out_frames = 0;
2096 void *buf;
2097 uint i, total_len;
2098 char prop[PROPERTY_VALUE_MAX];
2099 int codec_type = out->codec_type;
2100 int samesource_flag = 0;
2101 uint32_t latency_frames = 0;
2102 uint64_t total_frame = 0;
2103 audio_hwsync_t *hw_sync = &out->hwsync;
2104 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
2105 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
2106 * mutex
2107 */
2108 ALOGV("out_write_direct:out %p,position %zu, out_write size %"PRIu64,
2109 out, bytes, out->frame_write_sum);
2110 pthread_mutex_lock(&adev->lock);
2111 pthread_mutex_lock(&out->lock);
2112 if (out->pause_status == true) {
2113 pthread_mutex_unlock(&adev->lock);
2114 pthread_mutex_unlock(&out->lock);
2115 ALOGI("call out_write when pause status,size %zu,(%p)\n", bytes, out);
2116 return 0;
2117 }
2118 if ((out->standby) && out->hw_sync_mode) {
2119 /*
2120 there are two types of raw data come to hdmi audio hal
2121 1) compressed audio data without IEC61937 wrapped
2122 2) compressed audio data with IEC61937 wrapped (typically from amlogic amadec source)
2123 we use the AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO to distiguwish the two cases.
2124 */
2125 if ((codec_type == TYPE_AC3 || codec_type == TYPE_EAC3) && (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
2126 spdifenc_init(out->pcm, out->hal_format);
2127 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
2128 }
2129 // todo: check timestamp header PTS discontinue for new sync point after seek
2130 aml_audio_hwsync_init(&out->hwsync);
2131 out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
2132 }
2133 if (out->standby) {
2134 ret = start_output_stream_direct(out);
2135 if (ret != 0) {
2136 pthread_mutex_unlock(&adev->lock);
2137 goto exit;
2138 }
2139 out->standby = 0;
2140 /* a change in output device may change the microphone selection */
2141 if (adev->active_input &&
2142 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
2143 force_input_standby = true;
2144 }
2145 }
2146 void *write_buf = NULL;
2147 size_t hwsync_cost_bytes = 0;
2148 if (out->hw_sync_mode == 1) {
2149 uint64_t cur_pts = 0xffffffff;
2150 int outsize = 0;
2151 char tempbuf[128];
2152 ALOGV("before aml_audio_hwsync_find_frame bytes %zu\n", bytes);
2153 hwsync_cost_bytes = aml_audio_hwsync_find_frame(&out->hwsync, buffer, bytes, &cur_pts, &outsize);
2154 if (cur_pts > 0xffffffff) {
2155 ALOGE("APTS exeed the max 32bit value");
2156 }
2157 ALOGV("after aml_audio_hwsync_find_frame bytes remain %zu,cost %zu,outsize %d,pts %"PRIx64"\n",
2158 bytes - hwsync_cost_bytes, hwsync_cost_bytes, outsize, cur_pts);
2159 //TODO,skip 3 frames after flush, to tmp fix seek pts discontinue issue.need dig more
2160 // to find out why seek ppint pts frame is remained after flush.WTF.
2161 if (out->skip_frame > 0) {
2162 out->skip_frame--;
2163 ALOGI("skip pts@%"PRIx64",cur frame size %d,cost size %zu\n", cur_pts, outsize, hwsync_cost_bytes);
2164 pthread_mutex_unlock(&adev->lock);
2165 pthread_mutex_unlock(&out->lock);
2166 return hwsync_cost_bytes;
2167 }
2168 if (cur_pts != 0xffffffff && outsize > 0) {
2169 // if we got the frame body,which means we get a complete frame.
2170 //we take this frame pts as the first apts.
2171 //this can fix the seek discontinue,we got a fake frame,which maybe cached before the seek
2172 if (hw_sync->first_apts_flag == false) {
2173 aml_audio_hwsync_set_first_pts(&out->hwsync, cur_pts);
2174 } else {
2175 uint64_t apts;
2176 uint32_t apts32;
2177 uint pcr = 0;
2178 uint apts_gap = 0;
2179 uint64_t latency = out_get_latency(stream) * 90;
2180 // check PTS discontinue, which may happen when audio track switching
2181 // discontinue means PTS calculated based on first_apts and frame_write_sum
2182 // does not match the timestamp of next audio samples
2183 if (cur_pts > latency) {
2184 apts = cur_pts - latency;
2185 } else {
2186 apts = 0;
2187 }
2188
2189 apts32 = apts & 0xffffffff;
2190
2191 if (get_sysfs_uint(TSYNC_PCRSCR, &pcr) == 0) {
2192 enum hwsync_status sync_status = CONTINUATION;
2193 apts_gap = get_pts_gap(pcr, apts32);
2194 sync_status = check_hwsync_status(apts_gap);
2195
2196 // limit the gap handle to 0.5~5 s.
2197 if (sync_status == ADJUSTMENT) {
2198 // two cases: apts leading or pcr leading
2199 // apts leading needs inserting frame and pcr leading neads discarding frame
2200 if (apts32 > pcr) {
2201 int insert_size = 0;
2202 if (out->codec_type == TYPE_EAC3) {
2203 insert_size = apts_gap / 90 * 48 * 4 * 4;
2204 } else {
2205 insert_size = apts_gap / 90 * 48 * 4;
2206 }
2207 insert_size = insert_size & (~63);
2208 ALOGI("audio gap 0x%"PRIx32" ms ,need insert data %d\n", apts_gap / 90, insert_size);
2209 ret = insert_output_bytes(out, insert_size);
2210 } else {
2211 //audio pts smaller than pcr,need skip frame.
2212 //we assume one frame duration is 32 ms for DD+(6 blocks X 1536 frames,48K sample rate)
2213 if (out->codec_type == TYPE_EAC3 && outsize > 0) {
2214 ALOGI("audio slow 0x%x,skip frame @pts 0x%"PRIx64",pcr 0x%x,cur apts 0x%x\n",
2215 apts_gap, cur_pts, pcr, apts32);
2216 out->frame_skip_sum += 1536;
2217 bytes = outsize;
2218 pthread_mutex_unlock(&adev->lock);
2219 goto exit;
2220 }
2221 }
2222 } else if (sync_status == RESYNC){
2223 sprintf(tempbuf, "0x%x", apts32);
2224 ALOGI("tsync -> reset pcrscr 0x%x -> 0x%x, %s big,diff %"PRIx64" ms",
2225 pcr, apts32, apts32 > pcr ? "apts" : "pcr", get_pts_gap(apts, pcr) / 90);
2226
2227 int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, tempbuf);
2228 if (ret_val == -1) {
2229 ALOGE("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
2230 }
2231 }
2232 }
2233 }
2234 }
2235 if (outsize > 0) {
2236 in_frames = outsize / frame_size;
2237 write_buf = hw_sync->hw_sync_body_buf;
2238 } else {
2239 bytes = hwsync_cost_bytes;
2240 pthread_mutex_unlock(&adev->lock);
2241 goto exit;
2242 }
2243 } else {
2244 write_buf = (void *) buffer;
2245 }
2246 pthread_mutex_unlock(&adev->lock);
2247 out_frames = in_frames;
2248 buf = (void *) write_buf;
2249 if (getprop_bool("media.hdmihal.outdump")) {
2250 FILE *fp1 = fopen("/data/tmp/hdmi_audio_out.pcm", "a+");
2251 if (fp1) {
2252 int flen = fwrite((char *)buffer, 1, out_frames * frame_size, fp1);
2253 //LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size);
2254 fclose(fp1);
2255 } else {
2256 LOGFUNC("could not open file:/data/hdmi_audio_out.pcm");
2257 }
2258 }
2259 if (codec_type_is_raw_data(out->codec_type) && !(out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
2260 //here to do IEC61937 pack
2261 ALOGV("IEC61937 write size %zu,hw_sync_mode %d,flag %x\n", out_frames * frame_size, out->hw_sync_mode, out->flags);
2262 if (out->codec_type > 0) {
2263 // compressed audio DD/DD+
2264 bytes = spdifenc_write((void *) buf, out_frames * frame_size);
2265 //need return actual size of this burst write
2266 if (out->hw_sync_mode == 1) {
2267 bytes = hwsync_cost_bytes;
2268 }
2269 ALOGV("spdifenc_write return %zu\n", bytes);
2270 if (out->codec_type == TYPE_EAC3) {
2271 out->frame_write_sum = spdifenc_get_total() / 16 + out->spdif_enc_init_frame_write_sum;
2272 } else {
2273 out->frame_write_sum = spdifenc_get_total() / 4 + out->spdif_enc_init_frame_write_sum;
2274 }
2275 ALOGV("out %p,out->frame_write_sum %"PRId64"\n", out, out->frame_write_sum);
2276 }
2277 goto exit;
2278 }
2279 if (!out->standby) {
2280 if (out->multich == 8) {
2281 int *p32 = NULL;
2282 short *p16 = (short *) buf;
2283 short *p16_temp;
2284 int i, NumSamps;
2285 NumSamps = out_frames * frame_size / sizeof(short);
2286 p32 = malloc(NumSamps * sizeof(int));
2287 if (p32 != NULL) {
2288 //here to swap the channnl data here
2289 //actual now:L,missing,R,RS,RRS,,LS,LRS,missing
2290 //expect L,C,R,RS,RRS,LRS,LS,LFE (LFE comes from to center)
2291 //actual audio data layout L,R,C,none/LFE,LRS,RRS,LS,RS
2292 p16_temp = (short *) p32;
2293 for (i = 0; i < NumSamps; i = i + 8) {
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[6 + i];
2299 p16_temp[5 + i] /*RS*/ = p16[7 + i];
2300 p16_temp[6 + i] /*LRS*/ = p16[4 + i];
2301 p16_temp[7 + i]/*RRS*/ = p16[5 + i];
2302 }
2303 memcpy(p16, p16_temp, NumSamps * sizeof(short));
2304 for (i = 0; i < NumSamps; i++) { //suppose 16bit/8ch PCM
2305 p32[i] = p16[i] << 16;
2306 }
2307 ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
2308 free(p32);
2309 }
2310 } else if (out->multich == 6) {
2311 int *p32 = NULL;
2312 short *p16 = (short *) buf;
2313 short *p16_temp;
2314 int i, j, NumSamps, real_samples;
2315 real_samples = out_frames * frame_size / sizeof(short);
2316 NumSamps = real_samples * 8 / 6;
2317 //ALOGI("6ch to 8 ch real %d, to %d,bytes %d,frame size %d\n",real_samples,NumSamps,bytes,frame_size);
2318 p32 = malloc(NumSamps * sizeof(int));
2319 if (p32 != NULL) {
2320 p16_temp = (short *) p32;
2321 for (i = 0; i < real_samples; i = i + 6) {
2322 p16_temp[0 + i]/*L*/ = p16[0 + i];
2323 p16_temp[1 + i]/*R*/ = p16[1 + i];
2324 p16_temp[2 + i] /*LFE*/ = p16[3 + i];
2325 p16_temp[3 + i] /*C*/ = p16[2 + i];
2326 p16_temp[4 + i] /*LS*/ = p16[4 + i];
2327 p16_temp[5 + i] /*RS*/ = p16[5 + i];
2328 }
2329 memcpy(p16, p16_temp, real_samples * sizeof(short));
2330 memset(p32, 0, NumSamps * sizeof(int));
2331 for (i = 0, j = 0; j < NumSamps; i = i + 6, j = j + 8) { //suppose 16bit/8ch PCM
2332 p32[j] = p16[i] << 16;
2333 p32[j + 1] = p16[i + 1] << 16;
2334 p32[j + 2] = p16[i + 2] << 16;
2335 p32[j + 3] = p16[i + 3] << 16;
2336 p32[j + 4] = p16[i + 4] << 16;
2337 p32[j + 5] = p16[i + 5] << 16;
2338 }
2339 ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
2340 free(p32);
2341 }
2342 } else {
2343#if 0
2344 codec_type =
2345 get_sysfs_int("/sys/class/audiodsp/digital_codec");
2346 samesource_flag =
2347 get_sysfs_int("/sys/class/audiodsp/audio_samesource");
2348 if (out->last_codec_type > 0 && codec_type != out->last_codec_type) {
2349 samesource_flag = 1;
2350 }
2351 if (samesource_flag == 1 && codec_type) {
2352 ALOGI
2353 ("to disable same source,need reset alsa,last %d,type %d,same source flag %d ,\n",
2354 out->last_codec_type, codec_type, samesource_flag);
2355 out->last_codec_type = codec_type;
2356 pcm_stop(out->pcm);
2357 }
2358#endif
2359 ALOGV("write size %zu\n", out_frames * frame_size);
2360 ret = pcm_write(out->pcm, (void *) buf, out_frames * frame_size);
2361 if (ret == 0) {
2362 out->frame_write_sum += out_frames;
2363 }
2364 }
2365 }
2366exit:
2367 total_frame = out->frame_write_sum + out->frame_skip_sum;
2368 latency_frames = out_get_latency_frames(stream);
2369 clock_gettime(CLOCK_MONOTONIC, &out->timestamp);
2370 if (total_frame >= latency_frames) {
2371 out->last_frames_postion = total_frame - latency_frames;
2372 } else {
2373 out->last_frames_postion = total_frame;
2374 }
2375 ALOGV("\nout %p,out->last_frames_postion %"PRId64", latency = %d\n", out, out->last_frames_postion, latency_frames);
2376 pthread_mutex_unlock(&out->lock);
2377 if (ret != 0) {
2378 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
2379 out_get_sample_rate(&stream->common));
2380 }
2381
2382 return bytes;
2383}
2384
2385static ssize_t out_write_tv(struct audio_stream_out *stream, const void* buffer,
2386 size_t bytes)
2387{
2388 // TV temporarily use legacy out write.
2389 /* TODO: add TV platform specific write here */
2390 return out_write_legacy(stream, buffer, bytes);
2391}
2392
2393static int out_get_render_position(const struct audio_stream_out *stream,
2394 uint32_t *dsp_frames)
2395{
2396 struct aml_stream_out *out = (struct aml_stream_out *)stream;
2397 uint64_t dsp_frame_int64 = 0;
2398 *dsp_frames = out->last_frames_postion;
2399 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
2400 dsp_frame_int64 = out->last_frames_postion / out->raw_61937_frame_size;
2401 *dsp_frames = (uint32_t)(dsp_frame_int64 & 0xffffffff);
2402 if (out->last_dsp_frame > *dsp_frames) {
2403 ALOGI("maybe uint32_t wraparound,print something,last %u,now %u", out->last_dsp_frame, *dsp_frames);
2404 ALOGI("wraparound,out_get_render_position return %u,playback time %"PRIu64" ms,sr %d\n", *dsp_frames,
2405 out->last_frames_postion * 1000 / out->raw_61937_frame_size / out->config.rate, out->config.rate);
2406
2407 }
2408 }
2409 ALOGV("out_get_render_position %d\n", *dsp_frames);
2410 return 0;
2411}
2412
2413static int out_add_audio_effect(const struct audio_stream *stream __unused, effect_handle_t effect __unused)
2414{
2415 return 0;
2416}
2417
2418static int out_remove_audio_effect(const struct audio_stream *stream __unused, effect_handle_t effect __unused)
2419{
2420 return 0;
2421}
2422static int out_get_next_write_timestamp(const struct audio_stream_out *stream __unused,
2423 int64_t *timestamp __unused)
2424{
2425 return -EINVAL;
2426}
2427
2428//actually maybe it be not useful now except pass CTS_TEST:
2429// run cts -c android.media.cts.AudioTrackTest -m testGetTimestamp
2430static int out_get_presentation_position(const struct audio_stream_out *stream, uint64_t *frames, struct timespec *timestamp)
2431{
2432 struct aml_stream_out *out = (struct aml_stream_out *)stream;
2433
2434 if (!frames || !timestamp) {
2435 return -EINVAL;
2436 }
2437
2438 *frames = out->last_frames_postion;
2439 *timestamp = out->timestamp;
2440
2441 if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
2442 *frames /= out->raw_61937_frame_size;
2443 }
2444 ALOGV("out_get_presentation_position out %p %"PRIu64", sec = %ld, nanosec = %ld\n", out, *frames, timestamp->tv_sec, timestamp->tv_nsec);
2445
2446 return 0;
2447}
2448static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
2449 struct resampler_buffer* buffer);
2450static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2451 struct resampler_buffer* buffer);
2452
2453
2454/** audio_stream_in implementation **/
2455
2456/* must be called with hw device and input stream mutexes locked */
2457static int start_input_stream(struct aml_stream_in *in)
2458{
2459 int ret = 0;
2460 unsigned int card = CARD_AMLOGIC_BOARD;
2461 unsigned int port = PORT_I2S;
2462
2463 struct aml_audio_device *adev = in->dev;
2464 LOGFUNC("%s(need_echo_reference=%d, channels=%d, rate=%d, requested_rate=%d, mode= %d)",
2465 __FUNCTION__, in->need_echo_reference, in->config.channels, in->config.rate, in->requested_rate, adev->mode);
2466 adev->active_input = in;
2467
2468 if (adev->mode != AUDIO_MODE_IN_CALL) {
2469 adev->in_device &= ~AUDIO_DEVICE_IN_ALL;
2470 adev->in_device |= in->device;
2471 select_devices(adev);
2472 }
2473 card = get_aml_card();
2474
2475 ALOGV("%s(in->requested_rate=%d, in->config.rate=%d)",
2476 __FUNCTION__, in->requested_rate, in->config.rate);
2477 if (adev->in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2478 port = PORT_PCM;
2479 } else if (getprop_bool("sys.hdmiIn.Capture")) {
2480 port = PORT_SPDIF;
2481 } else {
2482 port = PORT_I2S;
2483 }
2484 LOGFUNC("*%s, open card(%d) port(%d)-------", __FUNCTION__, card, port);
2485 in->config.period_size = CAPTURE_PERIOD_SIZE;
2486 if (in->need_echo_reference && in->echo_reference == NULL) {
2487 in->echo_reference = get_echo_reference(adev,
2488 AUDIO_FORMAT_PCM_16_BIT,
2489 in->config.channels,
2490 in->requested_rate);
2491 LOGFUNC("%s(after get_echo_ref.... now in->echo_reference = %p)", __FUNCTION__, in->echo_reference);
2492 }
2493 /* this assumes routing is done previously */
2494 in->pcm = pcm_open(card, port, PCM_IN, &in->config);
2495 if (!pcm_is_ready(in->pcm)) {
2496 ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm));
2497 pcm_close(in->pcm);
2498 adev->active_input = NULL;
2499 return -ENOMEM;
2500 }
2501 ALOGD("pcm_open in: card(%d), port(%d)", card, port);
2502
2503 /* if no supported sample rate is available, use the resampler */
2504 if (in->resampler) {
2505 in->resampler->reset(in->resampler);
2506 in->frames_in = 0;
2507 }
2508 return 0;
2509}
2510
2511static uint32_t in_get_sample_rate(const struct audio_stream *stream)
2512{
2513 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2514
2515 return in->requested_rate;
2516}
2517
2518static int in_set_sample_rate(struct audio_stream *stream __unused, uint32_t rate __unused)
2519{
2520 return 0;
2521}
2522
2523static size_t in_get_buffer_size(const struct audio_stream *stream)
2524{
2525 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2526
2527 return get_input_buffer_size(in->config.period_size, in->config.rate,
2528 AUDIO_FORMAT_PCM_16_BIT,
2529 in->config.channels);
2530}
2531
2532static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
2533{
2534 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2535
2536 if (in->config.channels == 1) {
2537 return AUDIO_CHANNEL_IN_MONO;
2538 } else {
2539 return AUDIO_CHANNEL_IN_STEREO;
2540 }
2541}
2542
2543static audio_format_t in_get_format(const struct audio_stream *stream __unused)
2544{
2545 return AUDIO_FORMAT_PCM_16_BIT;
2546}
2547
2548static int in_set_format(struct audio_stream *stream __unused, audio_format_t format __unused)
2549{
2550 return 0;
2551}
2552
2553/* must be called with hw device and input stream mutexes locked */
2554static int do_input_standby(struct aml_stream_in *in)
2555{
2556 struct aml_audio_device *adev = in->dev;
2557
2558 LOGFUNC("%s(%p)", __FUNCTION__, in);
2559 if (!in->standby) {
2560 pcm_close(in->pcm);
2561 in->pcm = NULL;
2562
2563 adev->active_input = 0;
2564 if (adev->mode != AUDIO_MODE_IN_CALL) {
2565 adev->in_device &= ~AUDIO_DEVICE_IN_ALL;
2566 //select_input_device(adev);
2567 }
2568
2569 if (in->echo_reference != NULL) {
2570 /* stop reading from echo reference */
2571 in->echo_reference->read(in->echo_reference, NULL);
2572 put_echo_reference(adev, in->echo_reference);
2573 in->echo_reference = NULL;
2574 }
2575
2576 in->standby = 1;
2577#if 0
2578 LOGFUNC("%s : output_standby=%d,input_standby=%d",
2579 __FUNCTION__, output_standby, input_standby);
2580 if (output_standby && input_standby) {
2581 reset_mixer_state(adev->ar);
2582 update_mixer_state(adev->ar);
2583 }
2584#endif
2585 }
2586 return 0;
2587}
2588static int in_standby(struct audio_stream *stream)
2589{
2590 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2591 int status;
2592 LOGFUNC("%s(%p)", __FUNCTION__, stream);
2593
2594 pthread_mutex_lock(&in->dev->lock);
2595 pthread_mutex_lock(&in->lock);
2596 status = do_input_standby(in);
2597 pthread_mutex_unlock(&in->lock);
2598 pthread_mutex_unlock(&in->dev->lock);
2599 return status;
2600}
2601
2602static int in_dump(const struct audio_stream *stream __unused, int fd __unused)
2603{
2604 return 0;
2605}
2606
2607static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
2608{
2609 struct aml_stream_in *in = (struct aml_stream_in *)stream;
2610 struct aml_audio_device *adev = in->dev;
2611 struct str_parms *parms;
2612 char *str;
2613 char value[32];
2614 int ret, val = 0;
2615 bool do_standby = false;
2616
2617 LOGFUNC("%s(%p, %s)", __FUNCTION__, stream, kvpairs);
2618 parms = str_parms_create_str(kvpairs);
2619
2620 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
2621
2622 pthread_mutex_lock(&adev->lock);
2623 pthread_mutex_lock(&in->lock);
2624 if (ret >= 0) {
2625 val = atoi(value);
2626 /* no audio source uses val == 0 */
2627 if ((in->source != val) && (val != 0)) {
2628 in->source = val;
2629 do_standby = true;
2630 }
2631 }
2632
2633 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2634 if (ret >= 0) {
2635 val = atoi(value) & ~AUDIO_DEVICE_BIT_IN;
2636 if ((in->device != val) && (val != 0)) {
2637 in->device = val;
2638 do_standby = true;
2639 }
2640 }
2641
2642 if (do_standby) {
2643 do_input_standby(in);
2644 }
2645 pthread_mutex_unlock(&in->lock);
2646 pthread_mutex_unlock(&adev->lock);
2647
2648 int framesize = 0;
2649 ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_FRAME_COUNT, &framesize);
2650
2651 if (ret >= 0) {
2652 if (framesize > 0) {
2653 ALOGI("Reset audio input hw frame size from %d to %d\n",
2654 in->config.period_size * in->config.period_count, framesize);
2655 in->config.period_size = framesize / in->config.period_count;
2656 pthread_mutex_lock(&adev->lock);
2657 pthread_mutex_lock(&in->lock);
2658
2659 if (!in->standby && (in == adev->active_input)) {
2660 do_input_standby(in);
2661 start_input_stream(in);
2662 in->standby = 0;
2663 }
2664
2665 pthread_mutex_unlock(&in->lock);
2666 pthread_mutex_unlock(&adev->lock);
2667 }
2668 }
2669
2670 str_parms_destroy(parms);
2671 return ret;
2672}
2673
2674static char * in_get_parameters(const struct audio_stream *stream __unused,
2675 const char *keys __unused)
2676{
2677 return strdup("");
2678}
2679
2680static int in_set_gain(struct audio_stream_in *stream __unused, float gain __unused)
2681{
2682 return 0;
2683}
2684
2685static void get_capture_delay(struct aml_stream_in *in,
2686 size_t frames __unused,
2687 struct echo_reference_buffer *buffer)
2688{
2689 /* read frames available in kernel driver buffer */
2690 uint kernel_frames;
2691 struct timespec tstamp;
2692 long buf_delay;
2693 long rsmp_delay;
2694 long kernel_delay;
2695 long delay_ns;
2696 int rsmp_mul = in->config.rate / VX_NB_SAMPLING_RATE;
2697 if (pcm_get_htimestamp(in->pcm, &kernel_frames, &tstamp) < 0) {
2698 buffer->time_stamp.tv_sec = 0;
2699 buffer->time_stamp.tv_nsec = 0;
2700 buffer->delay_ns = 0;
2701 ALOGW("read get_capture_delay(): pcm_htimestamp error");
2702 return;
2703 }
2704
2705 /* read frames available in audio HAL input buffer
2706 * add number of frames being read as we want the capture time of first sample
2707 * in current buffer */
2708 buf_delay = (long)(((int64_t)(in->frames_in + in->proc_frames_in * rsmp_mul) * 1000000000)
2709 / in->config.rate);
2710 /* add delay introduced by resampler */
2711 rsmp_delay = 0;
2712 if (in->resampler) {
2713 rsmp_delay = in->resampler->delay_ns(in->resampler);
2714 }
2715
2716 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
2717
2718 delay_ns = kernel_delay + buf_delay + rsmp_delay;
2719
2720 buffer->time_stamp = tstamp;
2721 buffer->delay_ns = delay_ns;
2722 /*ALOGV("get_capture_delay time_stamp = [%ld].[%ld], delay_ns: [%d],"
2723 " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], "
2724 "in->frames_in:[%d], in->proc_frames_in:[%d], frames:[%d]",
2725 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns,
2726 kernel_delay, buf_delay, rsmp_delay, kernel_frames,
2727 in->frames_in, in->proc_frames_in, frames);*/
2728
2729}
2730
2731static int32_t update_echo_reference(struct aml_stream_in *in, size_t frames)
2732{
2733 struct echo_reference_buffer b;
2734 b.delay_ns = 0;
2735
2736 ALOGV("update_echo_reference, frames = [%zu], in->ref_frames_in = [%zu], "
2737 "b.frame_count = [%zu]", frames, in->ref_frames_in, frames - in->ref_frames_in);
2738 if (in->ref_frames_in < frames) {
2739 if (in->ref_buf_size < frames) {
2740 in->ref_buf_size = frames;
2741 in->ref_buf = (int16_t *)realloc(in->ref_buf,
2742 in->ref_buf_size * in->config.channels * sizeof(int16_t));
2743 }
2744
2745 b.frame_count = frames - in->ref_frames_in;
2746 b.raw = (void *)(in->ref_buf + in->ref_frames_in * in->config.channels);
2747
2748 get_capture_delay(in, frames, &b);
2749 LOGFUNC("update_echo_reference return ::b.delay_ns=%d", b.delay_ns);
2750
2751 if (in->echo_reference->read(in->echo_reference, &b) == 0) {
2752 in->ref_frames_in += b.frame_count;
2753 ALOGV("update_echo_reference: in->ref_frames_in:[%zu], "
2754 "in->ref_buf_size:[%zu], frames:[%zu], b.frame_count:[%zu]",
2755 in->ref_frames_in, in->ref_buf_size, frames, b.frame_count);
2756 }
2757 } else {
2758 ALOGW("update_echo_reference: NOT enough frames to read ref buffer");
2759 }
2760 return b.delay_ns;
2761}
2762
2763static int set_preprocessor_param(effect_handle_t handle,
2764 effect_param_t *param)
2765{
2766 uint32_t size = sizeof(int);
2767 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
2768 param->vsize;
2769
2770 int status = (*handle)->command(handle,
2771 EFFECT_CMD_SET_PARAM,
2772 sizeof(effect_param_t) + psize,
2773 param,
2774 &size,
2775 &param->status);
2776 if (status == 0) {
2777 status = param->status;
2778 }
2779
2780 return status;
2781}
2782
2783static int set_preprocessor_echo_delay(effect_handle_t handle,
2784 int32_t delay_us)
2785{
2786 uint32_t buf[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
2787 effect_param_t *param = (effect_param_t *)buf;
2788
2789 param->psize = sizeof(uint32_t);
2790 param->vsize = sizeof(uint32_t);
2791 *(uint32_t *)param->data = AEC_PARAM_ECHO_DELAY;
2792 *((int32_t *)param->data + 1) = delay_us;
2793
2794 return set_preprocessor_param(handle, param);
2795}
2796
2797static void push_echo_reference(struct aml_stream_in *in, size_t frames)
2798{
2799 /* read frames from echo reference buffer and update echo delay
2800 * in->ref_frames_in is updated with frames available in in->ref_buf */
2801 int32_t delay_us = update_echo_reference(in, frames) / 1000;
2802 int i;
2803 audio_buffer_t buf;
2804
2805 if (in->ref_frames_in < frames) {
2806 frames = in->ref_frames_in;
2807 }
2808
2809 buf.frameCount = frames;
2810 buf.raw = in->ref_buf;
2811
2812 for (i = 0; i < in->num_preprocessors; i++) {
2813 if ((*in->preprocessors[i])->process_reverse == NULL) {
2814 continue;
2815 }
2816
2817 (*in->preprocessors[i])->process_reverse(in->preprocessors[i],
2818 &buf,
2819 NULL);
2820 set_preprocessor_echo_delay(in->preprocessors[i], delay_us);
2821 }
2822
2823 in->ref_frames_in -= buf.frameCount;
2824 if (in->ref_frames_in) {
2825 memcpy(in->ref_buf,
2826 in->ref_buf + buf.frameCount * in->config.channels,
2827 in->ref_frames_in * in->config.channels * sizeof(int16_t));
2828 }
2829}
2830
2831static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
2832 struct resampler_buffer* buffer)
2833{
2834 struct aml_stream_in *in;
2835
2836 if (buffer_provider == NULL || buffer == NULL) {
2837 return -EINVAL;
2838 }
2839
2840 in = (struct aml_stream_in *)((char *)buffer_provider -
2841 offsetof(struct aml_stream_in, buf_provider));
2842
2843 if (in->pcm == NULL) {
2844 buffer->raw = NULL;
2845 buffer->frame_count = 0;
2846 in->read_status = -ENODEV;
2847 return -ENODEV;
2848 }
2849
2850 if (in->frames_in == 0) {
2851 in->read_status = pcm_read(in->pcm, (void*)in->buffer,
2852 in->config.period_size * audio_stream_in_frame_size(&in->stream));
2853 if (in->read_status != 0) {
2854 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
2855 buffer->raw = NULL;
2856 buffer->frame_count = 0;
2857 return in->read_status;
2858 }
2859 in->frames_in = in->config.period_size;
2860 }
2861
2862 buffer->frame_count = (buffer->frame_count > in->frames_in) ?
2863 in->frames_in : buffer->frame_count;
2864 buffer->i16 = in->buffer + (in->config.period_size - in->frames_in) *
2865 in->config.channels;
2866
2867 return in->read_status;
2868
2869}
2870
2871static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2872 struct resampler_buffer* buffer)
2873{
2874 struct aml_stream_in *in;
2875
2876 if (buffer_provider == NULL || buffer == NULL) {
2877 return;
2878 }
2879
2880 in = (struct aml_stream_in *)((char *)buffer_provider -
2881 offsetof(struct aml_stream_in, buf_provider));
2882
2883 in->frames_in -= buffer->frame_count;
2884}
2885
2886/* read_frames() reads frames from kernel driver, down samples to capture rate
2887 * if necessary and output the number of frames requested to the buffer specified */
2888static ssize_t read_frames(struct aml_stream_in *in, void *buffer, ssize_t frames)
2889{
2890 ssize_t frames_wr = 0;
2891
2892 while (frames_wr < frames) {
2893 size_t frames_rd = frames - frames_wr;
2894 if (in->resampler != NULL) {
2895 in->resampler->resample_from_provider(in->resampler,
2896 (int16_t *)((char *)buffer +
2897 frames_wr * audio_stream_in_frame_size(&in->stream)),
2898 &frames_rd);
2899 } else {
2900 struct resampler_buffer buf = {
2901 { .raw = NULL, },
2902 .frame_count = frames_rd,
2903 };
2904 get_next_buffer(&in->buf_provider, &buf);
2905 if (buf.raw != NULL) {
2906 memcpy((char *)buffer +
2907 frames_wr * audio_stream_in_frame_size(&in->stream),
2908 buf.raw,
2909 buf.frame_count * audio_stream_in_frame_size(&in->stream));
2910 frames_rd = buf.frame_count;
2911 }
2912 release_buffer(&in->buf_provider, &buf);
2913 }
2914 /* in->read_status is updated by getNextBuffer() also called by
2915 * in->resampler->resample_from_provider() */
2916 if (in->read_status != 0) {
2917 return in->read_status;
2918 }
2919
2920 frames_wr += frames_rd;
2921 }
2922 return frames_wr;
2923}
2924
2925/* process_frames() reads frames from kernel driver (via read_frames()),
2926 * calls the active audio pre processings and output the number of frames requested
2927 * to the buffer specified */
2928static ssize_t process_frames(struct aml_stream_in *in, void* buffer, ssize_t frames)
2929{
2930 ssize_t frames_wr = 0;
2931 audio_buffer_t in_buf;
2932 audio_buffer_t out_buf;
2933 int i;
2934
2935 //LOGFUNC("%s(%d, %p, %ld)", __FUNCTION__, in->num_preprocessors, buffer, frames);
2936 while (frames_wr < frames) {
2937 /* first reload enough frames at the end of process input buffer */
2938 if (in->proc_frames_in < (size_t)frames) {
2939 ssize_t frames_rd;
2940
2941 if (in->proc_buf_size < (size_t)frames) {
2942 in->proc_buf_size = (size_t)frames;
2943 in->proc_buf = (int16_t *)realloc(in->proc_buf,
2944 in->proc_buf_size *
2945 in->config.channels * sizeof(int16_t));
2946 ALOGV("process_frames(): in->proc_buf %p size extended to %zu frames",
2947 in->proc_buf, in->proc_buf_size);
2948 }
2949 frames_rd = read_frames(in,
2950 in->proc_buf +
2951 in->proc_frames_in * in->config.channels,
2952 frames - in->proc_frames_in);
2953 if (frames_rd < 0) {
2954 frames_wr = frames_rd;
2955 break;
2956 }
2957 in->proc_frames_in += frames_rd;
2958 }
2959
2960 if (in->echo_reference != NULL) {
2961 push_echo_reference(in, in->proc_frames_in);
2962 }
2963
2964 /* in_buf.frameCount and out_buf.frameCount indicate respectively
2965 * the maximum number of frames to be consumed and produced by process() */
2966 in_buf.frameCount = in->proc_frames_in;
2967 in_buf.s16 = in->proc_buf;
2968 out_buf.frameCount = frames - frames_wr;
2969 out_buf.s16 = (int16_t *)buffer + frames_wr * in->config.channels;
2970
2971 for (i = 0; i < in->num_preprocessors; i++)
2972 (*in->preprocessors[i])->process(in->preprocessors[i],
2973 &in_buf,
2974 &out_buf);
2975
2976 /* process() has updated the number of frames consumed and produced in
2977 * in_buf.frameCount and out_buf.frameCount respectively
2978 * move remaining frames to the beginning of in->proc_buf */
2979 in->proc_frames_in -= in_buf.frameCount;
2980 if (in->proc_frames_in) {
2981 memcpy(in->proc_buf,
2982 in->proc_buf + in_buf.frameCount * in->config.channels,
2983 in->proc_frames_in * in->config.channels * sizeof(int16_t));
2984 }
2985
2986 /* if not enough frames were passed to process(), read more and retry. */
2987 if (out_buf.frameCount == 0) {
2988 continue;
2989 }
2990
2991 frames_wr += out_buf.frameCount;
2992 }
2993 return frames_wr;
2994}
2995
2996static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
2997 size_t bytes)
2998{
2999 int ret = 0;
3000 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3001 struct aml_audio_device *adev = in->dev;
3002 size_t frames_rq = bytes / audio_stream_in_frame_size(&in->stream);
3003
3004 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
3005 * on the input stream mutex - e.g. executing select_mode() while holding the hw device
3006 * mutex
3007 */
3008 pthread_mutex_lock(&adev->lock);
3009 pthread_mutex_lock(&in->lock);
3010 if (in->standby) {
3011 ret = start_input_stream(in);
3012 if (ret == 0) {
3013 in->standby = 0;
3014 }
3015 }
3016 pthread_mutex_unlock(&adev->lock);
3017
3018 if (ret < 0) {
3019 goto exit;
3020 }
3021
3022 if (in->num_preprocessors != 0) {
3023 ret = process_frames(in, buffer, frames_rq);
3024 } else if (in->resampler != NULL) {
3025 ret = read_frames(in, buffer, frames_rq);
3026 } else {
3027 ret = pcm_read(in->pcm, buffer, bytes);
3028 }
3029
3030 if (ret > 0) {
3031 ret = 0;
3032 }
3033
3034 if (ret == 0 && adev->mic_mute) {
3035 memset(buffer, 0, bytes);
3036 }
3037
3038#if 0
3039 FILE *dump_fp = NULL;
3040
3041 dump_fp = fopen("/data/audio_in.pcm", "a+");
3042 if (dump_fp != NULL) {
3043 fwrite(buffer, bytes, 1, dump_fp);
3044 fclose(dump_fp);
3045 } else {
3046 ALOGW("[Error] Can't write to /data/dump_in.pcm");
3047 }
3048#endif
3049
3050exit:
3051 if (ret < 0)
3052 usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
3053 in_get_sample_rate(&stream->common));
3054
3055 pthread_mutex_unlock(&in->lock);
3056 return bytes;
3057
3058}
3059
3060static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream __unused)
3061{
3062 return 0;
3063}
3064
3065static int in_add_audio_effect(const struct audio_stream *stream,
3066 effect_handle_t effect)
3067{
3068 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3069 int status;
3070 effect_descriptor_t desc;
3071
3072 pthread_mutex_lock(&in->dev->lock);
3073 pthread_mutex_lock(&in->lock);
3074 if (in->num_preprocessors >= MAX_PREPROCESSORS) {
3075 status = -ENOSYS;
3076 goto exit;
3077 }
3078
3079 status = (*effect)->get_descriptor(effect, &desc);
3080 if (status != 0) {
3081 goto exit;
3082 }
3083
3084 in->preprocessors[in->num_preprocessors++] = effect;
3085
3086 if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3087 in->need_echo_reference = true;
3088 do_input_standby(in);
3089 }
3090
3091exit:
3092
3093 pthread_mutex_unlock(&in->lock);
3094 pthread_mutex_unlock(&in->dev->lock);
3095 return status;
3096}
3097
3098static int in_remove_audio_effect(const struct audio_stream *stream,
3099 effect_handle_t effect)
3100{
3101 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3102 int i;
3103 int status = -EINVAL;
3104 bool found = false;
3105 effect_descriptor_t desc;
3106
3107 pthread_mutex_lock(&in->dev->lock);
3108 pthread_mutex_lock(&in->lock);
3109 if (in->num_preprocessors <= 0) {
3110 status = -ENOSYS;
3111 goto exit;
3112 }
3113
3114 for (i = 0; i < in->num_preprocessors; i++) {
3115 if (found) {
3116 in->preprocessors[i - 1] = in->preprocessors[i];
3117 continue;
3118 }
3119 if (in->preprocessors[i] == effect) {
3120 in->preprocessors[i] = NULL;
3121 status = 0;
3122 found = true;
3123 }
3124 }
3125
3126 if (status != 0) {
3127 goto exit;
3128 }
3129
3130 in->num_preprocessors--;
3131
3132 status = (*effect)->get_descriptor(effect, &desc);
3133 if (status != 0) {
3134 goto exit;
3135 }
3136 if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3137 in->need_echo_reference = false;
3138 do_input_standby(in);
3139 }
3140
3141exit:
3142
3143 pthread_mutex_unlock(&in->lock);
3144 pthread_mutex_unlock(&in->dev->lock);
3145 return status;
3146}
3147
3148static int adev_open_output_stream(struct audio_hw_device *dev,
3149 audio_io_handle_t handle __unused,
3150 audio_devices_t devices,
3151 audio_output_flags_t flags,
3152 struct audio_config *config,
3153 struct audio_stream_out **stream_out,
3154 const char *address __unused)
3155{
3156 struct aml_audio_device *ladev = (struct aml_audio_device *)dev;
3157 struct aml_stream_out *out;
3158 int channel_count = popcount(config->channel_mask);
3159 int digital_codec;
3160 bool direct = false;
3161 int ret;
3162 bool hwsync_lpcm = false;
3163 ALOGI("enter %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d, flags=0x%x)", __FUNCTION__, devices,
3164 config->format, config->channel_mask, config->sample_rate, flags);
3165
3166 out = (struct aml_stream_out *)calloc(1, sizeof(struct aml_stream_out));
3167 if (!out) {
3168 return -ENOMEM;
3169 }
3170
3171 out->out_device = devices;
3172 out->flags = flags;
3173 if (getprop_bool("ro.platform.has.tvuimode")) {
3174 out->is_tv_platform = 1;
3175 }
3176 out->config = pcm_config_out;
3177 //hwsync with LPCM still goes to out_write_legacy
3178 hwsync_lpcm = (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(config->format));
3179 ALOGI("hwsync_lpcm %d\n", hwsync_lpcm);
3180 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY || hwsync_lpcm) {
3181 out->stream.common.get_channels = out_get_channels;
3182 out->stream.common.get_format = out_get_format;
3183 out->stream.write = out_write_legacy;
3184 out->stream.common.standby = out_standby;
3185
3186 out->hal_rate = out->config.rate;
3187 out->hal_format = config->format;
3188 config->format = out_get_format(&out->stream.common);
3189 config->channel_mask = out_get_channels(&out->stream.common);
3190 config->sample_rate = out_get_sample_rate(&out->stream.common);
3191 } else if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
3192 out->stream.common.get_channels = out_get_channels_direct;
3193 out->stream.common.get_format = out_get_format_direct;
3194 out->stream.write = out_write_direct;
3195 out->stream.common.standby = out_standby_direct;
3196 if (config->format == AUDIO_FORMAT_DEFAULT) {
3197 config->format = AUDIO_FORMAT_AC3;
3198 }
3199 /* set default pcm config for direct. */
3200 out->config = pcm_config_out_direct;
3201 out->hal_channel_mask = config->channel_mask;
3202 if (config->sample_rate == 0) {
3203 config->sample_rate = 48000;
3204 }
3205 out->config.rate = out->hal_rate = config->sample_rate;
3206 out->hal_format = config->format;
3207 out->raw_61937_frame_size = 1;
3208 digital_codec = get_codec_type(config->format);
3209 if (digital_codec == TYPE_EAC3) {
3210 out->raw_61937_frame_size = 4;
3211 out->config.period_size = pcm_config_out_direct.period_size * 2;
3212 } else if (digital_codec == TYPE_TRUE_HD || digital_codec == TYPE_DTS_HD) {
3213 out->config.period_size = pcm_config_out_direct.period_size * 4 * 2;
3214 out->raw_61937_frame_size = 16;
3215 }
3216 else if (digital_codec == TYPE_AC3 || digital_codec == TYPE_DTS)
3217 out->raw_61937_frame_size = 4;
3218
3219 if (channel_count > 2) {
3220 ALOGI("[adev_open_output_stream]: out/%p channel/%d\n", out,
3221 channel_count);
3222 out->multich = channel_count;
3223 out->config.channels = channel_count;
3224 }
3225 if (codec_type_is_raw_data(digital_codec)) {
3226 ALOGI("for raw audio output,force alsa stereo output\n");
3227 out->config.channels = 2;
3228 out->multich = 2;
3229 out->hal_channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3230 //config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3231 }
3232 } else {
3233 // TODO: add other cases here
3234 ALOGE("DO not support yet!!");
3235 return -EINVAL;
3236 }
3237
3238 out->stream.common.get_sample_rate = out_get_sample_rate;
3239 out->stream.common.set_sample_rate = out_set_sample_rate;
3240 out->stream.common.get_buffer_size = out_get_buffer_size;
3241 out->stream.common.set_format = out_set_format;
3242 //out->stream.common.standby = out_standby;
3243 out->stream.common.dump = out_dump;
3244 out->stream.common.set_parameters = out_set_parameters;
3245 out->stream.common.get_parameters = out_get_parameters;
3246 out->stream.common.add_audio_effect = out_add_audio_effect;
3247 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3248 out->stream.get_latency = out_get_latency;
3249 out->stream.set_volume = out_set_volume;
3250 out->stream.get_render_position = out_get_render_position;
3251 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3252 out->stream.get_presentation_position = out_get_presentation_position;
3253 out->stream.pause = out_pause;
3254 out->stream.resume = out_resume;
3255 out->stream.flush = out_flush;
3256 out->volume_l = 1.0;
3257 out->volume_r = 1.0;
3258 out->dev = ladev;
3259 out->standby = true;
3260 out->frame_write_sum = 0;
3261 out->hw_sync_mode = false;
3262 aml_audio_hwsync_init(&out->hwsync);
3263 //out->hal_rate = out->config.rate;
3264 if (0/*flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC*/) {
3265 out->hw_sync_mode = true;
3266 ALOGI("Output stream open with AUDIO_OUTPUT_FLAG_HW_AV_SYNC");
3267 }
3268 /* FIXME: when we support multiple output devices, we will want to
3269 * do the following:
3270 * adev->devices &= ~AUDIO_DEVICE_OUT_ALL;
3271 * adev->devices |= out->device;
3272 * select_output_device(adev);
3273 * This is because out_set_parameters() with a route is not
3274 * guaranteed to be called after an output stream is opened.
3275 */
3276
3277 LOGFUNC("**leave %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d)", __FUNCTION__, devices,
3278 config->format, config->channel_mask, config->sample_rate);
3279
3280 *stream_out = &out->stream;
3281
3282 if (out->is_tv_platform && !(flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
3283 out->config.channels = 8;
3284 out->config.format = PCM_FORMAT_S32_LE;
3285 out->tmp_buffer_8ch = malloc(out->config.period_size * 4 * 8);
3286 if (out->tmp_buffer_8ch == NULL) {
3287 ALOGE("cannot malloc memory for out->tmp_buffer_8ch");
3288 return -ENOMEM;
3289 }
3290 out->audioeffect_tmp_buffer = malloc(out->config.period_size * 6);
3291 if (out->audioeffect_tmp_buffer == NULL) {
3292 ALOGE("cannot malloc memory for audioeffect_tmp_buffer");
3293 return -ENOMEM;
3294 }
3295 //EQ lib load and init EQ
3296 ret = load_EQ_lib();
3297 if (ret < 0) {
3298 ALOGE("%s, Load EQ lib fail!\n", __FUNCTION__);
3299 out->has_EQ_lib = 0;
3300 } else {
3301 ret = HPEQ_init();
3302 if (ret < 0) {
3303 out->has_EQ_lib = 0;
3304 } else {
3305 out->has_EQ_lib = 1;
3306 }
3307 HPEQ_enable(1);
3308 }
3309 //load srs lib and init it.
3310 ret = load_SRS_lib();
3311 if (ret < 0) {
3312 ALOGE("%s, Load SRS lib fail!\n", __FUNCTION__);
3313 out->has_SRS_lib = 0;
3314 } else {
3315 ret = srs_init(48000);
3316 if (ret < 0) {
3317 out->has_SRS_lib = 0;
3318 } else {
3319 out->has_SRS_lib = 1;
3320 }
3321 }
3322 //load aml_IIR lib
3323 ret = load_aml_IIR_lib();
3324 if (ret < 0) {
3325 ALOGE("%s, Load aml_IIR lib fail!\n", __FUNCTION__);
3326 out->has_aml_IIR_lib = 0;
3327 } else {
3328 char value[PROPERTY_VALUE_MAX];
3329 int paramter = 0;
3330 if (property_get("media.audio.LFP.paramter", value, NULL) > 0) {
3331 paramter = atoi(value);
3332 }
3333 aml_IIR_init(paramter);
3334 out->has_aml_IIR_lib = 1;
3335 }
3336 }
3337 return 0;
3338
3339err_open:
3340 free(out);
3341 *stream_out = NULL;
3342 return ret;
3343}
3344
3345static void adev_close_output_stream(struct audio_hw_device *dev,
3346 struct audio_stream_out *stream)
3347{
3348 struct aml_stream_out *out = (struct aml_stream_out *)stream;
3349 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3350 bool hwsync_lpcm = false;
3351 LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream);
3352 if (out->is_tv_platform == 1) {
3353 free(out->tmp_buffer_8ch);
3354 free(out->audioeffect_tmp_buffer);
3355 }
3356
3357 hwsync_lpcm = (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && audio_is_linear_pcm(out->hal_format));
3358 if (out->flags & AUDIO_OUTPUT_FLAG_PRIMARY || hwsync_lpcm) {
3359 out_standby(&stream->common);
3360 } else if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
3361 out_standby_direct(&stream->common);
3362 }
3363 if (adev->hwsync_output == out) {
3364 ALOGI("clear hwsync output when close stream\n");
3365 adev->hwsync_output = NULL;
3366 }
3367 free(stream);
3368}
3369
3370static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3371{
3372 LOGFUNC("%s(%p, %s)", __FUNCTION__, dev, kvpairs);
3373
3374 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3375 struct str_parms *parms;
3376 char *str;
3377 char value[32];
3378 int ret;
3379 parms = str_parms_create_str(kvpairs);
3380 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3381 if (ret >= 0) {
3382 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
3383 adev->low_power = false;
3384 } else {
3385 adev->low_power = true;
3386 }
3387 }
3388 str_parms_destroy(parms);
3389 return ret;
3390}
3391
3392static char * adev_get_parameters(const struct audio_hw_device *dev __unused,
3393 const char *keys __unused)
3394{
3395 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3396 if (!strcmp(keys, AUDIO_PARAMETER_HW_AV_SYNC)) {
3397 ALOGI("get hwsync id\n");
3398 return strdup("hw_av_sync=12345678");
3399 }
3400 if (!strcmp(keys, AUDIO_PARAMETER_HW_AV_EAC3_SYNC)) {
3401 return strdup("true");
3402 }
3403 return strdup("");
3404}
3405
3406static int adev_init_check(const struct audio_hw_device *dev __unused)
3407{
3408 return 0;
3409}
3410
3411static int adev_set_voice_volume(struct audio_hw_device *dev __unused, float volume __unused)
3412{
3413 return 0;
3414}
3415
3416static int adev_set_master_volume(struct audio_hw_device *dev __unused, float volume __unused)
3417{
3418 return -ENOSYS;
3419}
3420
3421static int adev_get_master_volume(struct audio_hw_device *dev __unused,
3422 float *volume __unused)
3423{
3424 return -ENOSYS;
3425}
3426
3427static int adev_set_master_mute(struct audio_hw_device *dev __unused, bool muted __unused)
3428{
3429 return -ENOSYS;
3430}
3431
3432static int adev_get_master_mute(struct audio_hw_device *dev __unused, bool *muted __unused)
3433{
3434 return -ENOSYS;
3435}
3436static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
3437{
3438 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3439 LOGFUNC("%s(%p, %d)", __FUNCTION__, dev, mode);
3440
3441 pthread_mutex_lock(&adev->lock);
3442 if (adev->mode != mode) {
3443 adev->mode = mode;
3444 select_mode(adev);
3445 }
3446 pthread_mutex_unlock(&adev->lock);
3447
3448 return 0;
3449}
3450
3451static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
3452{
3453 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3454
3455 adev->mic_mute = state;
3456
3457 return 0;
3458}
3459
3460static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
3461{
3462 struct aml_audio_device *adev = (struct aml_audio_device *)dev;
3463
3464 *state = adev->mic_mute;
3465
3466 return 0;
3467
3468}
3469
3470static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
3471 const struct audio_config *config)
3472{
3473 size_t size;
3474 int channel_count = popcount(config->channel_mask);
3475
3476 LOGFUNC("%s(%p, %d, %d, %d)", __FUNCTION__, dev, config->sample_rate,
3477 config->format, channel_count);
3478 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
3479 return 0;
3480 }
3481
3482 return get_input_buffer_size(config->frame_count, config->sample_rate,
3483 config->format, channel_count);
3484
3485}
3486
3487static int adev_open_input_stream(struct audio_hw_device *dev,
3488 audio_io_handle_t handle __unused,
3489 audio_devices_t devices,
3490 struct audio_config *config,
3491 struct audio_stream_in **stream_in,
3492 audio_input_flags_t flags __unused,
3493 const char *address __unused,
3494 audio_source_t source __unused)
3495{
3496 struct aml_audio_device *ladev = (struct aml_audio_device *)dev;
3497 struct aml_stream_in *in;
3498 int ret;
3499 int channel_count = popcount(config->channel_mask);
3500 LOGFUNC("%s(%#x, %d, 0x%04x, %d)", __FUNCTION__,
3501 devices, config->format, config->channel_mask, config->sample_rate);
3502 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
3503 return -EINVAL;
3504 }
3505
3506 in = (struct aml_stream_in *)calloc(1, sizeof(struct aml_stream_in));
3507 if (!in) {
3508 return -ENOMEM;
3509 }
3510
3511 in->stream.common.get_sample_rate = in_get_sample_rate;
3512 in->stream.common.set_sample_rate = in_set_sample_rate;
3513 in->stream.common.get_buffer_size = in_get_buffer_size;
3514 in->stream.common.get_channels = in_get_channels;
3515 in->stream.common.get_format = in_get_format;
3516 in->stream.common.set_format = in_set_format;
3517 in->stream.common.standby = in_standby;
3518 in->stream.common.dump = in_dump;
3519 in->stream.common.set_parameters = in_set_parameters;
3520 in->stream.common.get_parameters = in_get_parameters;
3521 in->stream.common.add_audio_effect = in_add_audio_effect;
3522 in->stream.common.remove_audio_effect = in_remove_audio_effect;
3523 in->stream.set_gain = in_set_gain;
3524 in->stream.read = in_read;
3525 in->stream.get_input_frames_lost = in_get_input_frames_lost;
3526
3527 in->requested_rate = config->sample_rate;
3528
3529 in->device = devices & ~AUDIO_DEVICE_BIT_IN;
3530 if (in->device & AUDIO_DEVICE_IN_ALL_SCO) {
3531 memcpy(&in->config, &pcm_config_bt, sizeof(pcm_config_bt));
3532 } else {
3533 memcpy(&in->config, &pcm_config_in, sizeof(pcm_config_in));
3534 }
3535
3536 if (in->config.channels == 1) {
3537 config->channel_mask = AUDIO_CHANNEL_IN_MONO;
3538 } else if (in->config.channels == 2) {
3539 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
3540 } else {
3541 ALOGE("Bad value of channel count : %d", in->config.channels);
3542 }
3543 in->buffer = malloc(in->config.period_size *
3544 audio_stream_in_frame_size(&in->stream));
3545 if (!in->buffer) {
3546 ret = -ENOMEM;
3547 goto err_open;
3548 }
3549
3550 if (in->requested_rate != in->config.rate) {
3551 LOGFUNC("%s(in->requested_rate=%d, in->config.rate=%d)",
3552 __FUNCTION__, in->requested_rate, in->config.rate);
3553 in->buf_provider.get_next_buffer = get_next_buffer;
3554 in->buf_provider.release_buffer = release_buffer;
3555 ret = create_resampler(in->config.rate,
3556 in->requested_rate,
3557 in->config.channels,
3558 RESAMPLER_QUALITY_DEFAULT,
3559 &in->buf_provider,
3560 &in->resampler);
3561
3562 if (ret != 0) {
3563 ret = -EINVAL;
3564 goto err_open;
3565 }
3566 }
3567
3568 in->dev = ladev;
3569 in->standby = 1;
3570 *stream_in = &in->stream;
3571 return 0;
3572
3573err_open:
3574 if (in->resampler) {
3575 release_resampler(in->resampler);
3576 }
3577
3578 free(in);
3579 *stream_in = NULL;
3580 return ret;
3581}
3582
3583static void adev_close_input_stream(struct audio_hw_device *dev,
3584 struct audio_stream_in *stream)
3585{
3586 struct aml_stream_in *in = (struct aml_stream_in *)stream;
3587
3588 LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream);
3589 in_standby(&stream->common);
3590
3591 if (in->resampler) {
3592 free(in->buffer);
3593 release_resampler(in->resampler);
3594 }
3595 if (in->proc_buf) {
3596 free(in->proc_buf);
3597 }
3598 if (in->ref_buf) {
3599 free(in->ref_buf);
3600 }
3601
3602 free(stream);
3603
3604 return;
3605}
3606
3607static int adev_dump(const audio_hw_device_t *device __unused, int fd __unused)
3608{
3609 return 0;
3610}
3611
3612static int adev_close(hw_device_t *device)
3613{
3614 struct aml_audio_device *adev = (struct aml_audio_device *)device;
3615
3616 audio_route_free(adev->ar);
3617 free(device);
3618 return 0;
3619}
3620
3621static int adev_open(const hw_module_t* module, const char* name,
3622 hw_device_t** device)
3623{
3624 struct aml_audio_device *adev;
3625 int card = CARD_AMLOGIC_BOARD;
3626 int ret;
3627 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
3628 return -EINVAL;
3629 }
3630
3631 adev = calloc(1, sizeof(struct aml_audio_device));
3632 if (!adev) {
3633 return -ENOMEM;
3634 }
3635
3636 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
3637 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
3638 adev->hw_device.common.module = (struct hw_module_t *) module;
3639 adev->hw_device.common.close = adev_close;
3640
3641 adev->hw_device.init_check = adev_init_check;
3642 adev->hw_device.set_voice_volume = adev_set_voice_volume;
3643 adev->hw_device.set_master_volume = adev_set_master_volume;
3644 adev->hw_device.get_master_volume = adev_get_master_volume;
3645 adev->hw_device.set_master_mute = adev_set_master_mute;
3646 adev->hw_device.get_master_mute = adev_get_master_mute;
3647 adev->hw_device.set_mode = adev_set_mode;
3648 adev->hw_device.set_mic_mute = adev_set_mic_mute;
3649 adev->hw_device.get_mic_mute = adev_get_mic_mute;
3650 adev->hw_device.set_parameters = adev_set_parameters;
3651 adev->hw_device.get_parameters = adev_get_parameters;
3652 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
3653 adev->hw_device.open_output_stream = adev_open_output_stream;
3654 adev->hw_device.close_output_stream = adev_close_output_stream;
3655 adev->hw_device.open_input_stream = adev_open_input_stream;
3656 adev->hw_device.close_input_stream = adev_close_input_stream;
3657 adev->hw_device.dump = adev_dump;
3658 card = get_aml_card();
3659 if ((card < 0) || (card > 7)) {
3660 ALOGE("error to get audio card");
3661 return -EINVAL;
3662 }
3663
3664 adev->card = card;
3665 adev->ar = audio_route_init(adev->card, MIXER_XML_PATH);
3666
3667 /* Set the default route before the PCM stream is opened */
3668 adev->mode = AUDIO_MODE_NORMAL;
3669 adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
3670 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
3671
3672 select_devices(adev);
3673
3674 *device = &adev->hw_device.common;
3675 return 0;
3676}
3677
3678static struct hw_module_methods_t hal_module_methods = {
3679 .open = adev_open,
3680};
3681
3682struct audio_module HAL_MODULE_INFO_SYM = {
3683 .common = {
3684 .tag = HARDWARE_MODULE_TAG,
3685 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
3686 .hal_api_version = HARDWARE_HAL_API_VERSION,
3687 .id = AUDIO_HARDWARE_MODULE_ID,
3688 .name = "aml audio HW HAL",
3689 .author = "amlogic, Corp.",
3690 .methods = &hal_module_methods,
3691 },
3692};
3693