diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-07-21 05:04:58 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-07-21 05:04:58 +0000 |
commit | 6cf22e6af5a5e40a6e0aaa4153306d428a2ba148 (patch) | |
tree | 2910ea1a1b5f4a59d20fc07e604633dfa6afb196 /sys | |
parent | 122076cec066cb94e8721f111cc9549eb74792d3 (diff) |
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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/uaudio.c | 27 |
1 files 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 <sys/device.h> #include <sys/poll.h> +#include <machine/bus.h> + #include <sys/audioio.h> #include <dev/audio_if.h> #include <dev/mulaw.h> @@ -61,6 +63,7 @@ #include <dev/usb/usbdevs.h> #include <dev/usb/usbdi.h> #include <dev/usb/usbdi_util.h> +#include <dev/usb/usbdivar.h> #include <dev/usb/uaudioreg.h> @@ -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 |