Efficient sampling of audio render client position

189 Views Asked by At

I want to efficiently monitor audio playback position. I understand I can use IAudioClock::GetPosition() and that this is a blocking call that can fail, and should not be called from a thread that is decoding or resampling the audio stream.

So I set a waitable timer object with a dedicated thread blocked on it, that then calls IAudioClock::GetPosition() and invokes a callback function to process that. There is the concern of the effect on low power state if the timers frequency is too high, and with a period of 16ms this makes me go from 0-1% to 13% CPU usage.

Now I've noticed that IAudioClient::GetDevicePeriod() gives a value of 3ms for exclusive mode and 10ms for shared mode. As my PC is about 8 years old I assume this is a common situation. Which leads me to believe that as I used an event for wasapi to notify me to fill the audio play buffer, which is maybe guaranteed to happen at the device period intervals? If so the the check on position at that event being signaled should be more than precise enough if I only want a bit better than 16ms precision? I believe human audio/visual sync is good enough at close to 16ms for example.

I also understand how to extrapolate the position due to the coupling with query performance counter specified by IAudioClock::GetPosition() which of course helps.

So the crux of my question is, in a modern PC is the waitable timer object approach overkill? As simply sampling the position on the wasapi fill the buffer event is more than good enough? (But then you are calling a blocking GetPosition() in a situation where you shouldn't!) Or is the latter too unreliable for slightly better than 16ms precision? In which case I would have to suffer the extra CPU usage?

There is some interesting relevant discussion here: https://github.com/kinetiknz/cubeb/issues/324

0

There are 0 best solutions below