aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2016-11-12 17:32:22 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2016-11-12 17:32:22 +0000
commitac0e0a1a8979978fe97964fe541abfc44fee3c83 (patch)
tree7c5c925f6b98a1aac92cecce2b32fdec11a45515 /sys/dev
parent8a3ced0f671499a712f0bba23d9ccad87cbaf1f7 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/sound/usb/uaudio.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index ca858ff89b54..298f7f72e114 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -2047,9 +2047,23 @@ uaudio_chan_play_sync_callback(struct usb_xfer *xfer, usb_error_t error)
* Use feedback value as fallback when there is no
* recording channel:
*/
- if (ch->priv_sc->sc_rec_chan.num_alt == 0)
- ch->jitter_curr = temp - sample_rate;
+ if (ch->priv_sc->sc_rec_chan.num_alt == 0) {
+ int32_t jitter_max = howmany(sample_rate, 16000);
+ /*
+ * Range check the jitter values to avoid
+ * bogus sample rate adjustments. The expected
+ * deviation should not be more than 1Hz per
+ * second. The USB v2.0 specification also
+ * mandates this requirement. Refer to chapter
+ * 5.12.4.2 about feedback.
+ */
+ ch->jitter_curr = temp - sample_rate;
+ if (ch->jitter_curr > jitter_max)
+ ch->jitter_curr = jitter_max;
+ else if (ch->jitter_curr < -jitter_max)
+ ch->jitter_curr = -jitter_max;
+ }
ch->feedback_rate = temp;
break;