diff options
author | Glenn Kasten <gkasten@google.com> | 2015-08-13 16:46:44 -0700 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2015-08-14 10:08:40 -0700 |
commit | 1d4984a8a2d5c96ee7d14a0a224477ff4d4fa870 (patch) | |
tree | 5a71cfcb0ea85348e511a5ffbada8263e8e755c6 | |
parent | ff6eb80bd1e35ea3dbf988ef3e0bb743b364b571 (diff) | |
download | flounder-1d4984a8a2d5c96ee7d14a0a224477ff4d4fa870.tar.gz |
Fix distorted audio while on hangouts call
Bug: 22594886
Change-Id: I1caa47d0b217de083a68483a1cea4b9addb1b170
-rw-r--r-- | audio/hal/audio_hw.c | 58 | ||||
-rw-r--r-- | audio/hal/audio_hw.h | 5 |
2 files changed, 42 insertions, 21 deletions
diff --git a/audio/hal/audio_hw.c b/audio/hal/audio_hw.c index 11b60fd..6f16ee2 100644 --- a/audio/hal/audio_hw.c +++ b/audio/hal/audio_hw.c @@ -92,6 +92,24 @@ static struct pcm_device_profile pcm_device_capture = { .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC, }; +static struct pcm_device_profile pcm_device_capture_low_latency = { + .config = { + .channels = CAPTURE_DEFAULT_CHANNEL_COUNT, + .rate = CAPTURE_DEFAULT_SAMPLING_RATE, + .period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY, + .period_count = CAPTURE_PERIOD_COUNT_LOW_LATENCY, + .format = PCM_FORMAT_S16_LE, + .start_threshold = CAPTURE_START_THRESHOLD, + .stop_threshold = 0, + .silence_threshold = 0, + .avail_min = 0, + }, + .card = SOUND_CARD, + .id = 0, + .type = PCM_CAPTURE_LOW_LATENCY, + .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC, +}; + static struct pcm_device_profile pcm_device_capture_loopback_aec = { .config = { .channels = CAPTURE_DEFAULT_CHANNEL_COUNT, @@ -169,6 +187,7 @@ static struct pcm_device_profile pcm_device_hotword_streaming = { static struct pcm_device_profile * const pcm_devices[] = { &pcm_device_playback, &pcm_device_capture, + &pcm_device_capture_low_latency, &pcm_device_playback_sco, &pcm_device_capture_sco, &pcm_device_capture_loopback_aec, @@ -1177,6 +1196,7 @@ static int get_hw_echo_reference(struct stream_in *in) adev->primary_output->devices == AUDIO_DEVICE_OUT_SPEAKER) { struct audio_stream *stream = &adev->primary_output->stream.common; + // TODO: currently there is no low latency mode for aec reference. ref_pcm_profile = get_pcm_device(PCM_CAPTURE, pcm_device_capture_loopback_aec.devices); if (ref_pcm_profile == NULL) { ALOGE("%s: Could not find PCM device id for the usecase(%d)", @@ -1184,12 +1204,6 @@ static int get_hw_echo_reference(struct stream_in *in) return -EINVAL; } - if (in->input_flags & AUDIO_INPUT_FLAG_FAST) { - ALOGV("%s: change capture period size to low latency size %d", - __func__, CAPTURE_PERIOD_SIZE_LOW_LATENCY); - ref_pcm_profile->config.period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY; - } - ref_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device)); ref_device->pcm_profile = ref_pcm_profile; @@ -1936,8 +1950,7 @@ static int start_input_stream(struct stream_in *in) ALOGV("%s: enter: usecase(%d)", __func__, in->usecase); adev->active_input = in; - pcm_profile = get_pcm_device(in->usecase == USECASE_AUDIO_CAPTURE_HOTWORD - ? PCM_HOTWORD_STREAMING : PCM_CAPTURE, in->devices); + pcm_profile = get_pcm_device(in->usecase_type, in->devices); if (pcm_profile == NULL) { ALOGE("%s: Could not find PCM device id for the usecase(%d)", __func__, in->usecase); @@ -1945,12 +1958,6 @@ static int start_input_stream(struct stream_in *in) goto error_config; } - if (in->input_flags & AUDIO_INPUT_FLAG_FAST) { - ALOGV("%s: change capture period size to low latency size %d", - __func__, CAPTURE_PERIOD_SIZE_LOW_LATENCY); - pcm_profile->config.period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY; - } - uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase)); uc_info->id = in->usecase; uc_info->type = PCM_CAPTURE; @@ -2556,6 +2563,7 @@ static int check_input_parameters(uint32_t sample_rate, static size_t get_input_buffer_size(uint32_t sample_rate, audio_format_t format, int channel_count, + usecase_type_t usecase_type, audio_devices_t devices) { size_t size = 0; @@ -2564,7 +2572,7 @@ static size_t get_input_buffer_size(uint32_t sample_rate, if (check_input_parameters(sample_rate, format, channel_count) != 0) return 0; - pcm_profile = get_pcm_device(PCM_CAPTURE, devices); + pcm_profile = get_pcm_device(usecase_type, devices); if (pcm_profile == NULL) return 0; @@ -3464,6 +3472,7 @@ static size_t in_get_buffer_size(const struct audio_stream *stream) return get_input_buffer_size(in->requested_rate, in_get_format(stream), audio_channel_count_from_in_mask(in->main_channels), + in->usecase_type, in->devices); } @@ -4263,6 +4272,7 @@ static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, return get_input_buffer_size(config->sample_rate, config->format, audio_channel_count_from_in_mask(config->channel_mask), + PCM_CAPTURE /* usecase_type */, AUDIO_DEVICE_IN_BUILTIN_MIC); } @@ -4286,10 +4296,17 @@ static int adev_open_input_stream(struct audio_hw_device *dev, audio_channel_count_from_in_mask(config->channel_mask)) != 0) return -EINVAL; - if (source == AUDIO_SOURCE_HOTWORD) { - pcm_profile = get_pcm_device(PCM_HOTWORD_STREAMING, devices); - } else { - pcm_profile = get_pcm_device(PCM_CAPTURE, devices); + usecase_type_t usecase_type = source == AUDIO_SOURCE_HOTWORD ? + PCM_HOTWORD_STREAMING : flags & AUDIO_INPUT_FLAG_FAST ? + PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE; + pcm_profile = get_pcm_device(usecase_type, devices); + if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) { + // a low latency profile may not exist for that device, fall back + // to regular capture. the MixerThread automatically changes + // to non-fast capture based on the buffer size. + flags &= ~AUDIO_INPUT_FLAG_FAST; + usecase_type = PCM_CAPTURE; + pcm_profile = get_pcm_device(usecase_type, devices); } if (pcm_profile == NULL) return -EINVAL; @@ -4331,6 +4348,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev, } else { in->usecase = USECASE_AUDIO_CAPTURE; } + in->usecase_type = usecase_type; pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL); pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL); @@ -4775,7 +4793,7 @@ static int adev_open(const hw_module_t *module, const char *name, pcm_device_playback.config.stop_threshold = PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT); - pcm_device_capture.config.period_size = trial; + pcm_device_capture_low_latency.config.period_size = trial; } } diff --git a/audio/hal/audio_hw.h b/audio/hal/audio_hw.h index 3ed2cb5..8b097e1 100644 --- a/audio/hal/audio_hw.h +++ b/audio/hal/audio_hw.h @@ -163,6 +163,7 @@ enum { #define CAPTURE_PERIOD_SIZE 1024 #define CAPTURE_PERIOD_SIZE_LOW_LATENCY 256 #define CAPTURE_PERIOD_COUNT 2 +#define CAPTURE_PERIOD_COUNT_LOW_LATENCY 2 #define CAPTURE_DEFAULT_CHANNEL_COUNT 2 #define CAPTURE_DEFAULT_SAMPLING_RATE 48000 #define CAPTURE_START_THRESHOLD 1 @@ -232,7 +233,8 @@ typedef enum { PCM_PLAYBACK = 0x1, PCM_CAPTURE = 0x2, VOICE_CALL = 0x4, - PCM_HOTWORD_STREAMING = 0x8 + PCM_HOTWORD_STREAMING = 0x8, + PCM_CAPTURE_LOW_LATENCY = 0x10, } usecase_type_t; struct offload_cmd { @@ -322,6 +324,7 @@ struct stream_in { audio_devices_t devices; uint32_t main_channels; audio_usecase_t usecase; + usecase_type_t usecase_type; bool enable_aec; audio_input_flags_t input_flags; |