Max piece construction techniques


    Apr 01 2006 | 6:01 pm
    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.
    Peter McCulloch
    Performance:
    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 operator.
    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 expected better.
    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 rule.
    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, type
    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.
    Programming:
    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 background.
    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 it.
    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.