[linux-audio-dev] accumulated low latency, real time wisdom

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: [linux-audio-dev] accumulated low latency, real time wisdom
From: Paul Barton-Davis (pbd_AT_Op.Net)
Date: Tue Mar 14 2000 - 05:44:52 EST


>> I think they are using GTK + spinlocks in a wrong way,
>> leading do both bad latencies and instability of the software.
>> (even on the .WAV demo from their site you can hear some cracklings)
>
>Can you explain this issue a little more? I'm gearing up to use GTK+ in
>an audio project right now; I'd love it if you could give some info on
>do's and don'ts with GTK audio and sync features. You're the low-latency
>expert :-) after all and I'm trying to improve this whenever I can.

There are no GTK audio features. The key rule is that you use at least
2 threads, one for interactions with the audio interface(s), and one
for everything else, including the GUI. The audio never blocks for
anything except the audio interface. That means: no disk I/O, no
interaction with the X server. Blocking on a pthread lock is also bad,
but occasionally cannot be avoided.

Simply by obeying this rule, you can do fairly well even without
SCHED_FIFO, but ultimately, not running the audio thread with RT
priority will almost certainly cause dropouts from time to time unless
you are working with about 500msec of buffering, and perhaps even
then.

I have written 4 rather complex, low latency, real time audio/MIDI
apps, and in every single one of them, there is a common method of
dealing with requests/commands/data that go from the audio thread to
the GUI thread. Requests/commands from the audio thread(s) get put in
a lock-protected FIFO queue (the lock is held only for as long as it
takes to push/pop one element). Then we write a single byte to a pipe
that will eventually wake the GUI thread up (it has used
gtk_input_add() to listen for I/O on the pipe). This allows 5K
requests to be made before the audio thread will ever block making a
request, and in practice, the queue is at most 2 requests deep. For
example, this is how all error/warning/info messages are handled. It
takes less than 10usec to send such a message to the GUI thread with
this system, and the sender is more or less guaranteed never to block.

Since I write primarily for dual CPU systems or better, I use my own
function, pthread_mutex_spinlock() for short-held locks, ensuring that
the calling thread will not block unless the lock is held for an
abnormally long time (> 50% of the interthread context switch time).

The GUI thread gets a C++ object to manipulate directly, if necessary
with locks held for no more than a few instructions, and the audio
thread refers to the same object.

I think of my objects as the primary elements in the design, and some
of them come with "backing threads" to implement work that needs to
happen outside of the "main thread" of control which always runs the
GUI.

--p


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Tue Mar 14 2000 - 13:20:17 EST