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

Takashi Iwai tiwai at suse.de
Thu Jul 25 10:24:57 CEST 2013


At Wed, 24 Jul 2013 11:43:58 -0400 (EDT),
Alan Stern wrote:
> 
> On Wed, 24 Jul 2013, Takashi Iwai wrote:
> 
> > > I don't understand.  Consider a simple playback example.  Suppose the
> > > user wants to keep the latency low, so he requests 2 periods per
> > > buffer.  snd-usb-audio ignores this value and decides to use 10 URBs,
> > > which is equivalent to setting the buffer size to 10 periods.
> > 
> > You don't have to fill all 10 URBs to start the stream...
> 
> Maybe you don't have to, but it looks the driver does just that.  From
> snd_usb_endpoint_start():
> 
> 	if (snd_usb_endpoint_implicit_feedback_sink(ep)) {
> 		for (i = 0; i < ep->nurbs; i++) {
> 			struct snd_urb_ctx *ctx = ep->urb + i;
> 			list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs);
> 		}
> 
> 		return 0;
> 	}
> 
> 	for (i = 0; i < ep->nurbs; i++) {
> 		struct urb *urb = ep->urb[i].urb;
> 
> 		if (snd_BUG_ON(!urb))
> 			goto __error;
> 
> 		if (usb_pipeout(ep->pipe)) {
> 			prepare_outbound_urb(ep, urb->context);
> 		} else {
> 			prepare_inbound_urb(ep, urb->context);
> 		}
> 
> 		err = usb_submit_urb(urb, GFP_ATOMIC);
> 		if (err < 0) {
> 			snd_printk(KERN_ERR "cannot submit urb %d, error %d: %s\n",
> 				   i, err, usb_error_string(err));
> 			goto __error;
> 		}
> 		set_bit(i, &ep->active_mask);
> 	}
> 
> In this case, I'm particularly considering what happens when 
> snd_usb_endpoint_implicit_feedback_sink(ep) is false.
> 
> Besides, what's the reason for allocating 10 URBs if you're not going 
> to submit more than 2 of them at a time?

I don't know how you deduced 10 urbs in your example, but in general,
ep->nurbs is calculated so that the driver can hold at least two
ep->periods (i.e. double buffer).  The USB audio driver has
essentially two buffers: an internal hardware buffer via URBs and an
intermediate buffer via vmalloc.  The latter is exposed to user-space
and its content is copied to the URBs appropriately via complete
callbacks.

Due to this design, we just need two periods for URB buffers,
ideally, no matter how many periods are used in the latter buffer
specified by user.  That's why no buffer_size is needed in ep->nurbs 
estimation.  The actual calculation is, however, a bit more
complicated to achieve enough fine-grained updates but yet not too big
buffer size.  I guess this can be simplified / improved.


Takashi


More information about the Alsa-devel mailing list