What are the restrictions on an ALSA PCM callback?
Asked Answered
C

1

6

I am writing a program under Linux that utilizes both playback and record using ALSA (connected to a custom device). I would like to use the asynchronous callback architecture for both reading and writing data.

However, I have been unable to get any information with respect to the limitations of what I am allowed to do inside the callback. Specifically, do I have to be aynchronous-safe? If so, this seems to severely restrict what can be done, since among other things, I should not reference any global variables, making it rather hard to, for example, read from a buffer that is filled by the main thread of execution or write to a buffer which is subsequently saved to file outside the callback.

Is there any C concurrency constructs that I can use in the ALSA callbacks to coordinate use of globals with the main thread? For example, can I use POSIX semaphores? Do I have any guarantee that the ALSA callback is atomic with respect to the main thread (I know it's not atomic to other ALSA callbacks)?

Many thanks for any insight that people can bring to bear upon this.

Calix answered 28/2, 2012 at 22:41 Comment(4)
Just to let you know, here's a link that describes why using these APIs might not be a good idea. 0pointer.de/blog/projects/guide-to-sound-apis.htmlCrosshatch
Thanks! Very informative. Sadly, it's for a third-party device, so I'm stuck with ALSA.Calix
But are you stuck with the asynchronous APIs?Crosshatch
No, but I was having trouble with file I/O blocking for too long in the main loop, causing a buffer underrun, so I figured I'd get around it using asynch callbacks while the main loop stalls on the fflush. As I just discovered, the fflush on a file over NFS causes even the ALSA callback to be delayed by 200ms, so aynch may not save me after all...Calix
P
4

I don't know whether or not this answer will be considered overly negative towards ALSA by people, but I'll give it anyway.

I've tried, desperately, to use ALSA in a couple of asynchronous applications. It was so buggy, poorly documented and hard to use that after days of trying very hard to make the thing work I ultimately gave up.

I ended up using the ALSA OSS emulation layer and simply opening a fd for the sound device and using libevent as a way of doing asynchronous callbacks. This solution worked perfectly for me and I was extremely happy with the results -- I've used it for a while now.

In retrospect, ALSA is amazingly overcomplicated, overdesigned, buggy, badly documented, incompatible with I/O multiplexing techniques that the designers didn't think of in advance, etc. -- I have trouble understanding why it ended up becoming the standard in Linux systems, when much simpler and better designs are available on other Unix operating systems.

Photoemission answered 28/2, 2012 at 23:54 Comment(4)
Thanks for this answer. Unfortunately, a non-ALSA solution is not a choice (I'm using ALSA as an interface to multi-channel device containing a DAC/ADC with an ALSA device driver).Calix
Just because you have to use an ALSA driver does not mean you have to use the ALSA API -- you can use the OSS compatibility layer as your API instead of using the ALSA API. That's what I do.Photoemission
Oh! I didn't realize that. I'll look it up right now. Thanks.Calix
On some linux platforms, btw, this may require loading the ALSA OSS compatibility module into your kernel, but it is generally available by default.Photoemission

© 2022 - 2024 — McMap. All rights reserved.