[SDL] Audio callback function is not called in time sometimes
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