When an audio callback function is called for playback (i.e. iscapture=false
), the audio data used to fill the provided buffer will be played at some time in the near future. Is there a way to calculate, measure, or estimate the time (or range of possible times) from the initiation of the callback function to the actual production of sound by the audio device?
Similarly, the buffer provided in a record (iscapture=true
) callback function contains audio data that was captured at some time in the recent past. Is it possible to calculate, measure, or estimate how long ago that sound was actually recorded?
I should add that in attempting to achieve synchronization between recording and playback (multi-track recording in a DAW) I achieve the best results when I assume a playback latency of approximately 91 times the theoretical minimum latency, where the theoretical minimum in seconds is (chunk size / sample rate). I’m working at 48k Hz with a chunk size of 64 sample frames, so that’d be 91 * 64 / 48000 = 121.3ms, which is much, much worse than I expected. My expectation was that the system might hold a buffer of 2 or 3 times the chunk size before that data actually hits a DAC, and that therefore the real latency would be 2 or 3 (not 91) times that theoretical latency.
Some or most of this latency might actually be recording latency, rather than playback latency. I can’t test the two independently. The way I’m testing is by playing a prerecorded handclap through my laptop speakers while simultaneously recording that sound back in through the laptop microphone. I can only get the re-recorded clap to line up with the original if I assume that large 121ms delay, distributed somehow between recording and playback. All of my timing is based on the execution of the callback functions, and each of the callbacks is doing minimal work.
I’m still working to find errors in my methodology or calculations, but any guidance re: expected latency (recording & playback) in this situation would be helpful. Are there any scenarios where SDL would add significant overhead and latency in its handling of a callback buffer, or should it be close to two or three times the theoretical minimum latency?
First, measure your soundcards actual round trip latency (How do I measure the round-trip latency? - Prism Sound)…
Consumer sound cards will have higher buffers to avoid clicks/pops - 121ms is average. These cards cannot phsyically push the data out any quicker, and even if you try and effectively force the smaller buffer on the software side (ie < 121ms), the hardware wont be able to work fast enough and youll get pops/clicks/laggy audio.
So one bottleneck is your hardware. The other is the sound driver your OS/hardware is using, as Im sure (was true back in the day) Windows will also force a large, consumer friendly buffer size whereas ASIO drivers like ASIO4ALL allow you to go as low as the hardware permits.
As for SDL’s inherent latency, how its determined, how its changed - I cant comment.
1 Like
Thanks for the response @conorjh. The prism article basically describes how I’m currently measuring latency on my machine (though I’m adding a negligible amount of sound-through-air latency), and as a temporary fix, I hard-coded latency compensation based on my measurements. The problems I’m facing are:
- I’d like to avoid making my users run similar tests
- The measurable round trip latency encompasses sound card latency, playback device latency, record device latency, driver latency, and maybe SDL latency, but I have no way to determine how much latency each of those elements is contributing to the total.
- The latency values vary between tests within a musically significant time interval, even on all the same equipment.
Do soundcards, audio devices, and/or drivers report their own inherent latency? If so, of course it would be very convenient for me if SDL provided an API to request and read those reports, but I’m pretty sure it doesn’t. Do other, more audio-focused libraries like PortAudio provide something like that?
Re: 3, that may just be a fact of life. As much as I love the infinite flexibility of digital audio, it makes me wish we hadn’t left tape machines behind.
I think you can get device latency at least from a library like Juce. The driver and os latency I think you might be able to do performance counters for maybe if you just want to know