SynthMaker

cause-and-effect-chains with tagged triggers

Archive · 2006 5 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

NothanUmber ·

Imo one of the most difficult things to do in SM compared to "ordinary" programming languages is to work out what cause is responsible for a certain effect when several things are involved into the computation of a result value.

Here an example:

In this image we have a complex computation that is determined by two input values. Now the result should be stored into a sample and hold component but only when the change of the result value was triggered by a change of input 2 and not when only input 1 changes. In the shown case presumably everything works as expected as the connection from input 2 to the trigger of the s&h has order 2 and so the calculation result always arrives before the trigger signal. But now imagine that input 1 is not a simple integer but a midi signal. In that case things get highly nondeterministic: I had numerous cases where the computation somehow "waited" for a midi event that wasn't still arrived and thus the second path (the trigger signal that goes to the s&h) was executed first - so an old result value (or one that only considers the new value of input 1 but the old value of input 2 or vice versa) was sampled in the s&h. (Things get even worse when not only much midi stuff is involved but the whole thing is also part of a bigger feedback chain). To make a long story short: There are cases where it's hard to get the different pathes synchronized just with the help of the link order. (Up to now it was always somehow possible, but in some cases that required some rather complex and difficult to work out twisty hacks).

So here my suggestion: Intoduce something one could perhaps call tagged triggers, that means: it would be nice if one could tag an array of strings to each trigger. The trigger keeps it's tag when "flowing" through the various modules (so e.g. if one uses a tagged trigger to store a new value into a sample and hold then the trigger that is sent out from the output of the s&h has also the same tag, if this value is then used in a multiplication operation the result of this multiplication has also the same tag and so on.) That way one could always determine the cause of any effect one sees simply by looking at the tags of the trigger. (Additionally one would at least need a new module to apply tags to triggers and a filter with three outputs: 1) here triggers come out that match a specific (set of) tag(s) 2) the same triggers as with 1 but trigger that comes out of this output has the specific tag(s) removed 3) all other triggers that don't match the given tag(s))

Here how one would apply the concept to the schematic from above: (of course e.g. the link from input 2 to the s&h int input should have order 1 and the link from input 2 to the tag adding component has order 2. Have done it wrong in that example and am too lazy to change all the screenshots again... 🙂 )

The trigger is tagged with the name "inp2" before sending it on it's voyage. That way it's easy to filter it out. "Bad" effects from the input1 (even if it's connected to a midi source) shouldn't be a problem as a result that is based on a change of input 1 would never have the "inp2" tag applied to it and thus couldn't pass the tag filter.

And here a more complex example that uses the result in a different sample and hold when the cause of the recomputation was neither triggered by a change of input 2 nor input 3. (In that special case (as no other inputs beside 1,2 and 3 are present) that s&h would only store results that were caused by a change of input 1):

When tagged triggers would be available one could even allow "orderless" links that are executed in parallel so even a multicore cpu could be used to it's full extent 😍 (ok, that's not absolutely required for SM 1.0 😉 but I'd be really glad if something like the tagged triggers would make it... 🙂 )

Greetings, NothanUmber

NothanUmber ·

Here a even nicer, more general idea:

Make every datatype "taggable". This requires these components:

* a "Add Tag(s) to Datastream" component. This one has two inputs for arbitrary data types (this grey one). The first one is the main information carrier, to which the content of the other one get's tagged as some kind of meta data. (So one can use the outcoming tagged data as it would be a usual data of the type of the original "carrier", as already described with the tagged trigger solution the tags survive being routed through operators - if a tagged data component is used as an input of a component then all outputs of that component also have the same tag.)

* (optional) a tag extractor that allows to extract the meta information. Essentially the inverse of the tag adder.

* a tag filter that allows to filter data streams by tags. Essentially the same as mentioned above at the tagged triggers variant but this time not only triggers but arbitrary data types are supported for both carriers and tags.

Here a picture of how the examples from above would look like with the new generic solution:

In theory that behaviour could of course be simulated by using busses but then one would have to build custom version of every module in the toolbox that should support the new technique so a general SM support would be much nicer and more practical.

Greetings, NothanUmber

NothanUmber ·

Have done a bus based test implementation here.

Greetings, NothanUmber

rl ·

re: your original question. Maybe it could be solved "traditionally" by using the state machine module:

state 0: init :new value for input 1 -> take value into buffer and go into state 1 :else do nothing

state 1: armed :new value for input 2 or midi message arrived or.... -> do computation using buffer and input 2 and back to state 0 :new value for input 1 -> take value into buffer :else do nothing

NothanUmber ·

the problem with buffers is (at least for rather expensive computations) that several midi events could get caught in one buffer while the computation is running and thus unwanted quantizations could happen (perhaps one could introduce several buffers or measure the time between incoming events and store it with the event... but wait, that would require a precise timer that doesn't work with midi atm...) But you're right, presumably one always finds a solution that works without something like the tagging concept if one just trys hard enough. In some cases those solutions can become complex and difficult to comprehend though and (at least it seems to me) something like the tagged concept could help to work out and understand such schematics a little bit easier.

Greetings, NothanUmber

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.