RustAudio / rust-portaudio

PortAudio bindings and wrappers for Rust.
MIT License
375 stars 89 forks source link

Issues with running Linux ALSA stream #72

Closed mitchmindtree closed 9 years ago

mitchmindtree commented 9 years ago

@niclashoyer has been running into issues with rust-portaudio on Linux. The blocking stream immediately underruns and breaks from the loop, while the non-blocking stream shows some warning messages however seems to run fine. Perhaps we are missing some platform specific ALSA implementation? @jeremyletang any ideas? Do you test on linux?

blocking.rs output

PortAudio version : 1899
PortAudio version text : PortAudio V19-devel (built Aug 18 2014 05:50:44)
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:947:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:947:(find_matching_chmap) Found no matching channel map
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
Successfully initialized PortAudio
PortAudio host count : 2
PortAudio default host : 0
PortAudio host name : ALSA
PortAudio type id : -9979
Default input device info :
    version : 2
    name : default
    max input channels : 32
    max output channels : 32
    default sample rate : 44100
Default output device name : default
Successfully opened the stream.
Successfully started the stream.
Read stream available with 96 frames.
Write stream available with 768 frames.
Read stream available with 120 frames.
ALSA lib pcm.c:7843:(snd_pcm_recover) underrun occurred
Write stream available with 768 frames.
An error occurred while writing to the output stream: The output stream has overflowed
Successfully closed the stream.

Successfully terminated PortAudio.

non_blocking.rs output

PortAudio version : 1899
PortAudio version text : PortAudio V19-devel (built Aug 18 2014 05:50:44)
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:947:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:947:(find_matching_chmap) Found no matching channel map
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
Successfully initialized PortAudio
PortAudio host count : 2
PortAudio default host : 0
PortAudio host name : ALSA
PortAudio type id : -9979
Default input device info :
    version : 2
    name : default
    max input channels : 32
    max output channels : 32
    default sample rate : 44100
Default output device name : default
Successfully opened the stream.
Successfully started the stream.

Original issue was raised here.

mitchmindtree commented 9 years ago

@niclashoyer I have a suspicion that the non-blocking stream also underruns at first, however in the non-blocking example portaudio represents this as a StreamCallbackFlag while the blocking example it returns an error value (causing our loop to break). If you print the maybe_flag arg in the non_blocking.rs example's callback, you should see it indicating the underrun at first before becoming normal (this is what happens for me).

To fix this I might see if we can also map the overflow/underflow return value to an Option (like in the non-blocking example), because it's not really an error - it should probably be expected in cpu intensive situations, so it could be nicer for the user to optionally handle it rather than having to match on the Err variant for it.

mitchmindtree commented 9 years ago

Error::OutputUnderflowed error's description mistakenly described out output buffer had overflowed (rather than underflowed), will fix this now.

niclashoyer commented 9 years ago

Unfortunately #73 did not fix it for me, I added logs to this gist. The non blocking example works fine, but the blocking example still just exits immediately. Any hints on how to dig into this? I'd like to help as much as I can :smile:

mitchmindtree commented 9 years ago

Ahhh flip! I think we're close though...

Could you check the blocking.rs rust-portaudio example for exactly what function returns the Err that causes the loop to be broken? I think what you really want to do is catch Error::OutputUnderflowed and Error::InputOverflowed and ignore them and just keep looping - so if you can find which method is the culprit, then I'll know which one to fix (as in make the method return the under/overflowed as flags rather than an error).

Thanks for the help! I'm busy with conrod atm but will be back to help on this tomorrow :+1:

niclashoyer commented 9 years ago

It seems to be stream.write, at least I just catched the OutputUnderflowed error and the blocking example is now working :tada: I pushed my changes to the blocking example to #75, but I really don't know if ignoring the overflow/underflows in this case is the right thing to do. I get 3-4 underflows in the first seconds, but from then on the example runs stable without issues.

Conrod looks really nice. I'd like to check out piston really soon, it looks very interesting.

niclashoyer commented 9 years ago

Unfortunately #77 does not fix the blocking example for me, maybe we should reopen this. I do not get any over- or underruns, but the blocking example just exits with the message An unknown error occurred. Using --verbose there is slightly more information.

Example output:

[...]
Write stream available with 184 frames.
Read stream available with 520 frames.
Process didn't exit successfully: `target/debug/examples/blocking` (signal: 11)

On about 1 in 5 runs I get a different message, maybe this is helpful:

[...]
Write stream available with 137 frames.
Read stream available with 720 frames.
Assertion 'pa_atomic_load(&(c)->_ref) >= 1' failed at pulse/context.c:389, function pstream_memblock_callback(). Aborting.
Process didn't exit successfully: `target/debug/examples/blocking` (signal: 6)

Full logs in this gist. The non blocking example still runs fine, though. I'm still learning all the low level audio stuff, so I'm glad that I can at least help with testing :smile:

mitchmindtree commented 9 years ago

I'm still learning a lot too! Thanks so much for testing, it's been a huge help :)

Take 3: Hopefully #78 is the right fix!

niclashoyer commented 9 years ago

@mitchmindtree yes the blocking example is now working :+1:

mitchmindtree commented 9 years ago

Woohoo! :tada: