[alsa-devel] Buffer size for ALSA USB PCM audio

Alan Stern stern at rowland.harvard.edu
Mon Jul 29 17:00:56 CEST 2013

On Mon, 29 Jul 2013, Takashi Iwai wrote:

> > The existing code has a problem: Under some conditions the URB queue
> > will be too short.  EHCI requires at least 10 microframes on the queue
> > at all times (even when an URB is completing and is therefore no longer
> > on the queue) to avoid underruns.  Well, 9 microframes is probably good
> > enough, but I'll use 10 to be safe.  A typical arrangement of 2 URBs
> > each with 8 packets each (at 1 packet/uframe) violates this constraint,
> > and I have seen underruns in practice.
> > 
> > The patch below fixes this problem and drastically simplifies the 
> > calculation.  How does it look?
> Looks good through a quick glance.  But I'd rather like to let review
> Clemens and Daniel as I already forgot the old voodoo logic of the
> current driver code :)


To recap, the bug I want to fix is that snd-usb-audio does not always
keep the USB hardware queue sufficiently full.  (There is at least one
other minor bug -- the driver uses MAX_PACKS instead of MAX_PACKS_HS
for high-speed devices.)

Clemens remarked some time ago that keeping the queue full would be
trivial, if only he knew how full it needed to be.  The answer to that
is given above.  I have been trying to make the appropriate changes,
but I'm not finding it "trivial".  :-(  Partly because I don't fully
understand all the constraints that are already present, but also
because it isn't a straightforward calculation.

For a recording endpoint, it truly is simple because then the number of 
packets per URB never changes (as far as I can tell).

For a playback endpoint, the number of packets gets reduced when 
necessary, to insure that none of the packets in the URB starts after 
the end of the current ALSA period.  Since a period is defined in terms 
of the number of samples (ALSA frames) rather than an absolute time, 
the end of the period depends on the size of the packets.  And this 
size can vary if the output endpoint has a feedback endpoint.

The current driver seems to assume that endpoints with an _implicit_
feedback endpoint won't have variable-length packets.  I don't
understand why not; doesn't queue_pending_output_urbs() make the packet
sizes match the sizes from the corresponding feedback endpoint?

I'd appreciate any advice you can offer.

Alan Stern

More information about the Alsa-devel mailing list