2010-03-05 01:46:13 +07:00
|
|
|
#ifndef __USBAUDIO_ENDPOINT_H
|
|
|
|
#define __USBAUDIO_ENDPOINT_H
|
|
|
|
|
2012-04-12 18:51:11 +07:00
|
|
|
#define SND_USB_ENDPOINT_TYPE_DATA 0
|
|
|
|
#define SND_USB_ENDPOINT_TYPE_SYNC 1
|
|
|
|
|
|
|
|
struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
|
|
|
|
struct usb_host_interface *alts,
|
|
|
|
int ep_num, int direction, int type);
|
|
|
|
|
|
|
|
int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
|
2012-09-18 23:49:47 +07:00
|
|
|
snd_pcm_format_t pcm_format,
|
|
|
|
unsigned int channels,
|
|
|
|
unsigned int period_bytes,
|
ALSA: improve buffer size computations for USB PCM audio
This patch changes the way URBs are allocated and their sizes are
determined for PCM playback in the snd-usb-audio driver. Currently
the driver allocates too few URBs for endpoints that don't use
implicit sync, making underruns more likely to occur. This may be a
holdover from before I/O delays could be measured accurately; in any
case, it is no longer necessary.
The patch allocates as many URBs as possible, subject to four
limitations:
The total number of URBs for the endpoint is not allowed to
exceed MAX_URBS (which the patch increases from 8 to 12).
The total number of packets per URB is not allowed to exceed
MAX_PACKS (or MAX_PACKS_HS for high-speed devices), which is
decreased from 20 to 6.
The total duration of queued data is not allowed to exceed
MAX_QUEUE, which is decreased from 24 ms to 18 ms.
The total number of ALSA frames in the output queue is not
allowed to exceed the ALSA buffer size.
The last requirement is the hardest to implement. Currently the
number of URBs needed to fill a buffer cannot be determined in
advance, because a buffer contains a fixed number of frames whereas
the number of frames in an URB varies to match shifts in the device's
clock rate. To solve this problem, the patch changes the logic for
deciding how many packets an URB should contain. Rather than using as
many as possible without exceeding an ALSA period boundary, now the
driver uses only as many packets as needed to transfer a predetermined
number of frames. As a result, unless the device's clock has an
exceedingly variable rate, the number of URBs making up each period
(and hence each buffer) will remain constant.
The overall effect of the patch is that playback works better in
low-latency settings. The user can still specify values for
frames/period and periods/buffer that exceed the capabilities of the
hardware, of course. But for values that are within those
capabilities, the performance will be improved. For example, testing
shows that a high-speed device can handle 32 frames/period and 3
periods/buffer at 48 KHz, whereas the current driver starts to get
glitchy at 64 frames/period and 2 periods/buffer.
A side effect of these changes is that the "nrpacks" module parameter
is no longer used. The patch removes it.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Clemens Ladisch <clemens@ladisch.de>
Tested-by: Daniel Mack <zonque@gmail.com>
Tested-by: Eldad Zack <eldad@fogrefinery.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2013-09-25 02:51:58 +07:00
|
|
|
unsigned int period_frames,
|
|
|
|
unsigned int buffer_periods,
|
2012-09-18 23:49:47 +07:00
|
|
|
unsigned int rate,
|
2012-04-12 18:51:11 +07:00
|
|
|
struct audioformat *fmt,
|
|
|
|
struct snd_usb_endpoint *sync_ep);
|
|
|
|
|
2012-11-21 00:32:06 +07:00
|
|
|
int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep);
|
2012-11-21 14:30:48 +07:00
|
|
|
void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep);
|
2012-11-08 14:52:45 +07:00
|
|
|
void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);
|
2012-04-12 18:51:11 +07:00
|
|
|
int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
|
2013-10-07 03:31:10 +07:00
|
|
|
void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
|
2012-04-12 18:51:11 +07:00
|
|
|
void snd_usb_endpoint_free(struct list_head *head);
|
|
|
|
|
2013-04-04 04:18:52 +07:00
|
|
|
int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep);
|
2012-08-30 23:52:30 +07:00
|
|
|
int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep);
|
2012-04-12 18:51:11 +07:00
|
|
|
|
|
|
|
void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
|
|
|
|
struct snd_usb_endpoint *sender,
|
|
|
|
const struct urb *urb);
|
|
|
|
|
2010-03-05 01:46:13 +07:00
|
|
|
#endif /* __USBAUDIO_ENDPOINT_H */
|