I've been learning how to use PortAudio and have gotten it working pretty well. However, now that I have sounds playing, I'm noticing latency issues. I click a test button, and there is a slight but noticeable delay before the click sound plays.
From debugging, I can see that PortAudio is using DirectSound as the underlying API for playing the audio samples I feed it. And, according to PortAudio, the lowest latency I can get from DirectSound is 120ms. I've tried forcing PortAudio to use a lower latency (i.e. 10ms), but it seems to be hit or miss as to whether it works or not.
But then there are the hoards of people that use other made-for-games audio libraries like Fmod, which reliably do what you would expect and play a sound right when you tell it to without any delay. How is this being accomplished? Does Fmod not use DirectSound? Or is there some other way to get better latency that Fmod is using?
The problem with DirectSound and the WaveAudio APIs on windows is that they end up doing a lot of additional buffering and processing on the audio before sending it to the hardware, all of the buffering and processing (windows mixer, sample rate conversion) add latency. The only way to reduce that latency is to bypass the windows mixer and talk directly with the hardware driver. On windows, WASAPI and ASIO are the only choices that I'm aware of, though ASIO drivers are probably only on PCs with fancy audio devices.
I can't speak for FMOD, but my sound library (still under development) uses the WASAPI on windows for low-latency I/O. I haven't tested the latency when playing a file (which depends on a lot of other things), but I can pass through device input channels to output channels to test the latency which is around 20-30ms for a round trip (half that for playback).
WASAPI is better than anything else native on windows, but still isn't that great in my opinion. There's too much reliance on legacy structures (WAVEFORMATEX...) and the C++ interface is pretty barren and hard to work with. The need to choose between a 'shared' and 'exclusive' driver mode is ridiculous. The API solutions on Mac OS X and the ASIO driver spec are far nicer to work with. The other issue I have with WASAPI is that it doesn't allow access to all of the I/O channels on multichannel devices in shared mode.