FOLLOWING THROUGH WITH MY IDEA
In the light of the taken decisions, I started to get my head around programming a Euclidean Sequencer in Max/Msp. Today’s post analyses the development of the system handling the Pulse generation and distribution, that changed multiple times due to various issues encountered along the way. I’ll discuss such issues with the support of little portions of the patch, that I enriched with comments. Please open the links found in some sections of the article; they will direct you to the patches’ free download page.
CONCEPTS AND PRACTICAL TOOLS
The main component of the sequencer is a “global pulse generator control” – allowing to set the number of pulses to be featured in the sequence -. Each step is practically a “ toggle switch”, accepting zeros and non zeros in its inlet (0 = Off; non zero = On).
For a better and faster outcome, I decided to lay down the fundamental concepts behind the sequencer, with the aim of translating them into practical tools.
The two firm points where the use of samples and of a system able to filter specific messages/commands and route them to various destinations.
To reproduce audio, I opted for using the “buffer~”, a Max object that is able to store audio samples. The sample playback is made possible by a “ groove~” object, having the “buffer~’s” same name (you make it up)
e.g. [buffer~ sample1] —> [groove~ sample1]
As for the step distribution, I chose to use conditional equations. Such statements allow the user to set a condition by specifying a variable value:
e.g. [if $i1 == 1];
then, they allow to define the output value/command, fired only if the input matches the number stated in the equation:
e.g. [if $i1 == 1 then bang]
This way, whenever the input number equals one, the object fires a bang from its outlet. The equation accepts another condition using the form “else” following “then”
e.g. [if $i1 == 1 then bang else 0]
I immediately realized that this was the way to go, as it allowed me to filter the input value and activate/deactivate steps accordingly:
e.g. [if $i1 == 1 then 1 else 0]; whenever the input value equals 1, the toggle turns on; whenever the input number is not 1, the toggle turns off.
NUTS AND BOLTS
If you have spent some time coding, you certainly know the difference between reality and the plans we make up in our head. Personally, I tend to conceive while sweating in bed during the night and then I face the crude reality during the day.
So, what is the big issue here? Well, conditional equations present two main problems:
1. Writing compound statements, such as a combination of two or more simple statements
2. Dealing with compound statements/various statements at the same time
The first point was pretty easy to solve, as I found a short video that made everything much clearer. Finding out that I can state “or” in the equation, paved the way to the first system. The syntax used to state “or” is “||”, that translates into:
[if $i1 == 1 then 1 else 0 || $i2 == 2 then 1 else 0]
Now, let’s consider such an equation to find out why my first system didn’t work properly.
In this case:
– whenever the incoming value in the first inlet equals 1, a 1 is produced turning the toggle on
– whenever such an inlet receives a value different from one, a zero is produced turning the toggle off
– whenever the incoming value in the second inlet equals 2, a 1 is output causing the toggle to turn on
– whenever such an inlet receives a value different from two, a zero is produced turning the toggle off
This works fine when we got two separate toggles to turn on/off, but what happens when the toggle in question is the same? The 0 produced by the first statement wins over the 1 produced by the second one, thus causing the toggle to stay non active.
This is a big problem, since it is common that the same step must stay active in various cases as reported in the following example:
e.g. Input Value = 4 Pulses —> Step 5 = Active
= 5 Pulses —> Step 5 = Active
With such a system, Step 5 turns on when “4 Pulses” is selected, but it doesn’t when “5 Pulses” is selected. It is at this point, that gates came into play.
THE ROLE OF “GATE”
My mind went immediately to gates. The “gate” is a very simple object that takes an incoming message/value/data to be gated; “gate” can be closed or opened through a 0/1 input in its cold inlet (0 = Gate closed; 1 = Gate open).
With these thoughts in mind, I said to myself: “if I impede the 0 to reach its target toggle, I should be able to overcome the issue”. Once again, that worked in theory but not quite in practice. When the gate is open the 0 wins over the 1; while when it is closed, the toggle doesn’t even turn off anymore because it doesn’t receive the 0 signal.
Despite having failed in this particular scenario, “gate” remained one of the focal points of the patch’s development, as I used it in several situations to filter specific messages.
GETTING TO THE FINAL VERSION
After days of troubleshooting, I finally came up with the winning system to manage the pulse generation and distribution. The solution was revealed to me while checking a patch that I programmed last year, allowing serial communication between Arduino and Max/Msp.
While going through the patch, I noticed that I used an object called “zl”, which can perform various list processing functions depending on the mode set. In this case, I used the mode “nth”; “zl.nth” is able to separate the elements of a group, thus allowing the user to route them to different destinations:
e.g. [list = 1 3 5 7]
“zl.nth” is able to extract the number to extrapolate and output it from its outlet. This is possible when specifying the number’s position in the list:
e.g. [list = 1 3 5 7] “zl.nth 3″ outputs a 5, as it is the third element in the list
Afterwards, I also found out that I could insert the list of active steps into conditional equations directly
e.g. [if $i1 == 4 then 1 5 9 13 else 0]
such a list is then fed into a message box’s right inlet, thus allowing me to work with a variable source of numbers. The input list changes accordingly to the “Pulse Number” set. The group of numbers in the message box is then decoded by 16 “zl.nth” objects, that handle the step distribution. This way, there are no zeros impeding multiple steps’ activation.
That’s all for today, further info on the development of my project will follow in the next post!