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