[linux-audio-dev] Multithreaded programming for a poll model?

Pete Bessman ninjadroid at gazuga.net
Thu Jun 17 16:30:02 UTC 2004


At Thu, 17 Jun 2004 12:50:06 +0200,
Mario Lang wrote:
> 
> I am currently trying to figure out how to restructure the code
> of my little yatm tool to be flexible and extensible in the future.
> Basically, I'd like to be able to become a JACK client at
> some point in the future.  Since JACK uses a poll model, I have
> to majorly restructure my code. I think what I need is the following:
> Three threads, one for the UI, one for the MPEG/Vorbis/Speex decoder,
> and one for audio output (to either libao or JACK).

You actually probably only need two threads, one for the UI and one for
audio (more on this below).

> Additionally, I'd like to have the ability to make the
> buffer in between remember the last n seconds of audio data and make
> it possible to jump back in time <=n seconds during playback.

I think you could just change the value of the position indicator to
have it point that many frames back in time.

> I've looked at the lock-free ringbuffer of JACK, but I am not
> sure if this is really what I need here.  

The lock-free ringbuffer is necessary to communicate to the audio
thread in an RT-safe manner.  RT doesn't really mean "goes fast" so
much as it means "has a guaranteed minimum speed."  If you communicate
with the JACK thread just by mutex-protected global variables, that
guarantee becomes difficult to make.  This is because the JACK thread
will have to lock each mutex to check the value, and there is a
possibility that it might end up waiting an indeterminate amount of
time to get that lock if your UI thread has it.  If you use multiple
variables protected this way, things get worse.

So basically, if you need to tell your JACK thread something, you need
to do it with a ringbuffer.

What I'd recommend doing is creating a UI thread and having it
communicate to the audio thread via the ringbuffer.  The audio thread
would have some setting indicating a chunk of memory or file
(whatever) to read sound data from, in addition to settings on how to
read it and where it currently is within the file.  You would adjust
these settings by checking for messages from the UI in the ringbuffer
at the beginning of each callback invocation.

After checking for messages, just mixdown the number of frames
requested into the provided buffer, transforming it in accordance with
thread's current settings.

Hope that helps,

-Pete



More information about the Linux-audio-dev mailing list