Enabling live coding

In the draft for the DAFx paper on Multicore we currently give the impression that the audio graph have to be compiled before starting processing (or we are not discussing how we "trigger" the passing of source object and inlet number to the next object(s) downstream:

For processing to occur, the connections of the graph must be established and the graph readied for operation. This is done by first passing a source object and the outlet and inlet numbers of the connection to the downstream object's \texttt{connect()} method. Then, any connected objects need to be initialized by a call to their \texttt{init()} method, serving e.g. to provide information on sample rate and signal vector size to signal generators. This call will propagate up the tree from each terminal object, and is typically only called when the graph is started.

This could be extended to enable live coding in Max assuming that:

  1. The graph keeps track in a central place of the following information for each connection:
    • What object is the connection from
    • What outlet of the object are we connecting from
    • What object are we connecting to
    • What inlet of the object are we connecting to
  2. A notification system when connections are created and destroyed

When a new connection is created:

  1. The connect() method of the receiving object is called
  2. The connection is added to the central table/dict/linked list/whatever.

When a connection is destroyed:

Do we have a disconnect() method removing the connection? If so:

  1. disconnect() is called
  2. The connection is removed from the central table of connections
  • TAP: we have this partially implemented, it is called "drop".

When an object is created:

The graph is not altered in any way until we start making connections.

When an object is destroyed:

Before the object is destroyed:

  1. The central table is traversed searching for all connections from the object. Each of these are destroyed according to the above
  2. The Max object is destroyed
  3. The central table is traversed searching for all connections to the object. These are removed from the table

Final notes:

Currently the Multicore graph is discussed as a peer object model in the paper draft. The introduction of a central table adds a server-like element. It is also interesting how this somehow resembles some of the ideas used for current development of the Node lib...

Any object bridging Multicore to or from MSP will also be part of the MSP audio chain. If such objects are created or destroyed, or connections between them and MSP obejcts are created or destroyed, the MSP audio chain will have to be rebuilt. Still it does not affect the Multicore Audio Graph as such...

When deleting connections and objects, we have to make sure we do not try to process audio using the connections and objects while they are in the process of being deleted, so that we end up with pointers to null and crashes. This might be the most tricky part to get right. One option would be that deletions are scheduled to be done during the "post-process" round?

Currently the building of the graph also serves to set sample rate and vector size. Do this need to be initialized, or could it rather be passed around with each processing of vectors?

  • TAP: it is already passed around, but the problem is with generators. However, see below...

Then, any connected objects need to be initialized by a call to their \texttt{init()} method, serving e.g. to provide information on sample rate and signal vector size to signal generators. This call will propagate up the tree from each terminal object, and is typically only called when the graph is started.

We should investigate what the init() method serves to do currently, and how it might (not) work with the ideas put forward here.

  • TAP: I think we can merge the init() functionality into preprocess() -- this will make a lot of things cleaner/easier.