summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2014-10-21 06:13:21 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2014-10-21 06:13:21 -0700
commit78227db665d30fbca88a7a6501ba5be9b360c017 (patch)
tree3f00c82a7757f6475ef0e9e474ab070006a6d26f
parentc684939337cc5ffb3aadc3c97f2bcff8c326ab3b (diff)
parentdc9bb157cfc67e42e534da9f873beeb4673e1b36 (diff)
downloadandroid_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.c95
-rw-r--r--hal/audio_hw.h3
-rw-r--r--hal/msm8916/platform.h4
-rw-r--r--hal/msm8960/platform.h4
-rw-r--r--hal/msm8974/platform.h4
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