Sample Rate accuracy

Hi, I’ve stumbled across this: I’m building a simple test app based on the AudioDeviceManager tutorial, i.e. standalone audio application (under Windows), with practically nothing added but code that sums up buffersToFill.numSamples in getNextAudioBlock and then displays how many samples per second are collected this way. For a sample rate of 44100 and an audio buffer size of e.g. 1024 this pretty good fluctuates around 44100, for audio buffer size 512 it settles around 41000, for size 256 around 47000 and for 128 it goes down below 37000. CPU usage (which the tutorial displays) is below 1% in all cases.

Can my observation be true? Is this a problem of stand alone where e.g. cheap audio hardware/driver software (Realtek in a laptop) does not provide a proper reference clock and would it be gone if used in a DAW context?

Audio Device Type (top of the audio device manager gui component) is set to DirectSound in all cases. If I set it to Windows Audio numbers go completely out of order.

best,
Andreas

Maybe you could show your code, so we can see if there is some mistake how you are doing the calculations and displaying their results.

Anyway, why are you interested in this? Have you tried outputting a sine wave into the output to confirm the playback itself is actually working? Maybe at the lower buffer size settings some of the getNextAudioBlock calls get skipped and that results in a smaller sum for the samples processed per second than expected.

I have a decently fast machine (i7 4790) with Roland Duo Capture sound card. With DirectSound I can’t go below a block size of 896 without dropping samples.

With Windows Audio I can go down to 132 samples no issue. DirectSound is pretty bad for low latency. Use Windows Audio or ASIO instead.

What do you mean by:

numbers go completely out of order

displays how many samples per second are collected this way

How are you measuring time in seconds?

afaik on windows the callback will never be called in literal real time, since Windows isn’t an RTOS. ASIO and exclusive-mode WASAPI are as close as you can get and use a double-buffering scheme to do it.

Hi, thanks fo all answers. I did a test with the original Audio Device Manager tutorial and added my measuring code:

  • set a long count = 0L in prepareToPlay
  • set a juce::int64 t0 = Time::currentTimeMillis() in prepareToPlay()
  • add bufferToFill.numSamples to count in getNextAudioBlock(…)
  • set a juce::int64 t = Time::currentTimeMillis() in prepareToPlay()
  • display (float)count / (float)(t - t0) * 1000.0f in the timer callback that displays the cpu usage every 50ms

So that’s pretty basic stuff and - e voila - it shows reasonable numbers after waiting a few seconds (to compensate non real time effects and such as mentioned above)

The big difference to my own code was that I set max output channels to 0 in the AudioDeviceSelectorComponent because I only wanted to gather input data and do something with it. So in the end, the absence of output channels made the drivers behave very innacurately, especially the Windows Audio driver.

That is, for the moment, a solution to the problem for me.

Thanks for reading,
Andreas

So in the end, the absence of output channels made the drivers behave very innacurately, especially the Windows Audio driver.

very interesting. thanks for the update!