When does Switch execute in gen~

J Mangel's icon

as you can see from patch or pic, i am really trying to step through how gen~ processes one sample at a time. My mai questio here is, is switch tested/queried/outputs at any time a value arrives at any inlet or only when a value is received in the first inlet? What trobles me, is that according to my step thru, event one (e1) seems to send both a value from the recipt at inlet 1 and inlet 2, which would cause 2 values backed up at history, both which seem problematically within the same sample frame. I lost my train of thought, so please not that my event scheduling loses it some point.

I suppose the more general question is, how does gen handle events? when we say that gen handles processing 1 sample at a time, per sample frame, does it follow right to left order? does switch respond to any value in any slot?

Max Patch
Copy patch and select New From Clipboard in Max.

Graham Wakefield's icon

It's really crucial to understand this about gen~: Patch cables in gen~ are not messages, they are audio signals. At every passing sample frame of real time (44100 times a second if your sample rate is 44.1khz), every cable has exactly one value. The entire patch moves forward one sample at a time.

There are no messages, no events, so there is no hot/cold inlets, no left-to-right ordering, etc. Every patch cable is always active, always a stream of numbers at 44100 times a second. Even if the signal in the patch cable looks like a constant, e.g. a constant value of 0, it's actually a stream of 0 44100 times a second.

You can't "step through" like you can with Max objects, because within each of these sample slices of time, every object in your patch will do its job once and update its outlets, and the next object will read those values. The entire patch happens in one sample.

That's also why the only way to make a feedback loop is to use a history (or delay) object. You can't have two values backed up in a history, because there is only ever 1 value in a patch cord. If you patch two cables into an inlet, the inlet will add their values together.

If you've ever used a modular synthesizer, it may be helpful to think of gen~ patch cables as carrying voltages.

Once you get this way of thinking, everything becomes really straightforward.

Iain Duncan's icon

Great explanation. As Graham isn't touting his book, I will! This is covered very well in the two books on Gen, Wakefield and Taylor's and v3 of Cipriani and Giri. I can't recommend them both enough. :-)

J Mangel's icon

alright this is good. I think im so used to max, this is an alien concept. The modular analogy makes sense. Im still trying to imagine how switch works, the value in the open channel is continually output until switch opens the other outlet...

So Iain thats how i ended up with this problem, i really know nothing about gen, but i just started working through GO by wakefield/taylor, and im really trying to see why the patches work, and this particular patch in the book i couldnt track.

thanks yall.

Graham Wakefield's icon

You can think of switch is really like an electronic switch -- at any time either input 2 or input 3 is connected to the output. Input 1 chooses which one is connected.

In code terms, it is equivalent to this:

if (in1) {
    out1 = in2;
} else {
    out1 = in3;  
} 

Or this:

out1 = in1 ? in2 : in3;
J Mangel's icon

hey Graham, sorry, i missed that was you above - good book. Im picking it apart, ha ha. so, all of these responses have really helped. the switch selects an output continually. but this is the crazy part, and im just getting my head around it, if not for history, feedback would be impossible bc the signal feeding back in would just be superimposed on itself? value for value. or its an interminable loop... All object executions literally take place simultaneously? i promise, yall will give up assisting me here before i do....

but then i jump back up and read the earlier response with this but: "every object in your patch will do its job once and update its outlets, and the next object will read those values." tell me if im misreading, but that seems like a stepping process that i need to work through if i am to understand the function of a patch- am i wrong?

like this example pictured below, lets assume a signal of 0, right switch is outputting 0 to input 1 of left switch. but the incoming 0 signal has input 2 outputting at left switch. the moment we receive a 1 into this gen patch, there has to be an order of operations for right switch to output input 1. now we are receiving a 1 into input 1 on left switch. if there were no order of operations that input would be indeterminate right? I think that this is what i was trying to do with the possibly futile exercise above, ha ha.

thanks yall

Graham Wakefield's icon

"if not for history, feedback would be impossible"

yes, because feedback (without history) is impossible because it would imply an infinite loop.

"All object executions literally take place simultaneously? ... every object in your patch will do its job once and update its outlets, and the next object will read those values."

OK, let's say your samplerate is 44100.

44100 times per second, the entire gen~ patch will run. That means that each object in the gen patch will compute its next value, and output it. These are "simultaneous" in the sense that they all happen within 1/44100th of a second. But they are "sequential" in the sense that yes, the operators update one by one because the computer can only actually do things one by one.

When you edit the patch, the gen~ environment looks at what objects are connected to which, and then figures out from there in what order the objects should update. Every single object in your gen~ patch appears once in this list. Any particular object will come after any objects that feed into it.

This ordering of operations gets turned into machine code. Then, 44100 times a second this machine code is being run. (actually it's slightly different than this for efficiency reasons, but effectively it is the same)

If you count time in samples, then e.g. on sample frame number 74 (after 74 samples have elapsed), each object reads the 74th output of every object fed into it, and computes its own 74th output that can be used by the next objects. (The exception is history, which outputs the 73rd value it has received, for a 1 sample delay).

But other than history, you can always assume that the input to any operator is a value that was calculated within the same sample frame. If an object has 3 inlets, then all 3 inputs will have been calculated in the same sample frame. That is the sense in which they are "simultaneous" ("synchronous").

If an inlet has 2 cables connected, you can also be sure that both cables carry values calculated within the same sample frame, and the inlet will add them together.

"like this example pictured below, ...

In that patch, if in 1 is zero (which is interpreted as logical false), then the right switch will select the "false" option which is 2. The left switch also selects the "false" option, which is the 2 generated by the right switch. So the patch outputs 2.

If the in 1 is anything other than zero (which is interpreted as logical true), then the right switch will select the "true" option which is 1 . However the left switch also selects the "true" option, which here is 0. So the patch outputs 0.

J Mangel's icon

i uploaded the wrong pic, but you explained it.

"gen~ environment looks at what objects are connected to which, and then figures out from there in what order the objects should update." That was very helpful. Thanks for the help , again. Im now backing out of latchsync to go.ramp.div.gendsp.