[linux-audio-dev] Processing a chain of machines

Raf Geens raf at clueless.be
Sat May 24 14:35:02 UTC 2003


Hi all,

I'm currently working on creating Mess, a Buzz-like software studio written in 
C++ on Linux, and have run into a somewhat critical problem (note: this is my 
first "real" audio app): I'm using PortAudio as audio API and it's 
outputbuffer keeps underflowing because my callback function is too slow.

One of my goals is to enable the user to make a network of synths, samples, 
effects,etc. ("machines" in Buzz-terminology). My initial idea for 
implementing this was to associate a buffer and a process-function with each 
machine. If the machine only generated sound, the process-function would 
simply fill the buffer, if it was an effect the buffer would contain the 
effect's input which would be consequently overwritten by the effect's 
output. The MachineManager class contained a processChain-function which was 
responsible for calling each machine's process-function in the right order 
and copying and mixing the contents of the buffers according to the 
connections in the network.

PortAudio's callback called the processChain-function and next copied the 
contents of the master machine's buffer (the master represents the output in 
the network) to PortAudio's outputbuffer.

As a test I made a simple sine tone generating machine and connected it to the 
master. This resulted in some weird noises when using small buffers and in 
clear sine tones with pauses inbetween when using very large buffers.

In an attempt to let the callback do less work, I made an extra thread 
together with a set of two buffers with read/write flags, the idea being that 
the thread continuously tried to fill the buffers with the write flag set, 
using processChain (after this the buffer's flag would be set to 'read' ; if 
there was nothing left to write the thread would go to sleep) and the 
callback function given to PortAudio would check each time it ran for a 
readable buffer and copy that to it's own outputbuffer (and setting the just 
read buffer's flag to 'write', awakening the thread with processChain in it).
This again resulted in some weird noises (mostly due to thread scheduling not 
quite going the way I expected).

The problem with my first method seems to be the copying of all the buffers 
that makes the callback function too slow,  but I don't immediately see any 
other way of doing it (is there one?).
In retrospect the second way just seems wrong.

So my question right now is: how can I process a chain of machines in a fast 
enough way?


Raf



More information about the Linux-audio-dev mailing list