Retriggering value in gen~?
Hi,
Maybe an easy question im not sure. Basically in gen it seems that sending the same value does not trigger any change. So if I send a 0, it will only be sent once and each 0 I send thereafter it will not trigger anything to happen. Whereas if I change the number from 0 to 1 and back again there are 2 changes happening. I would be really grateful if someone can confirm this is expected behaviour and suggest any workarounds for this? ie How is it possible to retrigger the same number value going into Gen?
Two perspectives that can help to understand this, and some ideas for how to get what you want:
1) When you send a "0" message in Max, you're actually creating two pieces of information: the value 0, and the imperative to "respond now". Both things are bundled together into one message.
2) When working with gen~, you have to get used to the idea that everything is an audio signal running all of the time; there aren't "messages" as such like in Max. There's no bundling of value and 'respond now', because the genpatcher is *always* responding now, for every sample of passing time.
In terms of sending values, e.g. to a gen~ inlet or param, all gen~ knows and all `in` and `param` objects know is "what is the value of this signal right now". So, for example, an `in 1` object inside gen~ will continuously output a stream of values at the audio sampling rate (e.g. 44100Hz or 48000Hz etc, according to your DSP settings). If you have an audio stream from an MSP object hooked up to gen~'s inlet, then that audio stream will come out through `in 1`. But if, instead, you have a UI object like a number box or a message box etc. hooked up to the gen~ inlet, your messages just set what the value of `in 1` will be, but `in 1` will still send this into the gen~ patcher as a continuous stream of numbers. Even though all the numbers are the same, they are still streaming sample by sample. If you send another message but the value is the same value, then the `in 1` will still be streaming that same number. From the perspective of the gen~ patcher, nothing has changed. So, gen~ doesn't know to "respond now".
Of course sometimes you want to trigger some process to start, to create an event by telling gen~ to "respond now" Here's a few of the most typical ways of getting these kinds of events into gen~:
a) Use a trigger impulse signal with e.g. `click~`. A really simple example is `button` -> `click~` -> `gen~`. By default, the `click~` object in Max outputs an audio signal as a stream of zero values. If you give it a `bang`, like comes out of a `button` object, then at that moment the `click~` object will output a single sample with a value of 1, then it will return to a steam of zero-valued samples again. That is sometimes called a trigger or impulse, and it is as close as you can get to the audio-rate equivalent of a Max `bang`. Lots of objects in gen~ can respond to a single-sample trigger like this -- such as using a `latch` to sample another stream, or resetting a `phasor` or `accum` etc.
b) Variations of the above by looking for certain value changes in an incoming signal, like a zero to nonzero transition, a negative-to-positive transition, etc. Objects like `change` and logic operations are good for detecting these.
c) Overriding a named `history` object. Let's say you have a `history start` object, and you hook up a `0` object to its inlet. That means that at the end of every sample frame, this history value is being set to zero, so normally it will output a stream of zero values. However, if you were then to send a message to the gen~ object like "start 1", then *for one sample frame only* the `history start` object will output a value of 1, and then it will return to outputting zeroes. So, this is another way to create a trigger impulse in response to a Max message.
OK so to put these together, and send both the value 0 and the imperative to respond now, a typical case would be having an `in 1 trig` for the trigger part (driven e.g. by a click~), and a `param val` for the value part. So the message "0" can go to a `prepend val` -> gen~ for the value part, and `t b` -> `click~` -> gen~ for the trigger part.
That's not the only way -- there's other options you can use in some cases. E.g. if you knew your value is never zero, then you can pack the value into the impulse amplitude itself. Or, if you know your value never repeats two in a row, you can just use a `change` object inside gen~ to get the trigger. As usual with Max and programming generally, there's lots of possible solutions with different tradeoffs.
Anyway I hope this helps -- mostly once you get into the way of thinking that in a gen~ patcher everything, every cable, object, the entire patcher, is ticking away for every sample of passing time, that there's no events, just signals, it starts to get a lot clearer, and actually I think opens up a lot of freedom and possibilities.