Add support for adjusting the hardware buffering delay for USB audio.
Requested by: Goran Mekic <meka@tilda.center> MFC after: 1 week
This commit is contained in:
parent
a45a1a25b8
commit
4d76235fe3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=307651
@ -95,6 +95,7 @@ __FBSDID("$FreeBSD$");
|
||||
static int uaudio_default_rate = 0; /* use rate list */
|
||||
static int uaudio_default_bits = 32;
|
||||
static int uaudio_default_channels = 0; /* use default */
|
||||
static int uaudio_buffer_ms = 8;
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
static int uaudio_debug = 0;
|
||||
@ -109,9 +110,32 @@ SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_bits, CTLFLAG_RWTUN,
|
||||
&uaudio_default_bits, 0, "uaudio default sample bits");
|
||||
SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_channels, CTLFLAG_RWTUN,
|
||||
&uaudio_default_channels, 0, "uaudio default sample channels");
|
||||
|
||||
static int
|
||||
uaudio_buffer_ms_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int err, val;
|
||||
|
||||
val = uaudio_buffer_ms;
|
||||
err = sysctl_handle_int(oidp, &val, 0, req);
|
||||
|
||||
if (err != 0 || req->newptr == NULL || val == uaudio_buffer_ms)
|
||||
return (err);
|
||||
|
||||
if (val > 8)
|
||||
val = 8;
|
||||
else if (val < 2)
|
||||
val = 2;
|
||||
|
||||
uaudio_buffer_ms = val;
|
||||
|
||||
return (0);
|
||||
}
|
||||
SYSCTL_PROC(_hw_usb_uaudio, OID_AUTO, buffer_ms, CTLTYPE_INT | CTLFLAG_RWTUN,
|
||||
0, sizeof(int), uaudio_buffer_ms_sysctl, "I",
|
||||
"uaudio buffering delay from 2ms to 8ms");
|
||||
#endif
|
||||
|
||||
#define UAUDIO_IRQS (8000 / UAUDIO_NFRAMES) /* interrupts per second */
|
||||
#define UAUDIO_NFRAMES 64 /* must be factor of 8 due HS-USB */
|
||||
#define UAUDIO_NCHANBUFS 2 /* number of outstanding request */
|
||||
#define UAUDIO_RECURSE_LIMIT 255 /* rounds */
|
||||
@ -1278,10 +1302,10 @@ uaudio_configure_msg_sub(struct uaudio_softc *sc,
|
||||
|
||||
if (fps < 8000) {
|
||||
/* FULL speed USB */
|
||||
frames = 8;
|
||||
frames = uaudio_buffer_ms;
|
||||
} else {
|
||||
/* HIGH speed USB */
|
||||
frames = UAUDIO_NFRAMES;
|
||||
frames = uaudio_buffer_ms * 8;
|
||||
}
|
||||
|
||||
fps_shift = usbd_xfer_get_fps_shift(chan->xfer[0]);
|
||||
@ -2158,8 +2182,9 @@ uaudio_chan_play_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
}
|
||||
|
||||
/* start the SYNC transfer one time per second, if any */
|
||||
if (++(ch->intr_counter) >= UAUDIO_IRQS) {
|
||||
ch->intr_counter = 0;
|
||||
ch->intr_counter += ch->intr_frames;
|
||||
if (ch->intr_counter >= ch->frames_per_second) {
|
||||
ch->intr_counter -= ch->frames_per_second;
|
||||
usbd_transfer_start(ch->xfer[UAUDIO_NCHANBUFS]);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user