Open codepainters opened 1 year ago
Just a quick note that I ran in to this issue as-well. I was getting constant ALSA lib pcm.c:8545:(snd_pcm_recover) "overrun" occurred
errors. I changed the code to add the suggested:
PollDescriptorsFlow::XRun => {
if let Err(err) = stream.channel.prepare() {
error_callback(err.into());
}
if let Err(err) = stream.channel.start() {
error_callback(err.into());
}
continue;
}
And it seems to work fine now. I still get the overruns, but it gracefully continues. I am running on a raspberry PI zero w with the respeaker 2mic board attached.
I have moved away from CPAL altogether. My application only needs to work on Linux (Windows was a nice-to-have feature), and I only need a simple record capability (and I also use Respeaker!).
I decided to switch to raw alsa, which solved all my problems. I was initially afraid of the low-level interface, but it turned out surprisingly easy.
I'm working on an application using
cpal
over ALSA to continuously capture audio stream on Raspberry Pi. I use both RPI and PC for testing. Note: I'm using a version from master branch, as I need bothi16
andi32
sample formats, withi32
not being supported in stable version.Unfortunately I'm experiencing odd behavior upon capture overruns (which I trigger setting buffer size too low).
poll()
returnEPOLERR
which is not handled properly.And then I no longer get any more callbacks from
cpal
, but my application is eating up 100% of CPU core, aspoll()
is executed in a tight loop.The problem is here:
https://github.com/RustAudio/cpal/blob/7776c6634a8e21e2a585358545141fe091c38320/src/host/alsa/mod.rs#L746-L753
This match doesn't recognize
POLLIN|POLLERR
and returnsPollDescriptorsFlow::Continue
, causing the worker thread topoll()
again immediately, leading to a tight loop.The problem seems obvious, I'll try to come with a pull request.
ioctl
call fails.In this scenario I no longer get any data callbacks, instead I get error callback periodically (poll timeout).
I believe the problem is here:
https://github.com/RustAudio/cpal/blob/7776c6634a8e21e2a585358545141fe091c38320/src/host/alsa/mod.rs#L604-L609
The call to
prepare()
passes OK, but the stream is stopped - according to ALSA, this call changes the state toSND_PCM_STATE_PREPARED
, there also need to be a call tostart()
to transition toSND_PCM_STATE_RUNNING
and re-enable data flow.I'm a bit confused here about what is the intended
cpal
behavior here:Stream
and create a new one? In such case I believecpal
should do some cleanup (e.g. stop the polling loop).start()
call is missing.ioctl(SNDRV_PCM_IOCTL_READI_FRAMES)
fails withEPIPE
:Here, the error from
process_input()
is properly delivered to my error callback, but then we enter the tight loop scenario, due toPOLLERR
not being recognized.