The third installment in the inVeSTigations series added effects crossfading to our VST instrument/audio effect hosting possibilities, and demonstrated the use of the disable message that lets us load an effect and save on CPU cycles.
Just as a reminder, here's our patch:
By now, you've probably noticed something - while it's true that I'm leaving a lot of space and trying to carefully lay out the Max patches I'm including in these tutorials, the patches themselves are getting a bit complicated, and it's probably getting a little harder for you to see what a new thing I've added as we've gone along does.
If you're particularly clever, you might also have noticed that there's some commonality between the various versions of the patches I've included so far. If you continue on The Way That is Max for any length of time and actually decide to free yourself from the cycle of dependency that is often the lot of new users (asking others for their patches rather than doing your own programming and making a whole new patch for every single project you undertake are two symptoms of this mode of existence), you'll not only recognize this commonality, but begin to use it to your advantage. In this tutorial, we'll add some interesting new bells and whistles to VST hosting and take a look at how you can begin to visually simplify your Max patches, even as they become more complex.
Subpatches and Abstractions
The easiest way to think about making subpatches is intimately connected to a general approach to Max programming: thinking about messages.. One of Peter Elsea's interesting Max Tutorials describes this in detail
- What UI objects or input sources do you want to use in your patch?
- What kind of audio or video things to you want to happen?
- What's the output from the UI/input stuff look like?
- What kinds of messages do your audio/video objects/patches expect receive?
To quote Peter's tutorial Max and Problems, "You are either gathering messages from the world, making changes in the messages, or creating output."
That's a deep and subtle insight, and one we can use to help simplify this patch.
A little investigation of the patch in terms of inputs and outputs suggests a couple of features:
- Both VST plug-ins take their audio input from the same source
- Both VST plug-ins send their outputs to the same destination
- The logic used to mix plug-in output uses a single input (the hslider object)
You might also notice that although the messages used to load the VST plug-in are the same (the plug message, they're routed to different inputs.
We can rewrite our patch to simplify it in one of two ways; we can move a part of the patch into a subpatch, which would simplify the patch itself. Once we've created the subpatch, we can duplicate it and work with multiple versions of a set of crossfadable VST plug-ins. Here's what the patch would look like:
That's great, but we can also save the subpatch as an abstraction. If we save it in a folder that's in Max's search path (such as the patches folder located in the Max/MSP applications folder), we can load the abstraction by simply typing its name into an empty Max object box, just as if it were a Max external object.
While using subpatches cleans things up, saving a subpatch as an abstraction is better - we are creating Max patches we can use again and again, and our life with Max becomes a matter of creating reusable abstractions that will let us work more quickly and efficiently in the future. If we save the subpatch into the patches folder and give it a name (in this example, we'll call the saved abstraction twoplugs), we can now type the name of our saved abstraction, and a new abstraction will be created that looks and acts exactly the same way as the subpatch. So here's what our patch looks like now:
What does this input do?
That's a lot simpler to work with, and it'll be nice to have the twoplugs abstractions in our folder. We can create as many sets of crossfadable plug-ins as we'd like, chain them together, and generally enjoy their reusability.
One of the things you'll notice pretty quickly when you start creating your own little Max widgets you can reuse is that you'll probably forget what the inlets and outlets for the abstraction do. You already know (or you should know, if you've read the Getting Started manual) that you can find our what an inlet for an external object does by positioning your cursor over and inlet or outlet and reading the lower left-hand corner of the patcher window.
You can create the same thing for the inlets in your abstraction by using the Inspector for the inlet and outlet objects. Select an inlet or outlet object and type Command-I (Macintosh) or Alt-I (Windows) to open the Inspector, and type in the assistance message for the inlet.
When you position your cursor over an inlet or outlet of your abstraction or patcher now, you'll see the message.
You may find it helpful to include information about the input range for input to an inlet for your abstractions. For example, the rightmost inlet to the twoplugs object accepts input from the hslider object - input in the range of 0-255. When you go to use this object next time, it'll be helpful to remind yourself of that using an assistance message.
Double your pleasure, double your fun
Using the twoplugs abstraction certainly makes our patch look a lot neater. Since we have so much blank space, we can use our abstraction again, and create a patch that's twice as interesting as what we started with:
What's going on here? Well, this patch uses two twoplugs abstractions running in parallel. And we're controlling them both using a single source - the pictslider. Each of the two axes of the pictslider object controls one pair of the VST plug-ins hosted by the vst~ object nestled inside the twoplugs abstraction. As was the case with the hslider version of the patch we used earlier, we can disable a plug-in by moving the pictslider object's button to each of the four corners, as follows:
- Top left corner: plug-in 1 inside the left twoplugs abstraction is disabled
- Top right corner: plug-in 2 inside the left twoplugs abstraction is disabled
- Bottom left corner: plug-in 1 inside the right twoplugs abstraction is disabled
- Bottom right corner: plug-in 2 inside the right twoplugs abstraction is disabled
The new patch also contains some other things that should be familiar from previous inVeSTigations tutorials, too. You'll find the midiin- midiparse-qs.vstizer set of Max objects we used in inVeSTigations part 2 to route MIDI data to VST instruments. So this means that we can load either audio plug-ins or VST instruments when using the twoplugs abstractions.
You'll also notice that the patch includes a set of the messages we used to load VST plug-ins (the plug message, and the message that lets us view the plug-in edit windows (the open message).
Enough talk: take some time and experiment with loading four VST instruments controlled from a single MIDI source and grid-mixed using the pictslider, or load a quartet of audio plug-ins. If you feel like some tinkering, you might want to replace the sfplay~ object with an adc~ object so you can work with live input, or (if you're feeling a little more ambitious) think about how you might reroute things so that one of the twoplugs abstractions contains VST instruments whose outputs are routed to the second twoplugs abstraction that would contain audio plug-ins....
If you look back at contents of the twoplugs abstraction, you'll notice that there are a few outlets that aren't connected to anything at all. Perhaps you can imagine what we'll be doing next time out if you take a look at inVeSTigations part 1.
As usual, you can download a ZIP file containing the tutorial patches here.