I recently attended Day for Night, a festival dedicated to music and art, primarily of the digital variety. I left feeling deeply inspired to create some art of my own and since then have been tooling with Max. I had already been playing with Processing to do some visual programming, so it seemed like the perfect opportunity to try the two together.

The first thing I’ll say about Max is that there are usually a few ways to accomplish the same task. Knowing which one to use when is the challenge. Luckily the community is pretty helpful and examples abound.

In this article I’ll describe how to pass audio information from Max, using OSC messages, to Processing and visualize that information. We’ll be animating a shape that reacts to the amplitude of the audio. Here’s what you’ll need:

Max

Processing

The oscP5 library for Processing (available via the included library manager)

I generally like to know how things work under the hood, so there will be plenty of asides describing things in more detail as I go.

Max and OSC

My end goal is to visualize the amplitude of the audio, so my Max patch starts off pretty simply:

Output the amplitude

Using the playlist object, I’ve added a sound file and used the first outlet to send to the default output and to a meter object. The meter object will output a float value between 0 and 1. I’ve also connected a number object just to monitor the output value.

The next step is to create an OSC message and send it out into the world. This was my first foray into OSC, so I’m still learning what it can do. Here’s that first aside I said would happen:

OSC stands for Open Sound Control and is a protocol developed at UC Berkley primarily for networked communication for audio and multimedia. In my mind, it’s attempting to be the more open-ended MIDI, and I think it accomplishes that. It’s easy to write and easy to read. The message format is pretty simple: /<address_pattern> <value>

Knowing that, I want to create a message for the amplitude values that looks like: /amp 0.54

This is super simple with the prepend object in Max. It literally just prepends the input value with whatever text you give as an argument.

Creating an OSC message using the prepend object

The last thing we need to do in Max is send the OSC message. OSC is a bit network-protocol agnostic, meaning there are multiple ways to send a message over the network — UDP and TCP seem to be the most common.

In our case we’ll use UDP because it’s more straightforward, though more error prone.

To send a message using UDP, we can use the udpsend object specifying an address and port number. We can send any number of messages to this object, but we only need one for now. Here’s our completed patch!

Sending the OSC message over UDP

127.0.0.1 is the local address of my machine (and your’s too). I’ve chosen port 12000 because I know it’s available.

At this point, if you hit the play button, the data should start flowing. There’s an easy way to check! In Terminal type nc -ul 12000 | hexdump -C . You should see a whole bunch of this:

Reading UDP data

This is kinda cool. You can see our /amp address pattern, an f telling us it’s a float value and the HEX parser’s conversion of the value to a string (i.e. >m , =_@ ). That last part isn’t that helpful except to tell us that values are coming through.

Processing…

Now that we’ve got some data going out, let’s get that into Processing and make a pretty picture on the screen. If you’ve never used Processing, it’s a Java framework and IDE useful for programming animations, visuals, graphs, whatever really. Assuming you’ve installed oscP5 (Sketch > Import Library > Add Library and search for “oscP5”), we’re ready to get started. Here’s the complete Sketch to start. Hit the play button in Max and the run button in Processing to see the magic.

import oscP5.*; //OSC receive

OscP5 oscP5; // This value is set by the OSC event handler

float amplitude = 0; // Declare a scaling factor

float scale=6; // Declare a smooth factor

float smooth_factor=0.1; // Used for smoothing

float sum; void setup() { //fullScreen(); size(600,600);



// Initialize an instance listening to port 12000

oscP5 = new OscP5(this,12000);

} void draw() { background(0); // smooth the amplitude data by the smoothing factor

sum += (amplitude - sum) * smooth_factor; // scaled to height/2 and then multiplied by a scale factor

float amp_scaled=sum*(height/2)*scale; float mappedColor = map(amplitude * scale, 0, 1, 0, 255); //draw a dynamically-sized/colored circle

fill(0, mappedColor, 255);

ellipse(width/2, height/2, amp_scaled / 2, amp_scaled / 2);

} void oscEvent(OscMessage theOscMessage) { float value = theOscMessage.get(0).floatValue();



if (theOscMessage.checkAddrPattern("/amp")) {

if (value > 0.4) {

amplitude = value;

} else {

amplitude = 0.0;

}

}

}

What you should see

I think most of this is pretty self explanatory, but let’s go over the three functions here.

In Processing, every Sketch requires a setup and draw function. Setup is called once and here is where you do your, well, setup. We set the size of the window and intialize an oscP5 instance. draw is responsible for drawing stuff into the window and unless you specify otherwise, it is called on a loop, which is why we clear the window each time with background(0); .

Lastly, the oscEvent function — the oscP5 instance calls this function by itself anytime it receives a message. We just have to digest it. Here, we capture the float value for the message, check the address pattern for the said message, and if it’s what we’re expecting, we’ll set our internal amplitude value with the new value. You’ll notice I have an if else inside the pattern checker. This is our that threshold value that serves to prevent drawing the non-transient sound. If we lower it to 0.0, you’ll see the circle jump a lot more. You may need to play with this value depending on the volume and audio source you use.

Hopefully this shows you how easy it is to pass audio data from Max to Processing. I encourage you to play around with the threshold value and the scaling factor and then maybe toy around with your own drawing code! Drop a line if you have any comments or questions!

By the way, here’s the completed Max patch. Copy this to your clipboard and then use File > New from Clipboard.