[SDL] Audio callback function is not called in time sometimes

David Olofson david at olofson.net
Thu Dec 6 09:33:02 PST 2007

On Thursday 06 December 2007, Mine wrote:
> I use these stuff to synchronize the buffer read & write. I have two
> thread, one for decoding and write the audio data to my buffer, the
> other for reading the audio data from the buffer, so I use
> mutex/cond to protect the buffer.

Using multiple threads and locking means you're letting go of the CPU 
every now and then - and when you do, you're not always getting it 
back ASAP. General purpose operating systems don't behave very well 
in this regard, and there is little we can do about that, short of 
switching to a different OS.

If you need to do things like this, you need to use lock-free 
solutions. You can never turn a non RTOS into an RTOS, but at least, 
you can reduce the risk of drop-outs by not asking for more trouble 
than you have to.

However, before even considering this (lock-free solutions are hairy 
business), you should make sure your solution is theoretically 
correct in the first place...!

> I would like to send the buffer to audio device with nearly 0
> latency, which means I need my audio callback function works as fast
> as possible, but I find it sometimes takes more than 40 ticks, stuck
> in the SDL_Lock/Unlock.

You can't affect latency in that way. You can be en time, or you can 
be late. If you're on time everything works fine, whereas if you're 
late, you get a drop-out. That's all there is to it, really.

The audio callback is called as soon as the driver has room for 
another buffer of audio, and from that point, you have practically 
the full playback time of that audio buffer (ie samples_per_buffer / 
output_sample_rate) until you actually have to return. Returning 
earlier has no effect whatsoever on latency.

That said, there *is* a reason to keep the audio callback light: 
Finishing quickly means you have more margin for OS induced "coffee 
breaks". The callback may (or rather, will) sometimes fire a bit 
late, and then, obviously, you have a better chance of still 
finishing in time if you have less work to do. However, you shouldn't 
really care about this unless you're using substantial amounts of CPU 
power for audio processing. (Your average games sound engine would 
use a few % of the CPU time available. That's not an issue worth 
considering in this regard.)

You cannot avoid the problem by moving the work elsewhere. All that 
can ever do is make things *worse*. If you can't deliver the data in 
time, there is no way you can make the buffer deadline, no matter 
what you do.

> Maybe I should not use any protection in my read thread so it would
> work pretty fast?

That would solve only one thing: It would avoid blocking the audio 
callback. However, that would just mean your audio callback runs with 
no input every now and then, so you still get your output ruined. 
This is only of use when you have other streams playing at the same 
time, or when you're streaming from disk or similar. In the latter 
case, you'd add some intermediate buffering between the 
streaming/decoder thread and the audio callback, to allow for more 
timing variations without causing drop-outs in the stream.

If you really need low latency all the way from input to output (which 
is unusual in the context of codecs), the only real solution is to 
just do all your sound processing in the context of the audio 

//David Olofson - Programmer, Composer, Open Source Advocate

.-------  http://olofson.net - Games, SDL examples  -------.
|        http://zeespace.net - 2.5D rendering engine       |
|       http://audiality.org - Music/audio engine          |
|     http://eel.olofson.net - Real time scripting         |
'--  http://www.reologica.se - Rheology instrumentation  --'

More information about the SDL mailing list