[alsa-devel] Implementing full-duplex realtime sound processor
Hi there,
I'm trying to implement a full-duplex realtime sound processing app. I.e., it should capture a stream from a soundcard, do some processing on it and play it with minimal latency.
I don't want to use JACK or any other higher-level API, so I'm looking for the best way to do it directly with ALSA. So far I've discovered three approaches:
a) Just use blocking read/write functions. This approach seems flawed to me, since a separate thread is required for writing. Synchronizing between threds also introduces additional latency.
b) Use the alsalib's asynchronous functionality. At first sight it sounds attractively, but googling for it gets not so happy results. For example, the alsa.opensrc.org wiki claims this functionality is unstable, especially in combination with PulseAudio. I don't know if it's true or not, but it discourages me even from trying it.
c) Use synchronous I/O multiplexing (i.e poll syscall) together with non-blocking mode (much like doing I/O on network sockets). It becomes possible with the snd_pcm_poll_descriptors* family of functions.
So I decided to try the third way first and wrote a simple test program. I'm using Ubuntu and therefore have PulseAudio sound system. So my program worked successfully through PulseAudio (i. e. with 'default' pcm). But when I tried to run it directly on hw:0,0, it hung in the poll() system call, waiting infinitely for an event on a capturing PCM, as if there was no data available for capturing.
I started to look through ALSA API's functions and found occasionally snd_pcm_start. I've never seen it in any tutorial, but I decided to try calling it just after snd_pcm_prepare() for my capturing pcm handle and it did the trick. But if I call this function on a playback pcm handle, it fails with 'Broken pipe' error.
To sum it up, I have the following questions: - What does actually snd_pcm_start() do? - Why does it fail on a playback device and do the job on a capture device? - Why does my program work without it when I'm using PulseAudio? - Am I generally on the right way or should I use other approach?
Thanks, Gregory Bonik.
On 22 August 2010 17:40, Gregory Bonik gregory@bonik.org wrote:
Hi there,
I'm trying to implement a full-duplex realtime sound processing app. I.e., it should capture a stream from a soundcard, do some processing on it and play it with minimal latency.
I don't want to use JACK or any other higher-level API, so I'm looking for the best way to do it directly with ALSA. So far I've discovered three approaches:
Why don't you want to use JACK. It is a perfect fit for what you are trying to do, and it solves a LOT of problems that you don't yet know you will run into.
On 23/08/2010 10:50 +0100, James Courtier-Dutton wrote:
Why don't you want to use JACK. It is a perfect fit for what you are trying to do, and it solves a LOT of problems that you don't yet know you will run into.
Just because I don't want to force the users to use JACK, since it's not so standard. I plan to add support for it later, but I want my program still be usable without it. What are the problems you are talking about?
participants (2)
-
Gregory Bonik
-
James Courtier-Dutton