summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2010-07-21 05:04:58 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2010-07-21 05:04:58 +0000
commit6cf22e6af5a5e40a6e0aaa4153306d428a2ba148 (patch)
tree2910ea1a1b5f4a59d20fc07e604633dfa6afb196 /sys
parent122076cec066cb94e8721f111cc9549eb74792d3 (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.c27
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