0

I am trying to record what it is just playing out to the speaker using following ALSA APIs:

snd_pcm_mmap_writei()
snd_pcm_mmap_readi()

Both functions are called one to next in the same thread. The writei() function returns quickly (I believe it returns once playback buffer is available), while the readi() returns until designated samples are captured. But the samples captured are not what is has just played out. I am guessing that ALSA is not in a duplex mode, i.e., it has to finish playback first, then start to record, which records nothing meaningful but just clicks. The speaker still plays out the sound correctly.

All HW/SW parameters are setup correctly. If I do audio capture only, I will get a good sound wave. The PCM handles are opened with normal mode (not non-block, not async).

Anybody has suggestions how to make this work?

Anthon
  • 69,918
  • 32
  • 186
  • 246
  • You have to configure your sound hardware to route the sound from the playback device back to the capture device. Did you do this? – CL. Apr 13 '13 at 08:35
  • My purpose is to test if my speaker is working properly, so I have to capture the sound out of the speak. Thus the loopback from playback to capture is not setup. – Tianhua Chu Apr 15 '13 at 14:04
  • Why are you doing this in the same program? Can't you just run `aplay` and `arecord`? – CL. Apr 15 '13 at 15:52
  • Yes aplay and arecord definitely work, but I need to let my application use buffers to detect the speaker failure on the run. And I found out these two ALSA APIs need to be put into different threads, in order to sync them, which is still difficult to capture the sound from the exact moment it is played out. – Tianhua Chu Apr 15 '13 at 22:35

1 Answers1

0

You do not need to use the mmap functions; the normal writei/readi calls suffice.

To handle two PCM streams at the same time, run them in separate threads, or use non-blocking mode so that the same event loop can handle both devices.

You need to fill the playback buffer before the data is played, and capture data can be read only after the capture buffer has been filled, so the overall latency is the playback buffer size plus the capture period size plus any hardware delays and sound propagation delays.

CL.
  • 173,858
  • 17
  • 217
  • 259