Jaroslav Kysela wrote:
> On Tue, 9 Mar 2004, Takashi Iwai wrote:
>
> > BTW, the USB audio is another headache. the current ALSA PCM model isn't
> > perfectly suitable for the devices like USB audio.
>
> Unfortunately I don't see a better model.
Conceptually, USB devices have variable-sized periods. The question
is whether we actually want to allow this in the API. Probably not.
I have thought about forcing the period size to one ALSA frame (with
period_elapsed() calls at USB frame boundaries, like it's now). In
theory, applications should be able to cope with this.
> I don't know much about USB 2.0,
Not too much differences for the driver. The main difference is that
there are now 8000 microframes per second. I have written a patch
(see below) and am about to test it.
> but I guess that 1.x compatibility issues brings another overhead
> to this extension which makes it also unuseable when 1.x devices
> are connected to same USB port.
There are some nasty contortions when a 1.x device is connected
through a 2.0 hub, but otherwise there is no overhead for 1.x devices
because logically (and electrically AFAIK) either the 2.0 or the 1.x
host controller device is connected to a specific port.
Regards,
Clemens
--
Index: alsa-kernel/usb/usbaudio.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.c,v
retrieving revision 1.87
diff -u -r1.87 usbaudio.c
--- alsa-kernel/usb/usbaudio.c 8 Mar 2004 09:29:51 -0000 1.87
+++ alsa-kernel/usb/usbaudio.c 8 Mar 2004 09:48:09 -0000
@@ -104,6 +104,7 @@
*/
#define MAX_PACKS 10
+#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
#define MAX_URBS 5 /* max. 20ms long packets */
#define SYNC_URBS 2 /* always two urbs for sync */
#define MIN_PACKS_URB 1 /* minimum 1 packet per urb */
@@ -165,6 +166,8 @@
unsigned int freqm; /* momentary sampling rate in USB format, i.e.
fs/1000 in Q10.14 */
unsigned int freqmax; /* maximum sampling rate, used for buffer management
*/
unsigned int phase; /* phase accumulator */
+ unsigned int phase_shift; /* fractional bits of phase */
+ unsigned int phase_mask; /* (1 << phase_shift) - 1 */
unsigned int maxpacksize; /* max packet size in bytes */
unsigned int maxframesize; /* max packet size in frames */
unsigned int curpacksize; /* current packet size in bytes (for capture)
*/
@@ -250,7 +253,6 @@
cp[1] = subs->freqn >> 8;
cp[2] = subs->freqn >> 16;
}
- urb->interval = 1;
return 0;
}
@@ -301,7 +303,6 @@
spin_unlock_irqrestore(&subs->lock, flags);
urb->transfer_buffer = ctx->buf;
urb->transfer_buffer_length = offs;
- urb->interval = 1;
#if 0 // for check
if (! urb->bandwidth) {
int bustime;
@@ -390,7 +391,6 @@
urb->iso_frame_desc[i].length = 3;
urb->iso_frame_desc[i].offset = offs;
}
- urb->interval = 1;
return 0;
}
@@ -464,8 +464,8 @@
if (subs->fill_max)
counts = subs->maxframesize; /* fixed */
else {
- subs->phase = (subs->phase & 0x3fff) + subs->freqm;
- counts = subs->phase >> 14;
+ subs->phase = (subs->phase & subs->phase_mask) + subs->freqm;
+ counts = subs->phase >> subs->phase_shift;
if (counts > subs->maxframesize)
counts = subs->maxframesize;
}
@@ -515,7 +515,6 @@
spin_unlock_irqrestore(&subs->lock, flags);
urb->transfer_buffer_length = offs * stride;
ctx->transfer = offs;
- urb->interval = 1;
return 0;
}
@@ -822,15 +821,22 @@
{
unsigned int maxsize, n, i;
int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
- unsigned int npacks[MAX_URBS], total_packs;
+ unsigned int npacks[MAX_URBS], urb_packs, total_packs;
/* calculate the frequency in 10.14 format */
subs->freqn = subs->freqm = get_usb_rate(rate);
subs->freqmax = subs->freqn + (subs->freqn >> 2); /* max. allowed frequency */
subs->phase = 0;
+ if (subs->dev->speed == USB_SPEED_HIGH) {
+ subs->phase_shift = 11;
+ subs->phase_mask = 0x07ff;
+ } else {
+ subs->phase_shift = 14;
+ subs->phase_mask = 0x3fff;
+ }
/* calculate the max. size of packet */
- maxsize = ((subs->freqmax + 0x3fff) * (frame_bits >> 3)) >> 14;
+ maxsize = ((subs->freqmax + subs->phase_mask) * (frame_bits >> 3)) >>
subs->phase_shift;
if (subs->maxpacksize && maxsize > subs->maxpacksize) {
//snd_printd(KERN_DEBUG "maxsize %d is greater than defined size %d\n",
// maxsize, subs->maxpacksize);
@@ -842,9 +848,14 @@
else
subs->curpacksize = maxsize;
+ if (subs->dev->speed == USB_SPEED_HIGH)
+ urb_packs = nrpacks * 8;
+ else
+ urb_packs = nrpacks;
+
/* allocate a temporary buffer for playback */
if (is_playback) {
- subs->tmpbuf = kmalloc(maxsize * nrpacks, GFP_KERNEL);
+ subs->tmpbuf = kmalloc(maxsize * urb_packs, GFP_KERNEL);
if (! subs->tmpbuf) {
snd_printk(KERN_ERR "cannot malloc tmpbuf\n");
return -ENOMEM;
@@ -855,16 +866,16 @@
total_packs = (period_bytes + maxsize - 1) / maxsize;
if (total_packs < 2 * MIN_PACKS_URB)
total_packs = 2 * MIN_PACKS_URB;
- subs->nurbs = (total_packs + nrpacks - 1) / nrpacks;
+ subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
if (subs->nurbs > MAX_URBS) {
/* too much... */
subs->nurbs = MAX_URBS;
- total_packs = MAX_URBS * nrpacks;
+ total_packs = MAX_URBS * urb_packs;
}
n = total_packs;
for (i = 0; i < subs->nurbs; i++) {
- npacks[i] = n > nrpacks ? nrpacks : n;
- n -= nrpacks;
+ npacks[i] = n > urb_packs ? urb_packs : n;
+ n -= urb_packs;
}
if (subs->nurbs <= 1) {
/* too little - we need at least two packets
@@ -913,6 +924,7 @@
u->urb->pipe = subs->datapipe;
u->urb->transfer_flags = URB_ISO_ASAP;
u->urb->number_of_packets = u->packets;
+ u->urb->interval = 1;
u->urb->context = u;
u->urb->complete = snd_usb_complete_callback(snd_complete_urb);
}
@@ -935,6 +947,7 @@
u->urb->pipe = subs->syncpipe;
u->urb->transfer_flags = URB_ISO_ASAP;
u->urb->number_of_packets = u->packets;
+ u->urb->interval = subs->dev->speed == USB_SPEED_HIGH ? 8 : 1;
u->urb->context = u;
u->urb->complete =
snd_usb_complete_callback(snd_complete_sync_urb);
}
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel