diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2014-10-21 06:13:21 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-10-21 06:13:21 -0700 |
commit | 78227db665d30fbca88a7a6501ba5be9b360c017 (patch) | |
tree | 3f00c82a7757f6475ef0e9e474ab070006a6d26f | |
parent | c684939337cc5ffb3aadc3c97f2bcff8c326ab3b (diff) | |
parent | dc9bb157cfc67e42e534da9f873beeb4673e1b36 (diff) | |
download | android_hardware_qcom_audio-78227db665d30fbca88a7a6501ba5be9b360c017.tar.gz android_hardware_qcom_audio-78227db665d30fbca88a7a6501ba5be9b360c017.tar.bz2 android_hardware_qcom_audio-78227db665d30fbca88a7a6501ba5be9b360c017.zip |
Merge "hal: add support for low-latency capture"
-rw-r--r-- | hal/audio_hw.c | 95 | ||||
-rw-r--r-- | hal/audio_hw.h | 3 | ||||
-rw-r--r-- | hal/msm8916/platform.h | 4 | ||||
-rw-r--r-- | hal/msm8960/platform.h | 4 | ||||
-rw-r--r-- | hal/msm8974/platform.h | 4 |
5 files changed, 87 insertions, 23 deletions
diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 627900bb..b7078099 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -63,6 +63,9 @@ #define USECASE_AUDIO_PLAYBACK_PRIMARY USECASE_AUDIO_PLAYBACK_DEEP_BUFFER +static unsigned int configured_low_latency_capture_period_size = + LOW_LATENCY_CAPTURE_PERIOD_SIZE; + struct pcm_config pcm_config_deep_buffer = { .channels = 2, .rate = DEFAULT_OUTPUT_SAMPLING_RATE, @@ -288,6 +291,19 @@ static int enable_audio_route_for_voice_usecases(struct audio_device *adev, return 0; } +int pcm_ioctl(struct pcm *pcm, int request, ...) +{ + va_list ap; + void * arg; + int pcm_fd = *(int*)pcm; + + va_start(ap, request); + arg = va_arg(ap, void *); + va_end(ap); + + return ioctl(pcm_fd, request, arg); +} + int enable_audio_route(struct audio_device *adev, struct audio_usecase *usecase) { @@ -1439,7 +1455,8 @@ 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) + int channel_count, + bool is_low_latency) { size_t size = 0; @@ -1447,13 +1464,19 @@ static size_t get_input_buffer_size(uint32_t sample_rate, return 0; size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000; + if (is_low_latency) + size = configured_low_latency_capture_period_size; /* ToDo: should use frame_size computed based on the format and channel_count here. */ size *= sizeof(short) * channel_count; - /* make sure the size is multiple of 64 */ - size += 0x3f; - size &= ~0x3f; + /* make sure the size is multiple of 32 bytes + * At 48 kHz mono 16-bit PCM: + * 5.000 ms = 240 frames = 15*16*1*2 = 480, a whole multiple of 32 (15) + * 3.333 ms = 160 frames = 10*16*1*2 = 320, a whole multiple of 32 (10) + */ + size += 0x1f; + size &= ~0x1f; return size; } @@ -2970,7 +2993,8 @@ static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev __unu { int channel_count = audio_channel_count_from_in_mask(config->channel_mask); - return get_input_buffer_size(config->sample_rate, config->format, channel_count); + return get_input_buffer_size(config->sample_rate, config->format, channel_count, + false /* is_low_latency: since we don't know, be conservative */); } static int adev_open_input_stream(struct audio_hw_device *dev, @@ -2986,7 +3010,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev, struct stream_in *in; int ret = 0, buffer_size, frame_size; int channel_count = audio_channel_count_from_in_mask(config->channel_mask); - + bool is_low_latency = false; *stream_in = NULL; if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) @@ -3030,6 +3054,13 @@ static int adev_open_input_stream(struct audio_hw_device *dev, /* Update config params with the requested sample rate and channels */ in->usecase = USECASE_AUDIO_RECORD; + if (config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE && + (flags & AUDIO_INPUT_FLAG_FAST) != 0) { + is_low_latency = true; +#if LOW_LATENCY_CAPTURE_USE_CASE + in->usecase = USECASE_AUDIO_RECORD_LOW_LATENCY; +#endif + } in->config = pcm_config_audio_capture; in->config.rate = config->sample_rate; in->format = config->format; @@ -3053,7 +3084,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev, frame_size = audio_stream_in_frame_size(&in->stream); buffer_size = get_input_buffer_size(config->sample_rate, config->format, - channel_count); + channel_count, + is_low_latency); in->config.period_size = buffer_size / frame_size; } @@ -3135,6 +3167,23 @@ static int adev_close(hw_device_t *device) return 0; } +/* This returns 1 if the input parameter looks at all plausible as a low latency period size, + * or 0 otherwise. A return value of 1 doesn't mean the value is guaranteed to work, + * just that it _might_ work. + */ +static int period_size_is_plausible_for_low_latency(int period_size) +{ + switch (period_size) { + case 160: + case 240: + case 320: + case 480: + return 1; + default: + return 0; + } +} + static int adev_open(const hw_module_t *module, const char *name, hw_device_t **device) { @@ -3258,25 +3307,31 @@ static int adev_open(const hw_module_t *module, const char *name, &adev->streams_output_cfg_list); audio_device_ref_count++; + + char value[PROPERTY_VALUE_MAX]; + int trial; + if (property_get("audio_hal.period_size", value, NULL) > 0) { + trial = atoi(value); + if (period_size_is_plausible_for_low_latency(trial)) { + pcm_config_low_latency.period_size = trial; + pcm_config_low_latency.start_threshold = trial / 4; + pcm_config_low_latency.avail_min = trial / 4; + configured_low_latency_capture_period_size = trial; + } + } + if (property_get("audio_hal.in_period_size", value, NULL) > 0) { + trial = atoi(value); + if (period_size_is_plausible_for_low_latency(trial)) { + configured_low_latency_capture_period_size = trial; + } + } + pthread_mutex_unlock(&adev_init_lock); ALOGV("%s: exit", __func__); return 0; } -int pcm_ioctl(struct pcm *pcm, int request, ...) -{ - va_list ap; - void * arg; - int pcm_fd = *(int*)pcm; - - va_start(ap, request); - arg = va_arg(ap, void *); - va_end(ap); - - return ioctl(pcm_fd, request, arg); -} - static struct hw_module_methods_t hal_module_methods = { .open = adev_open, }; diff --git a/hal/audio_hw.h b/hal/audio_hw.h index bdb9aae4..a810674b 100644 --- a/hal/audio_hw.h +++ b/hal/audio_hw.h @@ -32,9 +32,6 @@ #define VISUALIZER_LIBRARY_PATH "/system/lib/soundfx/libqcomvisualizer.so" #define OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH "/system/lib/soundfx/libqcompostprocbundle.so" -#define BT_SCO_SAMPLE_RATE "bt-sco-samplerate" -#define BT_SCO_WB_SAMPLE_RATE "bt-sco-wb-samplerate" - /* Flags used to initialize acdb_settings variable that goes to ACDB library */ #define NONE_FLAG 0x00000000 #define ANC_FLAG 0x00000001 diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h index dec9edad..e38503fe 100644 --- a/hal/msm8916/platform.h +++ b/hal/msm8916/platform.h @@ -164,6 +164,10 @@ enum { #define LOW_LATENCY_OUTPUT_PERIOD_SIZE 240 #define LOW_LATENCY_OUTPUT_PERIOD_COUNT 2 +#define LOW_LATENCY_CAPTURE_SAMPLE_RATE 48000 +#define LOW_LATENCY_CAPTURE_PERIOD_SIZE 240 +#define LOW_LATENCY_CAPTURE_USE_CASE 0 + #define HDMI_MULTI_PERIOD_SIZE 336 #define HDMI_MULTI_PERIOD_COUNT 8 #define HDMI_MULTI_DEFAULT_CHANNEL_COUNT 6 diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h index 20984d85..491aa1af 100644 --- a/hal/msm8960/platform.h +++ b/hal/msm8960/platform.h @@ -138,4 +138,8 @@ enum { /* Define macro for Internal FM volume mixer */ #define FM_RX_VOLUME "Internal FM RX Volume" +#define LOW_LATENCY_CAPTURE_SAMPLE_RATE 48000 +#define LOW_LATENCY_CAPTURE_PERIOD_SIZE 240 +#define LOW_LATENCY_CAPTURE_USE_CASE 0 + #endif // QCOM_AUDIO_PLATFORM_H diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h index 62aa40a0..93b0a702 100644 --- a/hal/msm8974/platform.h +++ b/hal/msm8974/platform.h @@ -178,6 +178,10 @@ enum { #define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20 #define AUDIO_CAPTURE_PERIOD_COUNT 2 +#define LOW_LATENCY_CAPTURE_SAMPLE_RATE 48000 +#define LOW_LATENCY_CAPTURE_PERIOD_SIZE 240 +#define LOW_LATENCY_CAPTURE_USE_CASE 1 + #define DEVICE_NAME_MAX_SIZE 128 #define HW_INFO_ARRAY_MAX_SIZE 32 |