When troubleshooting audio problems it is sometimes interesting to know exactly what audio API the app in question is using.
Sometimes we can just ask the app developer, or look at their code.
Sometimes it is possible to get an educated guess by looking at the list of .dlls that get loaded into the app. But in cases where an app uses multiple audio APIs simultaneously, this doesn't help much.
The old-school technique, if you have a repro sitting in front of you, is to attach a debugger to the app, set a breakpoint or two, resume, and then once a breakpoint hits, dump the stack. But if you don't have a repro sitting in front of you, this is difficult.
Fortunately, Event Tracing for Windows (ETW) has a feature that you can ask for the stack at the time a given event was logged! I've blogged about this before in Tracking down calls to AvSetMmThreadCharacteristics.
- Download audio-client-stack.wprp
- From an elevated Command Prompt or PowerShell window:
wpr.exe -start audio-client-stack.wprp
(run the app and trigger the audio activity)
wpr.exe -stop some-filename.etl
- Open some-filename.etl in Windows Performance Analyzer
- Look at System Activity > Generic Events and System Activity > Stacks. Use Trace > Load Symbols to get function names to resolve.
For example, this is the callstack I get for Microsoft.Windows.Audio.Client/AudioClientInitialize when I do echo ^G (that's Ctrl-G) from a PowerShell window:
So in the case of echo ^G I can conclude that the API layer immediately above the Windows Audio Session API (WASAPI) is Windows Multimedia (WinMM)'s Waveform-Audio interface (waveOutOpen), because I happen to know that wdmaud.drv is the module that implements Waveform-Audio.
I can't tell from this stack alone whether there is another audio API above that (say, PlaySound.) I could repeat this process by finding an event that was logged by waveOutOpen and constructing another .wprp to grab the stack on that thread, and so on and so forth.