Roger Larsson writes:
I try to list some pro / con for call back and push
APIs:
push API:
Pro:
* simple to play a single file, basically a copy from source file to
destination.
Con:
* hard to write plugins that way. Take a look at arts plugins. They all have
a 'calculateBlock' = call back!
Why?
In a pure push model each processing step reads data from
one file/pipe/device, processes it, pushes it to a file/pipe/device
You get:
* lots of threads/processes that are not optimally synchronized.
Any thread is runnable when there are input available until the
output is full.
But that is not the important case, concider the case when the last
processing steps output is almost empty (if it gets empty you will hear
a click). How to prioritize it higher than all other threads? Should it
always be higher? Suppose it is a mixer that has several inputs...
Could be done by a super server that sets priorities depending
on position in the line? This is not easy...
There is no need to prioritize it. The possible bad synchronisation in
a 'push API' system arises from the fact that threads that do not need
any RT input (e.g. an oscillator) are essentially free running and are
allowed to 'work ahead', thereby stealing CPU time from the others.
This can easily be avoided by making these 'free-running' threads wait
on an event that has the right frequency, e.g. a counting semaphore
that is incremented by the output module each time a block is processed.
This way you can eleminate all buffering between the threads, and
you get a system that is as deterministic as e.g. JACK.
There is only on remaining problem: threads that need N inputs could be
scheduled up to N-1 times before they can proceed, which may generate
a number of unnecessary swaps. This is nicely solved by a system such as
JACK that will only wake op the processing thread (which then calls
your callback function) when all required resources are available.
The same effect can be had by using ITC mechanisms that allow you
to specify more complex conditions that a thread can wait for. The
result is a 'push-API' system that is completely deterministic and
as efficient as JACK. This is no imagination, I am using such a system
for telecom DSP applications. ITC is based on pthread condition variables.
--
Fons Adriaensen
ALCATEL TELECOM