1

I have a device that is continuously putting out PCM data. Under certain circumstances I want to record this output. To this end I have a process that waits for the signal to record and when it gets it, it starts a thread (via pthread_create). This thread opens the PCM device and starts recording using snd_async_add_pcm_handler. This handler fn uses pcm_readi to get any available info in the PCM stream and write it to disk.

All well and good - except

Once this starts running my calling process stops getting any cycles. It should be continuing to listen for the next event that would signal to stop recording. Watching the execution I see it slow and then halt once the PCM recording starts. If I don't start the recording the app runs normally and continues to respond.

So it seems like I'm left with two avenues:

  1. find gaps in the recording process and usleep (or similar) to give the calling app time to respond
  2. attempt to exit the recording using other means

I've failed to make any headway using #1 so I'm working on #2. It's known that the audio sample will start with low amplitude, go high for a second or two and then go low again. I'm using a rolling average to trap this low-high-low and am attempting to close the async IO.

Where it stands: Once the IO is supposed to be stopped I've tried calling snd_async_del_handler but this crashes the app with a simple 'IO possible' message. I've also tried calling snd_pcm_drop but this doesn't close the async io so it crashes the next time it tries to read. Combining the two in either order gives similar responses.

What step(s) have I missed?

ethrbunny
  • 10,379
  • 9
  • 69
  • 131

1 Answers1

3

The snd_async_* functions are strongly deprecated, because they don't work with all kinds of devices, are hard to use, and don't have any advantages in practice.

Please note that the ALSA API is not thread safe, i.e., calls for one PCM device must all be from one thread, or synchronized.

What you should do is to have an event loop (using poll) in your thread that handles both the PCM device and the exit message from the main thread. For this, the PCM device should be run in non-blocking mode (using the snd_pcm_poll_descriptors* functions). To send a message to the thread, use any mechanism with a pollable file handle, such as a pipe or eventfd.

CL.
  • 173,858
  • 17
  • 217
  • 259
  • I've tried some other ALSA fns and it seems like the ASYNC_* are the only ones that give me reliable data. I didn't realize they weren't thread-safe though. Ick. I'll probably have to combine the ALSA code with my signalling code esp since both are reading from the same device. Argh. – ethrbunny Feb 14 '13 at 21:06