I have written previously about my decision to use an off-the-shelf box of MIDI buttons to serve as stop control. The MIDIfighter 3D sends MIDI notes as its data output. It also can receive MIDI notes, with different velocities indicating to the unit what color it should make the rings around each button. When the MIDIfighter receives a note-on, this overrides whatever the normal “off” setting is for each ring, and persists until it receives a note-off message.
In this way it is possible for me to preset the MIDIfighter with my own color scheme to organize the buttons. I can use a color for couplers, a different one for combinations, something for individual stops, etc. Then, when I select one by pushing a button, I can use Max to generate a Note-On message with appropriate velocity to provide a visual indication of what is selected. When I push the button again or “retire the stop”, then Max will send a Note-Off message, returning the button to its default color. In the world of virtual organs – this is something that not all sample sets support in Hauptwerk. With the proper Max patch, the DSO will have lighted pistons!
With this patch, I learned a number of new things about Max, particularly about its internal order of operations, which are quite important in the signal flow of this patch. At the very top of the patch, I use the “notein” object to only take note data from the MIDIfighter – it can also send out CC data due to accelerometers in it on two axis, but I don’t want that data. The “stripnote” object ensures that I only see note-on messages – it tosses note-off objects on the floor. This is perfect, because I only need the note-ons, and will generate the note-offs myself in the rest of the patch. I actually only need the note-number, which is why I only use the leftmost outlet of this object. The integer box is just so I can see what is happening, and the “clear” message zero’s the array for debugging when clicked – in normal use it does nothing.
The real action depends on the next two boxes – the “table” object and the “value” object. I knew there had to be the equivalent of a traditional array in Max, just like every other language, and sure enough, that is what the table object is. It defaults to having 128 rows, which is perfect for receiving note values. By default the table is all 0’s, which is perfect. I have 64 possible note values, spread across 4 “pages” of the MIDIfighter’s buttons. By giving the table a name, it becomes globally referenceable in the patch, which we will need to make this work. The “value” object serves to create a global variable named notenum that I can reference later.
The actual program logic works as follows:
1. Take the note number and look it up in the buttons table.
2. If that value is “0”, then we currently “Off” and need to turn “On”
a) set the value in buttons to “1” to indicate that we are “on”
b) send the appropriate MIDI note to the MIDIfighter to change the ring color
3. If the value is “1”, then we are already “On”, and need to turn “OFF”
a) set the value in buttons to “0” to indicate that we are “off”
b) send the appropriate MIDI note-off to the MIDIfighter to change the ring color back to default
It is a very simple state machine, with the state held in an array.
The order of operations becomes very important throughout the bottom portion of the patch, and things are lined up left-to-right in a very intentionally. Execution is from right-to-left and then depth-before breadth. So for the “table buttons” objects, they execute when triggered by their Left inlet. That means that I need to have the value I want to set at the right inlet BEFORE the notenumber triggers the table insert operation. Max is an interesting language. A lot of the function of objects is built into the order and inlets of the object. Reading the documentation is mandatory for sorting out how to get the results you wish. This same logic applies to the “noteout” object at the very bottom of the patch. It receives data right to left, so that when it finally gets the notenumber input on its left-most inlet, it has everything it needs to form the note correctly and send it out to the MIDIfighter.
So this was a fun little exercise. I had a bit of logic debugging to fully understand the order of operations as applied to the objects I was using, but in the end I learned several things: how to use arrays, how to declare and use global variables, that the “if…then” statement could directly output a gate or “bang” as Max calls it.
The lighting part was the trickiest part. I now have button state held in a global array, so it should be trivial to use this state to open and close ranks, send MIDI panics, etc. We’ll be getting to those as the project progresses and the console comes to life! These LED rings become more visible the less stage light there is, and so will be viable in all lighting conditions.
Future work will involve choosing a final color scheme and then adding logic so that the “off” and “on” colors correspond to brighter and dimmer versions of the same color across all 64 buttons. I will leave un-used buttons completely dark so they are not confusing. Some buttons, like the general cancel and MIDI panic buttons will not be latching, and will need to be filtered out before this logic takes place. All of that is simple work that will easily build on top of this foundation.
Last post we looked at creating super and sub-octave couplers in Max for the DSO. In this post, we will see how easy it is to couple divisions of the DSO together.
In a pipe organ, each division of the organ is controlled by a particular keyboard. Said backwards, each keyboard controls a particular roomful of pipes! The pipes that are controlled by a given keyboard are literally not connected to the other keyboards or pedalboard! In practice, this is not as limiting as it seems. Each division is supposed to be furnished with a complete and useful set of stops. By having different characteristics on each manual, a wide range of expression can be realized.
Divisional couplers multiply the possibilities exponentially. A divisional coupler allows one to take all the stops currently pulled on one division, and play them from another division’s keyboard. For example, if I engaged a “Great-to-Pedal” coupler, then I could play the stops of the Great division of the organ from the pedalboard. A “Pedal-to-Great” coupler would allow me to play the pedal stops from the keyboard of the Great division. Very handy!
Now, it is obvious that in a MIDI virtual world that there are no chambers full of pipes, no wind chests, and no divisions. Any sound could be played from anywhere. I have chosen to preserve the idea because the divisions also serve an organizational and tonal purpose. Given that the DSO will have 50-70 stops when it is complete, it is necessary to have them organized by some principle. By making each division of the organization complete, with a range of tonal color, but a certain “bent”, each division can stand alone for polyphonic playing. “Color” stops, like the reed voices of a organ can often be added to a completely different division to create new textures and timbres. I can easily have Max remember the most useful combinations for me as dedicated global pistons. This same idea is common on new electronic actions, and has been for many decades now. So, I will use divisions as a way to organize and tonally shade my sounds, and then still have the ability to create global combinations of interest.
So, on to getting this done in Max. Because of my model of having the MIDI note data act as “wind pressure” behind the stops,it is easy to access all the note data coming from a keyboard or the pedalboard – whether one channel or many like the Seaboard.
That raw flow of notes from the pedalboard is coming into the “midifomat” object at the top left and applies “pressure” to the pink inlet of the switch. When I press the assigned toe piston on the pedalboard, it generates a CC message that flips the toggle beside the “midiformat”, and opens the switch. That note data then flows to each rank in the Great division. Any stops that are pulled allow that note information to flow on to the sound source for that rank. In the picture above, that would be the third stop of the Great organ (the toggle is selected). The pedalboard will now play whatever I select, or stop playing whatever I de-select on the Great. As soon as I retire the coupler, the note data is held up at the switch, and the pedal division returns to playing only its own ranks.
This is an easy coupler to build in Max, as you can see, but very powerful artistically. When I add a second manual, I will add a Swell-to-Pedal coupler to gain access to those stops as well.
I chose for my organ console to only couple the actual notes played on the pedal board. It would be trivial for me to instead couple the played notes plus the super/sub-octave couplers. I chose to keep those confined to the pedal division. In some cases, I will want to couple the sounds of the Great division so that the pedals play the bass sound that matches the manuals. My hands will be playing the upper voices, so I don’t need a super octave from the pedals playing up underneath my hands – I want to play just the bass notes. If I want the super/sub-octave on the Great, I can get it by just engaging the super/sub-octave couplers on the great, and then with some creative routing, I can play the pedals and get the super/sub octave happening on the Great.
Max makes even complex signal flow and logic very easy to follow. I am still using it within the trial period, but there is no doubt that Max will become a permanent part of my tool kit. It is very useful.
Some of the most useful couplers on an organ are the Super and Sub Octave couplers. They add the octave above and below the note you are playing across all the stops you have pulled on that division. So, if both are pulled, it triples the notes played. Of course, they can also be used individually. They work wonders to fatten or clarify a bass line, or to emphasize full tutti melodies, where just like an orchestra, you want all attention on a particular melodic line.
In a real organ, this is either programming inside the electronics, or a lot of complexity on a tracker instrument. For me, on the DSO, it turns out to be very easy to accomplish. Because I have the MIDI notes split out from the control data as soon as they enter my console patch, all I have to do is make a switch and then add or subtract 12 from whatever the note number is. I need to leave the velocities alone so that I get crisp “Note-On” and “Note-Off” messages from each.
This portion of my console patch shows the logic clearly. The green lines show the flow of MIDI note data. The purple is the “bang” or gate signal from the control logic. The MIDI notes played on the pedalboard provide constant “pressure” on the pink inlet of the switches. When CC24 127 is received from me pushing a toe piston, this creates a “bang” or gate signal that flips the state of the toggle and sends the gate signal on to the blue control input of the switches. This lets the MIDI note numbers and velocities through the switches. After the appropriate +12 is done to the note number, the note-number and velocity are re-packed and inserted into the note stream headed to the pedal ranks. Because the MIDI data straight from the pedal board is also present at the “midiformat” object at the bottom of the picture, I get the note and the super-octave. Using this setup, I can generate three Note-On or Note-Off messages for every note played on the pedalboard, for every stop that is pulled – true super and sub-octave couplers! Toggling CC24 by pressing the toe piston again reverses the process and closes the switches, removing the coupler from the chain.
When I have my stop system in place for the manuals, they will also get this same logic. All this took perhaps 15-20 minutes to sort out. Max is easy and fast.
———-Geeky Max Learning below ———————
Why are there two switches? Because there are note-on and off messages, I can’t switch just the note number – I also have to switch the corresponding velocity. If I don’t switch them together, then I could get into a situation where a note is sounding, but I take the switch off before the note-off, and then I’d have a hung note!
Why use “pack” and not “pak”? Pak creates a data at its output every time ANY of its inputs changes. When I tried that, I was getting up to three copies of each note due to varying arrival times of the velocity vs the note number! Changing this to “pack” instantly solved the problem. It only generates output when it receives a new note-number. Because Max executes right to left, the correct velocity is already waiting on the right input of the “pack” object.
Updated Jan. 10, 2015:
Jim Self on a Google+ conversation noticed that there was a cleaner way to do the couplers in that I was using two switches where I only needed one. The new coupler is shown on the left, the old on the right. I will update my Max patch so that both couplers are of the new design. It is always great to have code be as clean and efficient as possible. Many thanks to Jim for his observation! I’ve tested both ways and both work, so why not go with the simplest solution? In this case, less is more!
A large measure of the expressiveness of a pipe organ comes from creative registration (i.e. what stops you select and how you combine them). While the DSO is fully touch and pressure sensitive, pipe organs are not this way. This means that console features are very important to controlling the sound. I have chosen to incorporate most of those ideas into the initial build of the DSO.
Because I have the pedalboard completed, it is the first surface that I have fully set up in Max.
This Max patch makes every signal that the pedalboard provides available in a useful fashion. Starting from the top, the full output of the pedalboard arrives at an external MIDI port on my system. It hits a “midiparser” object that splits out the control and note data into separate stream.
The note data flows directly to the switches just above the pedal ranks, providing constant “pressure” that will flow the note data wherever the switches are open. In this way, one note can play simultaneously on all ranks, just like a pipe organ.
The control data passes as CC messages to the twenty “ctlin” objects (gold lines). Each is listening to a particular MIDI CC number that corresponds to a physical toe piston switch on my pedalboard. The three continuous pedal inputs are in the center between the rows of toe pistons. Each CC message contains the CC number, CC value, and MIDI channel. What I want is a simple state transition between 0 and 127 and back. Each button push generates a 127, and its release a 0. This is 2x the data I need. Enter the “togedge” object. It transitions only to and from 127, so each push of the toe piston reverses the signal. This provides the desired gate signal (or “bang” in Max-speak) that can operate the toggles and the switches controlling the note flow. The gate signals are shown in purple.
I am especially enjoying the fact that Max lets me think of the note and CC data as a “wind stream” or “flow” that behaves just like air or water would under pressure. It has made it very easy for me to manipulate the MIDI data and add features to my console. In the days ahead we will look at my implementation of super and sub-octave couplers and divisional couplers – both ideas absorbed from traditional console design. The rich data from the Seaboard is in blue. This data is multi-channel, with continuous aftertouch and pitch information per note. I wanted a different color to distinguish these flows from the simple note-on/note-off flows that come from the pedalboard. Like a pipe organ, my pedalboard is not velocity or touch sensitive. The ability to use color certainly makes it easy to keep a Max Patch organized and clean.
You can see that the continuous pedals are not yet wired into the ranks. Ultimately they will be connected to provide volume control for two manuals and the third will provide a programmed crescendo pedal once I get all the synth programming done. For now, it is enough that they are understood, parsed, and sitting waiting for me to connect them as I please.
I have known about Cycling’74’s Max language for some time, but avoided it. While I’ve done scripting in Ruby and Perl, I’ve always had a “no programming near my music” attitude. Maybe because my day job is so technical, I’ve wanted the music separate, I don’t know. It wasn’t a closely examined position to be sure.
At some point on a special, I upgraded Ableton license to have Max for Live, and I installed some of the pre-done modules, but never really did much with it.
As I’ve been playing with the Seaboard, I realized that most music applications are geared to consider an input as “one MIDI channel”, and to steer data in that way. Being of a bent towards pipe organs, both Hauptwerk and jOrgan work this way. A “manual” is a MIDI keyboard set to a particular channel. Clearly this was not going to work for me.
I have also used Apple’s MainStage for several years for a live rig that I play at church. This hosts all my soft synths, allows for easy set creation and quite flexible signal routing. It is not the most efficient application in the world, however, and its “one CPU core per channel strip” is often not what is needed or wanted on a modern quad-core MacBookPro. Particularly with “Poly-Thru” patches where the Roli app is hosting 5-10 plugins, this just doesn’t scale well.
I remembered that I had PD extended on my laptop and took a quick look at it. It is written by the same gentlemen that wrote Max originally, and works in much the same way. There are plenty of tools for MIDI work, but there still seemed to be a desire to filter things on output to a single MIDI channel. I suspect that could be gotten around, but it was clear that PD is focused on different applications primarily, so I went to Max.
I knew from previous explorations that Max for Live would not work because it is designed to operate inside an Ableton channel. I want my organ to be able to access 50-75 “stops” – each of which may be a soft-synth, sampler, or external MIDI connection to a real hardware synth like the Bowen Solaris. A single channel is not going to work, so I downloaded the full version of Max.
Within minutes I had the Seaboard MIDI input routed to a virtual MIDI port and on to an Absynth instance hosted in Vienna Ensemble Pro (VEP). This worked brilliantly and CPU usage was negligible. I wasn’t asking MAX to do much, and it responded by pretty much ignoring CPU. Fast, intuitive, and easy.
VEP is the heart of most media composers studios. It is the best way to hook multiple computers together to freely interchange MIDI and audio across a Gigabit Ethernet network. I have a small D-Link switch in my office just for this purpose. The VEP traffic runs across a separate VLAN and connects three computers. It just works, and it works at scale. On my Mac Pro, I regularly host 58-63GB of samples spread across 9 instances of VEP and 30+ Kontakt instances. I know it performs, and it is well-known for handling multi-processing issues well on large templates. My main orchestral template in Cubase is ~640 tracks – almost all of which are hosted through VEP instances on two slave computers.
Looking at the built-in MIDI processing functions, I quickly surmised that I could do exactly what I wanted to inside Max. I could build handling and logic for all the console functions of my organ project, and easily route all the channels from the Seaboard to any output. I would use VEP to host the synths. Max is easy and powerful. I had intended to ultimately learn enough to control DMX lights at some point, so that cemented it – Max would be my signal routing and console creation tool for the Digital Synthesis Organ.
It didn’t take long playing with it before a number of other possibilities for rig control and even composing tools started to take form in my head. It is really true that once you can program the world seems like a much more elastic place. I told my father-in-law, who is a master woodworker, that I was starting to “make jigs for my shop” and could now make my own audio and video tools. He remarked that I have the musical equivalent of a Bridgeport metal milling machine – the only tool that can make itself.