summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2015-08-13 16:46:44 -0700
committerGlenn Kasten <gkasten@google.com>2015-08-14 10:08:40 -0700
commit1d4984a8a2d5c96ee7d14a0a224477ff4d4fa870 (patch)
tree5a71cfcb0ea85348e511a5ffbada8263e8e755c6
parentff6eb80bd1e35ea3dbf988ef3e0bb743b364b571 (diff)
downloadflounder-1d4984a8a2d5c96ee7d14a0a224477ff4d4fa870.tar.gz
Fix distorted audio while on hangouts call
Bug: 22594886 Change-Id: I1caa47d0b217de083a68483a1cea4b9addb1b170
-rw-r--r--audio/hal/audio_hw.c58
-rw-r--r--audio/hal/audio_hw.h5
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;