From b9d6a1cecfa6aec65133471e007beed87db7fa3d Mon Sep 17 00:00:00 2001 From: jakemsr Date: Wed, 21 Jul 2010 05:04:57 +0000 Subject: [PATCH] some bits for USB 2.0 playback support. I'm not 100% sure about scaling the frame rate to the polling interval, but it works on the E-MU 0202 and it generally makes a lot of sense, especially considering that this often brings the frames rate back to 1 kHz, which is the frame rate of USB 1.x, which was the most current USB spec when USB audio 1.0 spec was written. --- sys/dev/usb/uaudio.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index fac6cc84903..8634aa92da3 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uaudio.c,v 1.79 2010/07/21 03:06:35 jakemsr Exp $ */ +/* $OpenBSD: uaudio.c,v 1.80 2010/07/21 05:04:57 jakemsr Exp $ */ /* $NetBSD: uaudio.c,v 1.90 2004/10/29 17:12:53 kent Exp $ */ /* @@ -52,6 +52,8 @@ #include #include +#include + #include #include #include @@ -61,6 +63,7 @@ #include #include #include +#include #include @@ -126,13 +129,14 @@ struct chan { u_int sample_rate; u_int bytes_per_frame; u_int max_bytes_per_frame; - u_int fraction; /* fraction/1000 is the extra samples/frame */ + u_int fraction; /* fraction/usb_fps is the extra samples/frame */ u_int residue; /* accumulates the fractional samples */ u_int nframes; /* # of frames per transfer */ - u_int usb_fps; + u_int usb_fps; u_int maxpktsize; u_int use_maxpkt; /* whether to always use maxpktsize */ u_int reqms; /* usb request data duration, in ms */ + u_int hi_speed; u_char *start; /* upper layer buffer start */ u_char *end; /* upper layer buffer end */ @@ -3007,7 +3011,7 @@ uaudio_chan_init(struct chan *ch, int mode, int altidx, const struct audio_params *param) { struct as_info *ai = &ch->sc->sc_alts[altidx]; - int samples_per_frame; + int samples_per_frame, ival; ch->use_maxpkt = 0; if (ai->attributes & UA_SED_MAXPACKETSONLY) { @@ -3026,6 +3030,19 @@ uaudio_chan_init(struct chan *ch, int mode, int altidx, ch->sample_rate = param->sample_rate; ch->sample_size = param->factor * param->channels * param->bps; ch->usb_fps = USB_FRAMES_PER_SECOND; + ch->hi_speed = ch->sc->sc_udev->speed == USB_SPEED_HIGH; + if (ch->hi_speed) { + ch->usb_fps *= 8; + /* + * Polling interval is considered a frame, as opposed to + * micro-frame being a frame. + */ + ival = ch->sc->sc_alts[altidx].edesc->bInterval; + if (ival > 0 && ival <= 4) + ch->usb_fps >>= (ival - 1); + DPRINTF(("%s: detected USB high-speed with ival %d\n", + __func__, ival)); + } /* * Use UAUDIO_MIN_FRAMES here, so uaudio_round_blocksize() can @@ -3059,6 +3076,8 @@ uaudio_chan_init(struct chan *ch, int mode, int altidx, ch->max_bytes_per_frame = ch->maxpktsize; ch->residue = 0; + DPRINTF(("%s: residual sample fraction: %d/%d\n", __func__, + ch->fraction, ch->usb_fps)); } void -- 2.20.1