[linux-audio-dev] aes: new model

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

Subject: [linux-audio-dev] aes: new model
From: Paul Davis (pbd_AT_Op.Net)
Date: Thu May 17 2001 - 21:08:05 EEST


prompted in part by discussions here and partly from discussions on
ardour-dev, i've been revising the design of aes. its about 75% done
right now. here's an attempt at a summary. the big change is that
there is no direct access to the DMA buffers (all audio is written to
Engine-provided buffers), and the object responsible for interfacing
with audio h/w (or whatever) is mutable at run time.

objects:
         Port : a description of an input or output
         Nodes : has 0...N input ports, 0...M output ports
         Plugin : a kind of Node with a "process(nframes)" function
         Driver : a kind of Plugin with a "wait()" function
         Engine : has a list of Plugins, and a single Driver

the main loop of the audio thread now looks like:

    while (!done) {
           driver->wait ();
    }

inside driver->wait() we do something like:

    poll ();

    ... determine how much data/space is available ...

    engine->process (nframes);

    move_output_data (); /* moves data from the driver's output ports
                            to the audio h/w
                          */

and Engine::process() looks like:

    foreach plugin in sorted Plugin list { plugin->process (nframes)

Note that a Driver is a kind of Plugin. So, the Engine builds a signal
graph for the current interconnections between all the ports, and
executes all Plugins (including both the Driver and regular Plugins)
in the "correct" order (if such a thing exists).

Expected signal flow:

   driver internals (e.g. ALSA) -> driver output ports ->
       plugin input ports -> plugin processing -> plugin output ports
              driver output ports -> driver internals (e.g. ALSA)

Expected execution flow (if the graph looks like the description above):

         driver->process (nframes); /* moves data from the audio h/w
                                        to the driver's input ports. */
         all other plugins

In the current design, there is only a single driver associated with
the engine.

The design is fairly MP and SP friendly: the engine can instantly
update all Plugins on the locations of their output and input buffers,
which can live in shm for the MP case. The mechanics of
plugin->process() can either be handled by a direct function call (SP)
or via a signal/pipe wake up of the relevant plugin process. This is
all very easy to do.

i don't yet know whether the use of all-engine-provided-buffers and no
direct writing to DMA areas will be more or less efficient than the
old AES design that used write_to_channel etc. but i am convinced that
this design is more correct and more flexible than the old one. It may
be faster to. we'll see.

The engine no longer supports busses directly. Busses would be
supported by a specific plugin, whose job was simply to declare N
inputs and N outputs, and to run a process() function that did
basically nothing. There's work to do on the details of this, but the
idea has great appeal for me, and may help settle the argument over
patchbay/bus designs.

this is not so different than a model Abramo proposed, which did
something like:

     foreach plugin { plugin->wait (); }
     foreach plugin { plugin->process(); }

however, for reasons that have been discussed here, i (and some other
people) don't believe that a low latency model will allow "waiting" on
anything except the PCM device state, and so i derived a slightly
different type of plugin, the "driver". a single driver is the only
thing which the engine wait()'s for before executing the signal graph
via plugin->process().

"Those who do not understand aRtS are condemned to reinvent it" :)

--p


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

This archive was generated by hypermail 2b28 : Thu May 17 2001 - 21:47:27 EEST