Max 5 Guitar Processor, Part 4

    At this point, we have a pretty useful guitar processing "rack", but it could use a little spice. This spice will come from two additional processors: a looping delay unit, and a basic reverb system. Also, to help keep the output useful, we will drop a limiter on the back end of the entire rig.
    Download the patch used in this tutorial.

    Tutorials in this series:

    Looping Delay

    The first processor we will add is an alternative version of the delay line – one that provides tap tempo, looping and sound-on-sound functionality. Unlike our previous delay module, this one will not provide modulation (for flanging and pitch shifting effects); rather it will be focused on capturing a loop, and allowing overdubs of additional sounds.
    As with any delay line, the most important setting is the delay time. We use a standard floating-point number box for entry, but it is probably most convenient to use the "tap tempo" function that is implemented. By clicking on the tap tempo button four times, you generate a delay time that will match your taps.
    The tap tempo function is provided by the taptempo abstraction at the top level of the patch. It counts four incoming bang messages, determines the three intervals between the taps, takes the average and uses that for the tempo calculation. Since it is assumed that we are tapping quarter notes, but want to use a four bar measure, the result is multiplied by four to give us a delay time value. This is an area where you might want to modify the function to meet your needs – if you really want to have the delay run at the rate you tapped, you can remove the [* 4] object at the end of the processing chain.
    The basic delay design, as found in the loop_handler subpatcher, is very similar to the layout of the modulating delay. The few tweaks provided are there to support the looping functions. First, when the "Freeze" button is "on", the feedback is switched to 100% feedback. This gives us a standard looping function. The feedback loop has a lowpass filter in it, which will change the audio in the loop if it is not fully open. The "Input Active" button is very important – it determines if the input signal is sent into the delay path. If it is off, the only output of the delay line is whatever is currently playing – if the delay is "frozen", you will hear the loop, while with freeze off you will only hear the remaining contents of the loop line feedback. What is cool about this is that, when you freeze the delay line, you can still overlay audio parts onto the loop – giving you sound-on-sound overdubbing.
    I've also implemented a click track that cycles at the same speed as the delay time. This way, if you want to work up some one-bar loops, you can hear the timing (in quarter note click) even before you begin recording. Most of these concepts are classic delay techniques, but this sort of looping processor is exactly why many people first get into Max/MSP. Even if you aren't into guitar processing per se, you may find this looping delay system can jump-start your Max experiments.


    What would an effects processing rig be without a reverb? As is typical for any processing rack, I've installed a reverb as the last effect in the system – this way, we will get consistant reverb from both our looped and our live guitar lines. To provide reverb, I've gone to a third-party external object: Nathan Wolek's gverb~. I happen to like the sound of it well enough, and I've wrapped it up in another abstraction so I can replace it in the future (if I decide to do that).
    If you look into the subpatcher reverb_handler, you'll see that I expose the reverb time control to the top-level patch, but I also provide a reverb mix control that uses the pan2 abstraction found in Max's examples folder. This gives me a decent equal power pan – but why would I need to pan? In fact, I don't; but I can use them as equal power mixers as well. By using only one output of the panner, and reverse panning the live sound, I can get a decent mixing function will little effort. This may not be the most efficient processing stream, but it sure was easy to implement!

    And a Limiter at the end…

    Finally, to make sure everything stays under control, I've added a limiter to the end of the processing chain. I'm using the omx.peaklim~ object, which implements a good quality limiter. The parameters for this object are a little weird, so after some experimenting, I found a set that worked for me. These are loadbang'd into the object during startup, and never change. I also reconfigured the output section of the Presentation Mode to make everything fit a little better, but the functionality should all be familiar from previous weeks' articles.


    This is the conclusion of new module additions, but far from the conclusion of this series. For my money, some of the most important information will be found in our next article, where we will cover preset management ('cuz I don't want to be mousing too much on-stage) and MIDI parameter controls (using my FCB-1010 foot controller). Get familiar with our new modules, and prepare for a big finale with our next Guitar Processing entry!

    • Feb 08 2010 | 11:25 pm
      Hey I built this into M4L and it works sweet :) A great place to start! However the cpu goes almost to the roof when i stop playing... Any ideas why? I'd be happy to share my m4l version of course.
    • Feb 09 2010 | 5:13 am
      Have you kept up with your Live and MFL updates? There were some early problems with CPU spiking then. Also, you may want to try removing parts to see if there are problems. That back-end limiter is one that I might be concerned with. In any case, what you are seeing is a bug, and a little testing on your end might help us come up with a reasonable fix. If you find something, you can shoot me some direct email at
    • Apr 22 2012 | 9:54 am
      For this looping delay, is there any way you could change it so the loop collects 4 bars of audio rather than just one bar? I'm new to max, sorry!
    • Apr 24 2012 | 10:35 am
      If you change the [* 4.] object to a [* 16.], it should give you 4 bars of audio in the loop