Re: [linux-audio-dev] Producer/consumer threads and syncing

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

Subject: Re: [linux-audio-dev] Producer/consumer threads and syncing
From: Paul Davis (pbd_AT_Op.Net)
Date: Fri Apr 19 2002 - 19:50:09 EEST


>Context: Linux/OSS
>
>I have two threads (play_thread and output_thread). The output_thread
>write sample chunks of 1024 bytes (from RAM) into a circular (jitter)
>buffer (of length 8). The play_thread plays sample chunks from the
>same circular buffer.
>
>The question is: How do I keep these two threads in sync?

well, i'm not totally sure, but definitely not anything like the way
you are doing. you cannot use a non-audio timing source to sync to a
timing source unless you want to do a lot of ugly code to resync them
as they drift (possibly in two directions over a given period of time).

>If I let the play_thread play samples as fast as it can, blocking on
>the write(2) system call, it gets _slightly_ to little data to run in
>lock step with the output thread. Hmm.

Yet another audio programmer sadly tied into the write(2) system call :)

>I tried to delay the play_thread using the same 127712 period as the
>output_thread, i.e. pseudo code follows:
>
>suspend.tv_sec = 0;
>suspend.tv_usec = 127712;

It seems that you are not aware that Linux (and POSIX OS's in general)
do not provide timing of this kind of resolution. You just can't do
this without (at the very least) a kernel patch, and even then, it
still won't provide correct sync without drift correction.

Instead, what you do is to use pthread_cond_signal() from the
play_thread to notify the output_thread that it needs to do some
work. Simply keep track of the relative position of the read/write
pointers for the ringbuffer, and when the gap is too large, tell the
output thread to deliver more data into it.

>The plan in the long run was to mix several incoming/outgoing udp streams
>using a number of threads taking care of mixing/udp in traffic/
>udp out traffic/play/recording, on each machine, using gettimeofday to
>sync each thread. If I have a problem with the syncing of two threads
>within a single UNIX process I will probably have little success with a
>more complex scenario though. :-)

I don't want to sound like a (broken record|skipping CD), but why
don't you consider using JACK as the framework for what you are doing?
You can forget about the mechanics of audio I/O and focus instead on
ways to do useful work, which in your case might be interesting work
for the rest of us too. Under JACK, your play thread will get called
periodically to deliver and/or process "nframes" of audio data. You'll
still have to work out the synchronization between that and the thread
thats writing data into the shared ringbuffer, but you'll be able to
forget about write(2), usleep(2) etc. You'll also be able to send data
to other JACK-aware applications.

http://jackit.sf.net/

--p


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

This archive was generated by hypermail 2b28 : Fri Apr 19 2002 - 19:34:52 EEST