Interactive Art

Max/MSP From Zero: Objects, Cords, and the Right-to-Left Rule

The patching environment behind an enormous amount of installation and performance work. Here is a working patch in ten minutes, and the two rules that cause every beginner bug.

If you have been to an interactive installation in the last twenty years, there is a reasonable chance something in the room was running Max. It is the patching environment that a large part of the sound-art, live-electronics and media-installation world standardised on, and it has been in continuous development since Miller Puckette wrote the original at IRCAM in the mid-1980s.

It is also commercial, which is the honest first thing to say. Max is a Cycling ‘74 product with a paid licence and a 30-day trial, and its free sibling Pure Data — same author, same model — does much of the same work. We covered getting started with Pure Data a few days ago, and almost everything below transfers.

Oliver Thurley’s beginners’ guide — the most current long-form introduction, and worth the hour.

The three layers

People use “Max” loosely for what is really three things in one application:

  • Max — the control layer. Messages, numbers, lists, timing, MIDI, logic. Everything that happens at event rate.
  • MSP — the audio layer. Objects whose names end in ~. Signals at sample rate.
  • Jitter — the matrix/video/OpenGL layer. Objects whose names start with jit..

Plus two things worth knowing exist:

  • Gen (gen~, jit.gen) — compiles a sub-patch to efficient code, for per-sample DSP or per-pixel work that would be too slow as patched objects.
  • Max for Live — Max patches running as Ableton Live devices, which is how most people now encounter it.

The interface, in five keystrokes

KeyCreates
nObject box — the thing that does something
mMessage box — sends its contents when clicked
fNumber box (float); i for integer
bButton (bang)
tToggle

And the one that matters most: Cmd/Ctrl-E toggles edit mode and presentation/run mode.

In edit mode you place objects and drag cords; clicking does nothing. In run mode you click things and the patch responds; you cannot move anything. If your patch seems dead, you are in edit mode. Every single person loses ten minutes to this once.

Drag from an outlet (bottom edge) to an inlet (top edge) to connect. Cords carrying audio are striped; control cords are thin. You can see the two domains at a glance.

Your first patch: a sine wave with a volume you can ramp

Place four objects (press n, type the text, click empty canvas):

[cycle~ 440]
[*~ 0.]
[ezdac~]

and a message box (press m):

[0.2 20(

plus one more object:

[line~]

Connect:

  • cycle~ outlet → *~ left inlet
  • *~ outlet → ezdac~ left inlet
  • *~ outlet → ezdac~ right inlet
  • 0.2 20 message outlet → line~ left inlet
  • line~ outlet → *~ right inlet

Cmd-E to leave edit mode, click the ezdac~ speaker icon to turn audio on, then click the message box.

A 440Hz sine at 20% volume, faded in over 20 milliseconds.

[ezdac~] is the beginner-friendly output with a built-in on/off button. The grown-up version is [dac~], which has no button and needs audio started elsewhere.

Rule one: the tilde

Objects ending in ~ run at sample rate. Objects without it run at event rate.

  • [cycle~] outputs 44,100 numbers a second, continuously
  • [cycle] is a different object entirely (a list-stepper)
  • [+ ] and [+~ ] both exist and are not interchangeable
  • You cannot connect a signal outlet to a control inlet. Max refuses, and the refusal is information.

Crossing between domains is explicit: [sig~] makes a number into a constant signal, [snapshot~] samples a signal into a number, [line~] turns a message into a smooth ramp.

And [line~] is not optional. Send a bare number to [*~]’s right inlet and the volume jumps discontinuously — a discontinuity in an audio signal is a click. [0.2 20( means “ramp to 0.2 over 20 milliseconds,” and ramping is what stops your patch sounding broken. Nearly every click and pop in a beginner patch is a missing [line~].

Rule two: right to left

Max fires outlets right to left, depth first.

An object with three outlets sends out of the rightmost first, then the middle, then the left. And “depth first” means each message is followed all the way down its chain of connections before the next outlet fires.

This trips people up because the resulting bug is order-dependent and looks random. A value arrives at one inlet before another has been updated, so your calculation uses last frame’s number.

The fix is [trigger] (abbreviated [t]), which makes the order explicit:

[t b i]     ← sends the integer out the right outlet FIRST, then a bang out the left

So the idiom is: use [t] to send your data to the right and your trigger to the left, guaranteeing the data is in place before the bang asks for it.

Use [trigger] whenever order matters, and the problem never recurs. Patching without it works until it doesn’t, at which point you have a bug you cannot reproduce.

A playable patch: envelope and keyboard

[kslider]                      ← an on-screen keyboard (Max object)
 |
[t i i]                        ← pitch right, trigger left
 |        \
[mtof]     (to the envelope)
 |
[cycle~]
 |
[*~]  ←  [line~]  ←  [function] or messages [1 5( then [0 400(
 |
[ezdac~]

Key objects there:

  • [kslider] — clickable keyboard, outputs MIDI note numbers
  • [mtof] — MIDI note to frequency. Essential and endlessly useful.
  • [function] — a graphical breakpoint envelope editor; its output drives [line~] directly

For an attack-then-decay you need the decay delayed, same as in Pd:

[t b b]
 |      \
[del 5]  [1 5(
 |
[0 400(

The documentation is the best thing about Max

Right-click (or alt-click) any object and choose Help. Every object opens a working patch demonstrating itself, which you can edit, copy from, and play with. This is the single best feature of the environment.

Beyond that:

  • The reference pane shows every inlet, outlet, attribute and message for the selected object
  • Help → Max Documentation has structured tutorials, and the MSP and Jitter tutorial sets are genuinely good
  • Cmd-click an object in a patch to open its help; double-click an abstraction to open its contents

Where to go next, by what you want to build

Installations. Learn [udpreceive]/[udpsend] and the OSC objects — this is how Max talks to TouchDesigner, Processing, Unity, a phone, or another machine. Then [serial] for Arduino, and [jit.grab] plus [cv.jit] for camera input.

Live performance. [preset] and [pattr] for state, [live.*] objects if you are going into Max for Live, and a hard look at [poly~] for voice management.

Video and visuals. Jitter, and specifically [jit.gl.*] for OpenGL rather than the CPU matrix objects. [jit.gen] when per-pixel work gets slow.

DSP. [gen~], which lets you write per-sample algorithms that would be impossible as patched objects, and is the gateway to building things that sound like nobody else’s.

Max or Pure Data?

Pd if cost matters, if you need it to run on a Raspberry Pi in an installation for two years, or if you want to embed the engine in an app via libpd. It is free, BSD-licensed, and will outlive every company involved.

Max if you want Jitter (Pd’s video story is much weaker), Max for Live, gen~, or the documentation and polish — which are genuinely worth money if your time has value.

Learn either and you can read the other in an afternoon.