Direwolf does not send a continuous stream to the audio device.
It merely sends samples when it has a transmission to accomplish.
This seems to work okay on hardware devices, but is causing an
issue when working against a virtual device like plug or dmix
because the vitual device seems to get into a weird state while
direwolf is not sending samples. This causes it to error out
with -EBADFD on every transmission after the first.
Direwolf tries to recover from this error by running
snd_pcm_recover() on the output device. Inspecting the code of
this function revealed that it was a noop on any errors other
than -EPIPE or -ESTRPIPE, so it had no hope of fixing any issues
other than a buffer underrun or a suspended device.
This patch breaks things out so that we only run snd_pcm_recover()
on -EPIPE or -ESTRPIPE, and for any other error we go ahead and
just try to prepare the device again. This appears to work to
make transmissions subsequent to the first work correctly on
virtual devices. We handle -EBADFD differently merely so that
we don't print the error message for a quasi-expected condition.
This problem could also possibly be solved by unprotecting the
snd_pcm_prepare() on line 1174 of audio.c and just preparing the
device whether it apparently needs it or not, but I'm wary of the
unintended consequences of doing so in cases where the code is
currently working. Much more testing would be necessary for that
solution. This solution should only touch cases that are not working
currently regardless.