PortAudio/portaudio

paWinDirectSoundUseLowLevelLatencyParameters & .framesPerBuffer ignored?

benfx123 opened this issue · 3 comments

I am trying to expose all of the available host APIs to a user, so that they can choose paDirectSound, paASIO, paWASAPI... and so on. At the moment, I am developing for Windows 10.

I'm having trouble getting paDirectSound to work. I have created a PaWinDirectSoundStreamInfo and set .flags = paWinDirectSoundUseLowLevelLatencyParameters. However, this does not seem to work unless .framesPerBuffer is set to 2048, which is too large for my requirements.

If I set .framesPerBuffer ro anything other than 2048, the sound is corrupted, and in some cases, I get a paOutputUnderflow error in my callback function.

If I initialise the stream without using a PaWinDirectSoundStreamInfo, everything seems to work fine. But this isn't a solution, because I need minimal latency.

have I misunderstood what setting the paWinDirectSoundUseLowLevelLatencyParameters flag would do?

This doesn't really answer your question, but I would advise against using DirectSound for low latency use cases. In modern Windows (i.e. Vista and later), DirectSound goes through the usual Windows audio pipeline which comes with around 20 ms of inherent latency. On top of that, again on modern Windows DirectSound has a known limitation where input cursor granularities below 31.25 ms simply won't work at all and will make PortAudio hang (#775), which will add even more latency if you use DirectSound for input (recording).

You'll probably want to use WASAPI in Exclusive Mode instead - that one is designed for low latency use cases.

To begin, to use DirectSound with PortAudio there is absolutely no need to use paWinDirectSoundUseLowLevelLatencyParameters unless you know what you are doing.

To address your question: if you use paWinDirectSoundUseLowLevelLatencyParameters you specify the DirectSound buffer size explicitly. As usual, framesPerBuffer is still used to determine the PortAudio callback buffer size, it is not ignored, but it also has no additional effects on the DirectSound buffers, since you specified those explicitly.

You need to explicitly specify the DirectSound buffer size and the framesPerBuffer in a way that will work. Aside from setting the paWinDirectSoundUseLowLevelLatencyParameters flag, you didn't tell us what direct-sound specific parameters you tried, so I can't address the question of why 2048 works and other values don't. It could be that lower values simply do not work on your system but I am not sure. I agree that in principle, if a certain PA callback buffer size works, smaller sizes (down to some scheduling limit, say 5ms) should also work, and if they do not it is possible that there is an issue. But I don't think that's clear yet.

And to further @dechamps comment, we are now at the stage with DirectSound where it is a Legacy API: it worked fine on older Windows versions, but Microsoft seems to be degrading its performance with successive Windows releases such that it we appear to be seeing regressions in PortAudio/DirectSound. We havn't developed a clean-cut policy on this but we probably need to.