[alsa-devel] [RFC] ALSA vs. dedicated char device for a USB Audio Class gadget driver
laurent.pinchart at skynet.be
Thu May 14 15:45:01 CEST 2009
Linux provides a USB Audio Class (UAC) driver on the USB host side, but a UAC
gadget driver on the USB device side is currently missing.
Considering plugging in this hole, I'm looking at userspace <-> kernelspace
In a nutshell (let's consider recording, where the device appears to the host
as a USB microphone), the kernel driver needs to be fed with audio data from a
userspace application and stream those data on USB. Audio data can come from a
real microphone (through an ALSA driver), a file, a network socket, ... the
driver will not care.
I need an API to transfer audio data from userspace to kernelspace. I
initially thought about ALSA, but it turns out some assumptions made by ALSA
are not fulfilled by my system. One of the most serious problems is that the
UAC gadget driver doesn't have any audio clock. The only hardware clock
available is the USB device controller interrupts generated at the USB
transfer rate, and those are much faster than the audio sample rate. This will
cause buffer underruns that I need to handle.
I can thing of 3 solutions to solve this issue, and I'd like your opinion on
1. Get the userspace application to provide a clock to the driver. This could
be done by writing to a /proc file, a special char device, or even by adding
an ioctl to ALSA. Every time the driver receives a clock tick it would
transfer one period of data.
2. Find out how much data is available in the ALSA ring buffer. I could then
throttle USB interrupts when no data is available in the buffer and try again
later. ALSA maintains a read and a write pointer (hw_ptr and appl_ptr) that
can be accessed through the snd_pcm_*_avail() functions. However, I'm not sure
how to handle proper locking, and I don't understand how runtime->boundary
interacts with those functions. I've also heard that there's a free-running
mode that will make those functions return bogus values. I'd appreciate help
3. Use another API (dedicated character device, socket, ...) to transfer audio
data from userspace to kernelspace. ALSA is way too big for my requirements (2
layers of abstraction, architectured around assumptions that make sense for
real sound cards but not for my hardware, ...). On the other hand, it would be
handy to use existing ALSA applications to driver the device.
I'd appreciate comments regarding the API choice. How do you all expect to
push data from a userspace application to a UAC driver on the device side ? If
ALSA is *the* way, is one of the above solutions practical or is there a
better way ?
More information about the Alsa-devel