Order of execution in the MSP world
Hi,
I'm making a patch that reads from a buffer, applies an effect, then writes back into the same buffer, mixed with the buffers original contents. I'm using the index~ and poke~ objects. How can I predict if the index~ is going to read the original buffer or the affected buffer? How can I predict the order of events? This is obviously very important with patches such as this.
Thanks,
Rob
regarding _inputs_ to individual non-signal objects the order is right to left with the leftmost input generally triggering any output
regarding non-signal objects between each-other, it is bottom-right to top-left, with vertical order preceding horizontal order (i think), and innermost sub-patch taking precedence over enclosing (parent) patchers....
but, with ~ objects it is basically top to bottom, and always within the context of a signal vector. I think any feedback process, if possible, is delayed by a signal vector-- but you'd need to post the patch to get more specific answers. If you use send~ and receive~ the order is delayed by a vector, so that would effect things for you (you might be able to use that behaviour to your advantage though). If you want to get beyond that limitation you can look into gen~
send~ and receive~ introduce one vector of delay only if it is necessary (feedback loop in DSP graph). Probably you can enforce order of execution by connecting objects to be executed later to those to be executed earlier via some bogus connections ( -> [*~ 0] -> [+~ ] -> ). But keep in mind that Max computes signal in blocks (vectors), so sample-by-sample buffer rewriting is only possible when signal vector size == 1 (just assumption, not tested) or using gen~.
[t~ ~ ~ ~ ~] Not to be confused with the new trigger
which can also operate at each output
[t (i * 2) (f / 2 * pi) i abs(i) bang "hello"]
Maybe?
index :: original buffer + index to signal process :: poke original buffer (feed..)
If you have gen~, you can use splat. It's intended for this type of processing. (Read/write with mix)
I would definitely use gen~ for such purposes, it's more reliable, precise (especially if you want to use constants like pi), and the feedback minimum delay is only one sample instead of one vector size.
However, if there is no feedback in the patch, msp should work well, exactly as mentionned above (and similarly to gen~ except this feedback question): top-to-bottom processing, no right-to-left ordering: basically, all objects receiving signal from a single object will be processed together (not at the same time, but in the same processing block (one vector size), so for the user's it's as if they were processed at the same time), and then the next objects on the cascade are processed, etc... until the output. So basically, within one block, the whole DSP chain is being processed at once.
So to answer your question, Robert, if I follow your description well, index~ will read the "old" samples, and in the same block, poke~ should overwrite those samples with new values without affecting the behavior of index~.
This works however so only if the sample index which is sent to index~ is exactly the same as the one which is sent to poke~. If you write samples in poke~ in advance (i.e. if the sample index which is sent to poke~ is bigger than the one sent to index~), poke~ will indeed affect the behavior of index~ (because index~ will read the new values of the buffer instead of the old ones). This could lead to interesting nasty feedback effects...
Alexis
Alexis
Hi,
This is good to know actually, thanks for the tip! I should double-check such a nasty hack is also needed for gen~.
Alexis
Actually this should be okay in gen~, if one connect the second outlet of peek (index output) to poke.