szechyjs/dsd — pull request #38 by jpwichern (2014-06-05 17:40:54+00:00)
Title: Portaudio hack

This is the hack I made to add support for portaudio in DSD. It is born from the 'frustration' of having only one audio device connected with the standard Windows audio in/out in Cygwin. With this you can in- and output to any audio device available through portaudio in Windows. On my computer this includes my internal soundcard, all in- and output devices of the Creative X-Fi i have in there and the virtual audio cable driver I have installed. It seems only mono/stereo is available, nothing fancy like 5.1. But we don't need that here anyway.
You need to use device numbers for the commandline invocation, like "dsd.exe -i pa:6 -o pa:14". The device numbers are shown with the pa_devs example application, part of the portaudio source.
The implementation is quite straight forward. Both an input and output PaStream are made (if using portaudio for both in- and output). Requesting data from the input in dsd_symbol is quite similar to requesting data from a unix device. Output is a bit more complicated. To prevent error messages about output buffer underruns, I check if there are 'too many' available stream frames. In that case I stop the output stream and start it again, which creates a number of 'empty' frames equal to the delay time specified when creating the stream. Then output data is again written to the output stream. Why I don't stop the stream immediately after I've written data to it is because the stop function will busy-wait until all stream data is written to the audio device. When the output buffer is (almost) empty that's no big deal. But when it's filled, you get input stream overflows because there isn't enough time for the code in dsd_symbol to read and process the input data.

TODO: add cmake support for the portaudio library. Currently I compile the code with an added '/usr/lib/libportaudio.dll.a' to the LIBS define in CMakeLists.txt.