For high sample rates, lock input & output sample rate if possible.
Bug: 80363107
Test: connect Mi Noise-cancelling headset and confirm input and output
Connect varius music-oriented interfaces and verify simultaneous play/record with no stutters.
Change-Id: I81ae019b85662f0a71efdd143ac6abe6d6a1a742
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c
index 746a3c9..d797a21 100644
--- a/modules/usbaudio/audio_hal.c
+++ b/modules/usbaudio/audio_hal.c
@@ -47,6 +47,9 @@
/* Lock play & record samples rates at or above this threshold */
#define RATELOCK_THRESHOLD 96000
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
struct audio_device {
struct audio_hw_device hw_device;
@@ -62,7 +65,7 @@
/* lock input & output sample rates */
/*FIXME - How do we address multiple output streams? */
- uint32_t device_sample_rate;
+ uint32_t device_sample_rate; // this should be a rate that is common to both input & output
bool mic_muted;
@@ -597,6 +600,7 @@
ret = -EINVAL;
}
+ /* TODO: This is a problem if the input does not support this rate */
out->adev->device_sample_rate = config->sample_rate;
device_unlock(out->adev);
@@ -1022,20 +1026,36 @@
}
/* Rate */
+ int request_config_rate = config->sample_rate;
if (config->sample_rate == 0) {
config->sample_rate = profile_get_default_sample_rate(in->profile);
}
- if (in->adev->device_sample_rate != 0 && /* we are playing, so lock the rate */
+ if (in->adev->device_sample_rate != 0 && /* we are playing, so lock the rate if possible */
in->adev->device_sample_rate >= RATELOCK_THRESHOLD) {/* but only for high sample rates */
- ret = config->sample_rate != in->adev->device_sample_rate ? -EINVAL : 0;
- proxy_config.rate = config->sample_rate = in->adev->device_sample_rate;
+ if (config->sample_rate != in->adev->device_sample_rate) {
+ unsigned highest_rate = profile_get_highest_sample_rate(in->profile);
+ if (highest_rate == 0) {
+ ret = -EINVAL; /* error with device */
+ } else {
+ proxy_config.rate = config->sample_rate =
+ min(highest_rate, in->adev->device_sample_rate);
+ if (request_config_rate != 0 && proxy_config.rate != config->sample_rate) {
+ /* Changing the requested rate */
+ ret = -EINVAL;
+ } else {
+ /* Everything AOK! */
+ ret = 0;
+ }
+ }
+ }
} else if (profile_is_sample_rate_valid(in->profile, config->sample_rate)) {
proxy_config.rate = config->sample_rate;
} else {
proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(in->profile);
ret = -EINVAL;
}
+
device_unlock(in->adev);
/* Format */