Max piece construction techniques
This is by no means exhaustive, but these are some things that I have
found useful over the years, and I am indebted those who showed me some
of these. These are for pieces that are through-composed, so they
definitely won’t apply in all cases. I’ll be curious to hear your
comments, opinions, refutations, etc.
The patch should be as simple to operate as possible. If you’re only
advancing through cues, they should be operable from the computer
keyboard. Do not ask the computer operator to click through cue
numbers as it is easy to miss, and it forces the operator to focus on
the screen instead of the music. Spacebar is large and hard to miss
for advancing cues. Also, if it will be someone other than you
operating the computer part (and without much rehearsal) do not ask the
operator to do things that are awkward. I ran a piece that asked the
computer operator to follow pedalling indications with the spacebar
while clicking through very small messageboxes containing cue numbers,
which left me with no hands free to turn pages or ride the mixer.
Instead of having separate tasks, make them smaller tasks. So instead
of "pedalling" to record into a long delay loop, have two cues, one for
starting, and one for stopping. It’s much easier to time for the
In addition to performance, your cues system should have some rehearsal
algorithms built-in. Not necessarily that you should be able to skip
around at random (though that would be helpful creatively), but
moreover that if the piece begins with a two-minute soundfile, when you
skip ahead, you should either skip ahead in the soundfile, or simply
mute it, rather than having to wait two minutes for it to finish.
Could even be as simple as having a button that stops all soundfiles
that are playing. A "Panic" setting also can be a good thing, as it
allows you a safe way of muting everything, before you rewind, etc. I
use a big message box with sends at the beginning of each main section
that will get everything set appropriately.
There’s a strong chance that you’ll get the same 20-30 minute long
sound check that the guy with the tape piece will. It’s not fair, but
it seems to happen a lot, so plan for it by making your interface/setup
as monkeyproof as possible. Starting the piece should be simple and
fast, and you shouldn’t have to remember to open patcher x and click on
three things in a specific order. (that’s what trigger is for…) Be
able to do a full reset of your patch WITHOUT having to reload it: use
the universal object in the top-level patcher to make loadbang and
loadmess reload where necessary. Being able to skip around in the
patch saves valuable rehearsal time and allows you to test the parts
that may present the most issues. Try to find out in advance whether
you’re dealing with a digital or analog mixer, and, if possible, about
the experience of the engineer. Inexperienced engineer + fancy
unfamiliar digital board with complicated setup = bring a small analog
mixer as backup; you may be thankful. I’ve seen this equation play out
very badly before at a national conference where you would have
Prepare for different performance spaces. That long reverb may sound
great in a small room, but may just be too soupy in a large room.
Having a trim on these type of processes (i.e. reverb time trimmed to
-1 sec.) can help you quickly adapt without having to edit cues.
Feedback delays are a particular candidate for this. You also don’t
have to do it multiplicatively; you could use a clip 0 0.95 before the
feedback coeff. Vary the rightmost inlet to set the maximum amount of
feedback gain, while preserving the lower values. You should have easy
access to these trim values in case you have to compensate in the
middle of the performance. Maintaining a list of values that have
worked in the past can suggest patterns for usage. (these values seem
to work in big spaces, these seem to work in small spaces)
In performance, do not route the dry audio through your patch. (unless
you have a strong musical reason for doing so) Use a prefader aux send
into your computer. This way, the computer always sees a consistent
level, and you can control the mix of the live instrument
independently. Having a physical fader is always more useful in
performance than having a virtual fader because you don’t have to mouse
for it. I’ve seen a lot of disasters happen by not following this
Have a way of easily testing your audio output. In my stereo patches,
I have a test-sound player that loops a soundfile that plays different
pitches in the right and left channels. (Make sure that the soundfile,
etc. roughly conforms to the dynamics of your piece) This allows you to
test output, set levels, and ensure that panning is correct all in one.
If you’re working with a performer, have a way of providing a tuning
note. You could do it via the built-in synth, etc.; don’t assume that
there will be a piano, etc. where you’re going to perform. (or that
it will be in tune!)
Have easy ways of recording the input and output of your patches. If
you record the input, then you can use it later for testing purposes
when the performer is not around, or when you’re not in the performance
space. Also, it makes it much easier to put together a recording.
Having multiple recordings of the input makes it easier to stress test
the patch. You might want to do some routines on the dac~ so that it
shuts off recording before you shut off audio. (sel 0, trigger 0 0)
Higher bit rates may be an especially good idea…
If you’re using qlist, try this trick: If you want to add a comment,
COMMENT This is adjusting the delay-time;
then add a receive COMMENT with a gate and send it to print. Very
useful for troubleshooting. I use an additional one called CUEACTION
(or something like that) to describe what goes on in that cue. It
helps in performance, because I can see what’s supposed to be
happening, so I know if part of a cue isn’t firing correctly.
Controlling the inputs and outputs of a process is almost as important
as the process itself, so envelopes, or even just the ability to easily
bypass the process can be very useful. Processes that are always on
chew up sonic space and lead to a reduction in information. (things
that always move together become perceptually grouped under Gestalt
theory) I also use spatialization to move processes from foreground to
Gain control is one of the most important things in ensuring consistent
performances. Making sure that signal-processing parts of the patch
see the same approximate signal levels each time you run the patch
helps you to assure a good blend with synthetic components and
soundfiles. Adding a volume meter with a target level in the main
patch is a good step towards this. (specify the note(s) that this
should target; i.e. the fortississimo high C instead of the
mezzoforte F#) I’m working on developing some calibration routines
that will try to do this automatically. Use peak in combination with
meter~ to keep track of the loudest incoming (and outgoing) amplitude
so that you can trim accordingly. Generally speaking, I’ve found it’s
more effective to have performers play the loudest part of the piece
while you’re setting levels than to ask them to play their loudest
note, because they’ll tend to underestimate.
Modules should have multiple levels of gain control. You should be
able to access it in an on/off fashion, but also variable, and having
an additional trim component to this all is extraordinarily helpful. I
use a toggle, floatbox, bondo, * 1. combo for this. There should be
mute/unmute subroutines so that the module cleanly enters/exits the
mute state without clicks. I use matrix~ 1 1 0. for this. (sending it
0 0 $1 100, etc.) It’s musically advantageous to be able to turn
on/off the input without doing the same for the output.
If you have a very prominent feedback delay part of the patch, have a
way of clearing the input, or at least quickly reducing the amount of
feedback should an undesirable sound get stuck. It’s very important
to use an envelope to control the input, needless to say.
Otherwise that one click turns into
click…….click…..click…..click…..click…..click… . And
high-frequency feedback…eeeee…. A clip~ on the output, or
somewhere in the chain, can be a very practical thing.
Matrix mixers can provide a lot of sonic variety. Having access to
multiple delay units as part of the chain can make the other processes
more interesting. Also, WHERE you listen in the process can be very
important. Think also about the way that mixers work, what with using
aux sends, etc. on processes. You might not need a full-blown matrix~;
I’ve seen very elegant solutions done with poly~ and changing the
targets of send~ and receive~ objects.
Spatialization can be very effective as a means of density control. If
you use two reverbs instead of one, you can create nice effects like
sounds moving off into the distance on the left, right, etc. With a
little bit of lowpass filtering, and adjusting the wet/dry ratios on
the signal, you can build a pretty decent spatializer, which will add a
lot of depth to the sound. (though I like multi-channel, it’s
surprising what you can get out of stereo) Spatial crescendos have
much more impact than just amplitude crescendos. Also, as an interface
thing, considering x/y separate from distance can allow you to build
things that are musically interesting, though perhaps less perceptually
accurate. (such as a loud sound that’s moving from speaker to speaker,
or a very distant sound that’s in all speakers equally)
Stability versus speed: some things that save CPU can also be less
stable, so be sure to stress test them to make sure. Oftentimes people
try to do things at the control-rate (such as LFOs) to save CPU, and
this works to a certain point, but after that you tend to get into
diminished returns. (especially if you’re having to interpolate lots
of values) CPU spikes from a flood of control-rate data can bog down a
patch, too; generally speaking, the audio rate is much more stable
because it generally runs at the same speed. Vexpr is a great way of
streamlining mixing/spatialization tasks. Also, once you’re doing a
lot of audio processing, the control-rate can be less dependable
timing-wise. (unless you’re using audio interrupt, but there’s more
overhead for that)
Sometimes processes can be more or less functionally equivalent.
Having a reverb before a filter bank may work the same as that huge
filter bank you were trying to use, or if you’re using a bunch of
detunings, see how much different a chorus on the output is from what
you’re getting. I use pcontrol for doing muting/unmuting, and have
found it to be very dependable, but there are lots of other ways to do
omx.4band~ can be very useful at the final output stage.
Trigger is really important to use to control the order of control-rate
processes. As a general rule of thumb, if I’m sending one value to
multiple places, I use trigger to ensure that regardless of how things
get moved around, the order is preserved, and this goes double when
dealing with send and receives.
A very soft ping-pong delay, particularly on synthetic processes, can
be very helpful at adding depth to the sound. If you use a windowed
delay, you can change the values over time with a metro and a drunk;
this keeps it from getting too predictable. This is also a great trick
for thickening up a granular sound.
A high-shelf filter using biquad~ can change the color of a sound
significantly by functioning like a lowpass or high-boost.
Ranges of values are more interesting than singular values for almost
anything, and rand~ is great for this.
If you use fiddle~, use a poly~ to wrap it. That way you can run it at
its desired vector size of 64, and run the rest of the patch at
whatever vector size you want. (I use 256, just because I’m on an
older machine and trying to wring as much as I can out of it)
Preset systems are good, but are not necessarily musical. Sometimes
just changing a few values at a time via a mapping process can be very
effective, and your preset system should be flexible enough to
accomodate this where practical. Having a way of naming presets can be
very useful as a reminder as to what they do. Having multiple ways of
accessing the same value is a good idea. i.e. a global receive and a
local receive would allow you to set all the filter Q’s, or just the
one filter Q.
Rigorously stress-test your patch. Leave it running overnight, try
unexpected inputs, etc. Do anything you can to simulate performance
conditions. (sometimes I’ll add a little bit of the output back into
the input to test it for microphone bleed)
It’s good policy to name all your abstractions such that they begin
with a unique identifier. (mine all start with PM.) Otherwise, if you
send the patch to someone, they may have a different patch with the
same name and havoc ensues… Eventually, if you’re going to send it
out, it’s probably a good idea to consolidate abstractions into
patchers where possible, so that there’s a minimum of "which patch?"
and less potential for naming conflicts.
Envelope followers can be great for mapping, particularly if you add a
layer of abstraction to them, by having them control the speed of a
rand~, cycle~, etc., or even just delaying them by a few seconds.
Also, independent amplitude LFOs can be surprisingly effective when
combining synthetic sounds.
lot of useful info and tricks… especially for a newbie.. :) thanks for sharing them
Thank you for sharring… lotsa usefull info !
Jamona implements most of this very well
Forums > MaxMSP