author | xiaojing.huang <xiaojing.huang@amlogic.com> | 2018-05-04 15:13:31 (GMT) |
---|---|---|
committer | xiaojing.huang <xiaojing.huang@amlogic.com> | 2018-05-04 15:13:58 (GMT) |
commit | 3f7ef8a9461b5cadaaad0f3ccf81bbaf4567f215 (patch) | |
tree | 1c0ed9e59c74f7d63d9d19f4bfdf900c165c5682 | |
parent | 9a85caf05941e1c758f4450221ab277f97611720 (diff) | |
download | amlogic-o-amlogic.zip amlogic-o-amlogic.tar.gz amlogic-o-amlogic.tar.bz2 |
fix Google assistant can't work via mic after switching HDMI input
PD#165452
Change-Id: I88c84c67b08dddae94a1684e91e85b2f9b39aba9
-rwxr-xr-x[-rw-r--r--] | audio/audio_hal/aml_hw_mixer.c | 41 | ||||
-rwxr-xr-x[-rw-r--r--] | audio/audio_hal/audio_hw.c | 130 |
2 files changed, 99 insertions, 72 deletions
diff --git a/audio/audio_hal/aml_hw_mixer.c b/audio/audio_hal/aml_hw_mixer.c index d725a4f..2928fc7 100644..100755 --- a/audio/audio_hal/aml_hw_mixer.c +++ b/audio/audio_hal/aml_hw_mixer.c @@ -86,12 +86,15 @@ int aml_hw_mixer_write(struct aml_hw_mixer *mixer, const void *w_buf, uint size) unsigned write_size = size; unsigned tail = 0; + if (!mixer->start_buf) + return size; pthread_mutex_lock(&mixer->lock); space = aml_hw_mixer_get_space(mixer); + space &= ~63; if (space < size) { - ALOGI("write data no space,space %d,size %d,rp %d,wp %d,reset all ptr\n", space, size, mixer->rp, mixer->wp); - mixer->wp = 0; - mixer->rp = 0; + // ALOGI("write data no space,space %d,size %d,rp %d,wp %d,reset all ptr\n", space, size, mixer->rp, mixer->wp); + // mixer->wp = 0; + // mixer->rp = 0; } //TODO if (write_size > space) { @@ -110,7 +113,7 @@ int aml_hw_mixer_write(struct aml_hw_mixer *mixer, const void *w_buf, uint size) } pthread_mutex_unlock(&mixer->lock); - return size; + return write_size; } static inline short CLIPSHORT(int r) { @@ -118,11 +121,19 @@ static inline short CLIPSHORT(int r) (r < -0x8000) ? 0x8000 : r; } - +static inline int CLIPINT(int r) +{ + /* + return (r > 0x7fffffff) ? 0x7fffffff : + (r < -0x80000000) ? 0x80000000 : + r; + */ + return r; +} int aml_hw_mixer_mixing(struct aml_hw_mixer *mixer, void *mbuf, int size) { - int16_t *main_buf = (int16_t *)mbuf; - int16_t *cached_buf; + int32_t *main_buf = (int32_t *)mbuf; + int32_t *cached_buf; int32_t read_size = size; int32_t cached_size = 0; int32_t tail = 0, tmp; @@ -140,24 +151,24 @@ int aml_hw_mixer_mixing(struct aml_hw_mixer *mixer, void *mbuf, int size) return 0; } - cached_buf = (int16_t *)(mixer->start_buf + mixer->rp); + cached_buf = (int32_t *)(mixer->start_buf + mixer->rp); if (read_size + mixer->rp > mixer->buf_size) { tail = mixer->buf_size - mixer->rp; - for (i = 0; i < tail/2; i++) { + for (i = 0; i < tail/4; i++) { tmp = *main_buf + *cached_buf++; - *main_buf++ = CLIPSHORT(tmp); + *main_buf++ = CLIPINT(tmp); } read_size -= tail; - cached_buf = (int16_t *)mixer->start_buf; - for (i = 0; i < read_size/2; i++) { + cached_buf = (int32_t *)mixer->start_buf; + for (i = 0; i < read_size; i++) { tmp = *main_buf + *cached_buf++; - *main_buf++ = CLIPSHORT(tmp); + *main_buf++ = CLIPINT(tmp); } mixer->rp = read_size; } else { - for (i = 0; i < read_size/2; i++) { + for (i = 0; i < read_size/4; i++) { tmp = *main_buf + *cached_buf++; - *main_buf++ = CLIPSHORT(tmp); + *main_buf++ = CLIPINT(tmp); } mixer->rp += read_size; mixer->rp %= AML_HW_MIXER_BUF_SIZE; diff --git a/audio/audio_hal/audio_hw.c b/audio/audio_hal/audio_hw.c index 1117557..aa70136 100644..100755 --- a/audio/audio_hal/audio_hw.c +++ b/audio/audio_hal/audio_hw.c @@ -70,9 +70,9 @@ #include <SPDIFEncoderAD.h> #include "audio_hw_ms12.h" #endif -/*#if defined(IS_ATOM_PROJECT) +/* #if defined(IS_ATOM_PROJECT) #include "audio_aec_process.h" -#endif*/ +#endif */ /* set proprety */ #ifdef ENABLE_HUITONG @@ -616,22 +616,21 @@ static int check_input_parameters(uint32_t sample_rate, audio_format_t format, i return 0; } -static size_t get_input_buffer_size (unsigned int period_size, uint32_t sample_rate, audio_format_t format, int channel_count) +static size_t get_input_buffer_size(unsigned int period_size, uint32_t sample_rate, audio_format_t format, int channel_count) { size_t size; /* take resampling into account and return the closest majoring multiple of 16 frames, as audioflinger expects audio buffers to be a multiple of 16 frames */ - if (period_size == 0) { + if (period_size == 0) period_size = (pcm_config_in.period_size * sample_rate) / pcm_config_in.rate; - } - size = (period_size +15)/16*16; + size = (period_size + 15) / 16 * 16; if (format == AUDIO_FORMAT_PCM_32_BIT) - return size * channel_count * sizeof(int32_t); - else - return size * channel_count * sizeof (int16_t); + return size * channel_count * sizeof(int32_t); + else + return size * channel_count * sizeof(int16_t); } static uint32_t out_get_sample_rate(const struct audio_stream *stream) @@ -1153,11 +1152,11 @@ static char *out_get_parameters (const struct audio_stream *stream, const char * if (out->flags & AUDIO_OUTPUT_FLAG_PRIMARY) { ALOGI ("Amlogic - return hard coded sample_rate list for primary output stream.\n"); cap = strdup ("sup_sampling_rates=8000|11025|16000|22050|24000|32000|44100|48000"); - } else if (out->out_device & AUDIO_DEVICE_OUT_SPDIF){ - cap = strdup ("sup_sampling_rates=32000|44100|48000"); } else { if (out->out_device & AUDIO_DEVICE_OUT_HDMI_ARC) { cap = (char *) strdup_hdmi_arc_cap_default (AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES, format); + } else if (out->out_device & AUDIO_DEVICE_OUT_SPDIF){ + cap = strdup ("sup_sampling_rates=32000|44100|48000"); } else { cap = (char *) get_hdmi_sink_cap (AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES,format); } @@ -2670,6 +2669,10 @@ static int start_input_stream(struct aml_stream_in *in) } /* check to update port */ port = alsa_device_get_pcm_index(port); +#if defined(IS_ATOM_PROJECT) + if (in->device & AUDIO_DEVICE_IN_BUILTIN_MIC) + port = 2; +#endif ALOGI("%s: card(%d), port(%d)", __func__, card, port); /* this assumes routing is done previously */ in->pcm = pcm_open(card, port, PCM_IN, &in->config); @@ -2703,8 +2706,8 @@ static int in_set_sample_rate(struct audio_stream *stream __unused, uint32_t rat static size_t in_get_buffer_size(const struct audio_stream *stream) { - size_t size; struct aml_stream_in *in = (struct aml_stream_in *)stream; + size_t size; #if defined(IS_ATOM_PROJECT) audio_channel_mask_t channel_mask = in->hal_channel_mask; audio_format_t format = in->hal_format; @@ -2713,20 +2716,21 @@ static size_t in_get_buffer_size(const struct audio_stream *stream) channel_mask = AUDIO_CHANNEL_OUT_STEREO; format = AUDIO_FORMAT_PCM_32_BIT; } - ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__, - channel_mask, in->requested_rate, format); - size = get_input_buffer_size(in->config.period_size, in->requested_rate, - format, - audio_channel_count_from_in_mask(channel_mask)); + ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__, + channel_mask, in->requested_rate, format); + size = get_input_buffer_size(in->config.period_size, in->requested_rate, + format, + audio_channel_count_from_in_mask(channel_mask)); #else - ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__, - in->hal_channel_mask, in->requested_rate, in->hal_format); - size = get_input_buffer_size(in->config.period_size, in->requested_rate, - in->hal_format, - audio_channel_count_from_in_mask(in->hal_channel_mask)); + ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__, + in->hal_channel_mask, in->requested_rate, in->hal_format); + size = get_input_buffer_size(in->config.period_size, in->requested_rate, + in->hal_format, + audio_channel_count_from_in_mask(in->hal_channel_mask)); #endif - ALOGD("%s: exit: buffer_size = %zu", __func__, size); - return size; + ALOGD("%s: exit: buffer_size = %zu", __func__, size); + + return size; } static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) @@ -2787,7 +2791,7 @@ static int in_standby(struct audio_stream *stream) struct aml_stream_in *in = (struct aml_stream_in *)stream; int status; - if ((in->device & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_LINE)) && in->ref_count == 2) { + if ((in->device & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_LINE)) && in->ref_count == 2) { ALOGD("%s: ref_count = %d", __func__, in->ref_count); return 0; } @@ -2999,7 +3003,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte struct aml_audio_parser *parser = adev->aml_parser; int channel_count = audio_channel_count_from_in_mask(in->hal_channel_mask); size_t in_frames = bytes / audio_stream_in_frame_size(&in->stream); - size_t cur_in_bytes, cur_in_frames; + size_t cur_in_bytes, cur_in_frames; int ret, in_mute = 0, parental_mute = 0; /* acquiring hw device mutex systematically is useful if a low priority thread is waiting @@ -3015,11 +3019,11 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte if (ret < 0) goto exit; in->standby = 0; -/*#if defined(IS_ATOM_PROJECT) - if (in->device & AUDIO_DEVICE_IN_BUILTIN_MIC) - adev->mic_running = 1; -#endif*/ } +/* #if defined(IS_ATOM_PROJECT) + if ((in->device & AUDIO_DEVICE_IN_BUILTIN_MIC) && !adev->mic_running) + adev->mic_running = 1; +#endif */ /* if audio patch type is hdmi to mixer, check audio format from hdmi*/ if (adev->patch_src == SRC_HDMIIN && parser != NULL) { @@ -3087,7 +3091,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte mic_buf[2 * i] = tmp_buffer_8ch[8 * i + 6]; mic_buf[2 * i + 1] = tmp_buffer_8ch[8 * i + 7]; } - /* if (in->device & AUDIO_DEVICE_IN_BUILTIN_MIC) { + /* if (in->device & AUDIO_DEVICE_IN_BUILTIN_MIC) { int read_bytes = in->requested_rate == 16000 ? 60 + cur_in_bytes : 20 + cur_in_bytes; if (adev->spk_buf_size < cur_in_bytes) { ALOGI("%s: realloc spk_buf size from %zu to %zu", __func__, adev->spk_buf_size, cur_in_bytes); @@ -3848,7 +3852,7 @@ static int adev_set_parameters (struct audio_hw_device *dev, const char *kvpairs ret = aml_audio_output_routing (dev, adev->active_outport, true); if (ret < 0) ALOGE ("%s() output routing failed", __func__); - goto exit; + goto exit; } ret = str_parms_get_str(parms, "spdif_raw_enable", value, sizeof(value)); if (ret >= 0) { @@ -4128,17 +4132,19 @@ static int adev_get_mic_mute (const struct audio_hw_device *dev, bool *state) static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev __unused, const struct audio_config *config) { - size_t size; int channel_count = audio_channel_count_from_in_mask(config->channel_mask); + size_t size; - ALOGD("%s: channel_mask(%#x) rate(%d) format(%#x)", __func__, + ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__, config->channel_mask, config->sample_rate, config->format); if (check_input_parameters(config->sample_rate, config->format, channel_count) < 0) return -EINVAL; - - size = get_input_buffer_size(config->frame_count, config->sample_rate, config->format, channel_count); - + + size = get_input_buffer_size(config->frame_count, config->sample_rate, config->format, channel_count); + + ALOGD("%s: exit: buffer_size = %zu", __func__, size); + return size; } @@ -4282,26 +4288,28 @@ static int adev_open_input_stream(struct audio_hw_device *dev, } #endif #if defined(IS_ATOM_PROJECT) - if (aux_mic_devce) { - in->config.channels = 8; - in->config.format = PCM_FORMAT_S32_LE; - adev->aux_mic_in = in; - } exit: - if (aux_mic_devce & AUDIO_DEVICE_IN_BUILTIN_MIC) { - /* aec_spk_mic_init(); - if (!adev->spk_ring_buf.start_addr) - ring_buffer_init(&adev->spk_ring_buf, 4 * (20 + 2 * 4 * DEFAULT_PLAYBACK_PERIOD_SIZE) * PLAYBACK_PERIOD_COUNT); - else - ring_buffer_reset(&adev->spk_ring_buf); */ - if (in->ref_count > 0) { - in->requested_rate = config->sample_rate; - in->hal_channel_mask = config->channel_mask; - in->hal_format = config->format; + if (aux_mic_devce) { + if (in->ref_count == 0) { + in->config.channels = 8; + in->config.format = PCM_FORMAT_S32_LE; + adev->aux_mic_in = in; + } + if (aux_mic_devce & AUDIO_DEVICE_IN_BUILTIN_MIC) { + /* aec_spk_mic_init(); + if (!adev->spk_ring_buf.start_addr) + ring_buffer_init(&adev->spk_ring_buf, 4 * (20 + 2 * 4 * DEFAULT_PLAYBACK_PERIOD_SIZE) * PLAYBACK_PERIOD_COUNT); + else + ring_buffer_reset(&adev->spk_ring_buf); */ + if (in->ref_count > 0) { + in->requested_rate = config->sample_rate; + in->hal_channel_mask = config->channel_mask; + in->hal_format = config->format; + } + set_audio_source(LINEIN); } - } - if (aux_mic_devce) in->device |= aux_mic_devce; + } in->ref_count++; #endif *stream_in = &in->stream; @@ -5154,12 +5162,20 @@ ssize_t mixer_aux_buffer_write (struct audio_stream_out *stream, const void *buf if (ret == 0) bytes = used_size; #else - aml_hw_mixer_write (&adev->hw_mixer, buffer, bytes); + ret = aml_hw_mixer_write (&adev->hw_mixer, buffer, bytes); + if (ret == (int)bytes) { + usleep(bytes * 1000000 / audio_stream_out_frame_size (stream) / + out_get_sample_rate (&stream->common) * 15 / 16); + } else { + usleep(bytes * 1000000 / audio_stream_out_frame_size (stream) / + out_get_sample_rate (&stream->common) * 15 / 16)*2; + } #endif + in_frames = ret/frame_size; clock_gettime (CLOCK_MONOTONIC, &aml_out->timestamp); aml_out->frame_write_sum += in_frames; aml_out->last_frames_postion = aml_out->frame_write_sum; - return bytes; + return ret; } ssize_t process_buffer_write(struct audio_stream_out *stream, @@ -5959,7 +5975,7 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, // tell atv or dtv source and decide to create or not. // One more case is ATV->ATV, should recreate audio patch. if (input_src != ATV || (input_src == ATV && aml_dev->patch_src == SRC_ATV)) { - set_audio_source (input_src); + set_audio_source(input_src); ret = create_patch(dev, sources->ext.device.type, sinks->ext.device.type); if (ret) { ALOGE("%s: create patch failed", __func__); |