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