Low Latency on Windows with IAudioClient3

Windows has updated WASAPI to enable low-latency shared audio streams which would be very useful when building JUCE standalone apps! Pete Brown mentioned this in his talk at ADC 2018 talk, but it doesn’t seem like this capability has been added to JUCE yet. There’s a Github issue on the subject, but it doesn’t seem like the changes have been made yet.

I’m happy to go make these changes and get this to happen, but I’m fairly new to COM programming. It looks like in the JUCE WASAPI connector, some funky macros are used to call Windows COM objects using hard-coded strings for class identifiers. Does anyone know how they got the strings which correspond to CLSIDs of Windows classes? If I can find the CLSID for the IAudioClient3 interface, then it could be fairly straightforward to swap this in, change a couple functions and try out low latency shared mode!

Thanks for your help!

2 Likes

Well, bear in mind that that would only work on Windows 10 machines as indicated by MSDN:

Your COM code would need to be backwards compatible down to Windows Vista, and maybe Windows XP (it’s unofficially dropped from JUCE I think).

2 Likes

My guess would be it would be easy enough to keep the IAudioClient code as a fallback, and slot in IAudioClient3 if the OS is new enough. I agree it’s not quite as clean as the current setup, but forcing users to have ASIO drivers installed to get a worthwhile experience feels ridiculous when modern native apps have far better performance.

1 Like

Yeah, I think it’s just a matter of finding out which interface is available and storing the COM pointers properly. By the looks of the methods new to IAudioClient3, there doesn’t seem to be any crazy logic needed to get those lower latencies - it appears to be a drop-in replacement.

+1 to that!


I tried to poke around to see if I can find a GUID/CLSID but there doesn’t seem to be anything explicit. What you might be able to do is store the value for IID_IAudioClient3 (you might need to extern it).

Another way is to make use of __uuidof. Something like:

IAudioClient3* client = nullptr;
auto client3ID = __uuidof (client); //Use the result here somehow...

I’m a bit rusty with Win32 COM these days but hopefully these ideas can be a hint in the right direction.

Looks like this client made its way in: Enabling Windows Audio's SRC !

4 Likes

So exciting to have this looped in! Question for the team or anyone who knows: is there a way to disable exclusive/high latency modes with the new setup? It would be really nice to have these in the Projucer as check boxes, or at least in the code as defines so allowed modes can be specified.

We’re moving away from having lots of compile time config flags which enable/disable behaviour as this makes the build process difficult when not using the Projucer (such as with the new CMake support). If you want to omit the low latency and exclusive WASAPI audio devices you can override AudioDeviceManager::createAudioDeviceTypes() to return your own device list which doesn’t contain them.

1 Like

Thanks for the advice! That seems like a lot of overkill for a pretty common task but fair enough. I see how it is easier for Cmake not to support these flags, but having an easy way to do something standard like disabling exclusive mode seems pretty necessary to me. Would it be problematic to move the defines somewhere the user can over-ride them?

JUCE already has too many compile-time flags which make the build process opaque and test coverage difficult so we’re reluctant to add more for things like this. If you don’t want to have a derived AudioDeviceManager then you could also just not display the option to your users in your device selector UI.

1 Like