Archive for March, 2010

An Interview with Chris Coleman

Artist and educator Chris Coleman is recognized in the Max community for his work on Maxuino, a Max interface to the popular Arduino microcontroller board. When I spoke with him, Chris also discussed his early sculpture work, teaching, collaborations, and how Max/MSP and Arduino fit into the evolving landscape of electronic media tools and practices.

(more…)

LFO Tutorial 7 (Rattle and Hmmm)

A simple truth emerges from the practice of writing Max patches like the Max for Live device we’ve been working on: The trajectory of “finishing” your Max patch is something you approach on an asymptotic curve – you approach being “done,” but never quite reach it. This tutorial is an attempt to honor that curve of near-completion.

There’s always something new or something more you can add. It seems as though the difference between patches in this regard is how long you work with something before you decide to make the change. I’ve used the same basic approach to performing and improvising for a number of years now in the patch that I use, but the actual insides of the patch itself are very different with what I started with when I thought my performance patch was “done.” It changed in tiny increments very slowly over a long period of time – I’d make a change, go do a few gigs or some recordings with it, and slowly decide whether my great improvement really was great or really was an improvement.

Download the patches used in this tutorial.

Other LFO tutorials:

Writing tutorials like this series hides that process in two ways. First, since you’re looking over my shoulder while I do the patching instead of approaching the problem solving yourself, you’re only seeing the end product. Second, the sequence of tutorials has more to do with grouping ideas pedagogically rather than replaying the sequence in which I would actually have developed a patch.

With luck, I’ve finished my tutorials without having made some specific change you might have in mind, which might give you the motivation to leave behind a life of passive Maxing to add the thing(s) you care about.

This time out, I’m going to focus on adding a few new features to the waveplayah Max for Live device I ported in the previous tutorial. I’m also going to focus a little bit on trying to update the patch in ways that might be more generally useful for your own Max programming rather than being mere tweaks to a single Max for Live device. Okay, let’s begin.

Demystifying pattr

The waveplayah.amxd Max for Live device allows you to create Live presets in the same way as you do with any other Instrument, Audio or MIDI effects device; you set your parameters and save the patch with a new name. The Live application also includes the hot swap feature that makes it a breeze to switch presets while you’re working. In this tutorial, I’m going to show you another way to create and save parameter values in a Max for Live device by using the pattr family of Max objects.

For reasons I don’t entirely understand, many Max users would rather mess about with the Max preset object rather than take the plunge into using the robust and insanely useful pattr family of objects. One possible reason for this (besides simple risk aversion) seems to be that people think that pattr is hard to learn and use. While I showed you just how easy it is to pattrise your Max patch in the first tutorial in this series, let’s assume that you’re a Max for Live user who hasn’t read back that far and take another look….

In fact, we have already done almost all of the work to use pattr with the waveplayah device in the previous tutorial when we used Max’s Parameters Window to set all the UI objects in our patch as part of the process of porting it for use in Max for Live. One of the things we did was to give each UI object in our patch a “Scripting Name” which we linked to the “Long Name” of the object. We did this so that it would be easy to identify a particular UI object whenever we want to add automation to a parameter.

Doing that work last time out makes pattrising this Max for Live device a snap (giving your parameters names is really the only time-consuming part of adding pattr functionality)

That’s it. We’re done. No, really.

If you’d like to see what adding the pattrstorage and autopattr objects has done, hold down the command (Macintosh) or the control (Windows) key and double-click on the pattrstorage object. The pattr Client objects window will appear and show you all of the parameters of your Max for Live device that are registered and whose values will be stored. Neat trick, eh?

We can now store values for all of the parameters in our device by sending the message store [number] to the pattrstorage object, and recall patches by sending the message recall [number] to the object. But I’m going to add a nice visual interface for saving and recalling presets while I’m at it.

You’re done – the preset object now talks directly to the pattrstorage object, and clicking or shift-clicking on the preset object’s dots will recall and store presets (you will want to add your preset object to the Presentation layer and decide where to put it in your user interface, of course).

A little local color

There’s an interesting and subtle feature of Max for Live that you may not have noticed yet – when you change the skin of the Live application (using the Look/Feel tab in the Live application’s Preferences menu) Max for Live automatically adjusts the colors of all Live user interface objects to match the Live application’s new color scheme.

Give it a try – close the waveplayah device’s edit window, open Live’s Preferences window, choose the Look/Feel tab, and change the skin using the pull down menu. Cool, huh?

There’s only one problem with our waveplayah device – the non-Max for Live user interface objects (the rslider objects and the multislider object we’re using for our visual display) stay the way they are regardless of the skin we choose. Unlike the Max for Live UI objects, they don’t automatically adapt. We’re going to add some patching to our device that will let us automatically change those colors, too.

The color schemes you see when you use any Max UI object are attributes of the object. You can see what they are by using the object’s Inspector, and you can use messages to Max objects to change how any object is displayed.

Max for Live includes a special object called live.colors that you can use to find out what the current color scheme associated with a Live skin is, and you can use standard Max patching techniques to set the colors of the rslider and multislider objects.

Here’s how it works. Each Live skin includes a set of color tags used to identify how some part of the Live UI looks – the color used for backgrounds, text, the color that is used when a UI element is selected, and so on. The live.colors object lets you use Max messages to ask about what color is used for any of these tags, and you can take that information and format it for use as a regular Max message that changes the color of a regular Max UI object.

So what are the names of these Live color tags used when skinning the application? There’s a helpful example that will show you the names and current color values of all of the different colors that make up a Live skin in the help file for the live.colors object (click on the message box containing the word everything, then double-click on the “View.All” subpatch to open it and show you the colors and tag names).

Likewise, we can use Max’s object Inspector to find out the names of each attribute that correspond to the current color of the UI object by selecting the object, slicking on the Inpsector icon in the Patcher Window toolbar, and then scrolling down to see the color attributes. To see the attribute names associated with the color attributes, just click on the Show Attribute Names icon in the Inspector window toolbar. Here’s an example that lists the attribute names and colors for the rslider object:

We now have a list of color tags for the Live skin, and another list of attribute names for the rslider object. How can we use the live.colors object to automatically set the color of an rslider object in our Max for Live device?

The live.colors object will take the name of a color tag as a message in its inlet and output a list of the four RGBA color values as a list of four floating point numbers, preceded by the name of the color tag we asked for. From there, it would be a simple matter to use dollar-sign style Max messages to strip off the name of the color tag and format a message we can send to an rslider object:

But we’re going to be making several different queries – it would be nice to have a little more efficient way to get what we want. So let’s consider how we might make things a little easier.

To set everything up, all we need to do is to decide on the color tags we want to use and the attribute names of the rslider and multislider objects we want to change. The fact that the live.colors object starts its output list with the name of the color tag we asked for means we can use the Max route object to route its output to a different output for each different request. That means we only need one live.colors object to do everything for us. And since the route object strips off the first item of its input list, the route object will spit out a nice four number list ready to go – all we need to do is use the append object to attach the name of the UI object attribute whose color we want to change.

The version of the waveplayah device file included with this tutorial contains a simple subpatch called “skinner_box” that checks for the current Skin colors whenever you add the device to your Live session and uses that information to change the color scheme for the rslider and multislider objects. A little investigation of the subpatcher will show you another neat trick that allows you to update the colors whenever you load a new skin.

Dragging and Dropping

In the original version of the waveplayah patch, I had decided on a really simple UI for loading files – the inclusion of a button that initiated a file load via the Max filedialog object. It was quick and easy and it worked like a charm, but I kept thinking that I’d like to have a nice drag and drop interface that would let me grab AIFF and WAV files from the Live file browser. Although I don’t really use MP3 files very much (They don’t sound as good as AIFF/WAV files and they don’t use less memory since the file format is converted on import), I thought it would be nice to have the option of using them. That’s a little bit of a problem, however – the message that loads AIFF and WAV files (replace) isn’t the same message you use to load MP3s into a buffer (import) – I’d have to have a way to figure out what kind of file I have and load it accordingly.

I was sitting and staring at my list of imagined features when it suddenly hit me – My pal and colleague Darwin Grosse’s insanely great Loop Shifter MIDI instrument that comes with Max for Live had a drag and drop interface already in it!

And, of course, that patch had an edit button. So I decided to give Darwin’s patch a look to see if I could borrow and modify it. I loaded the Loop Shifter MIDI instrument and hit the edit button, and toggled from Presentation to Patching mode in the toolbar to see the insides of the patch.

It wasn’t too difficult to locate the part of Darwin’s patch that seemed to be doing the heavy lifting – a subpatch called file selector. Here it is:

I started as I usually do – by looking at what’s connected to the inputs and outputs of the subpatcher itself (what messages does the subpatch get and from where? What comes out of the outlets of the subpatch?). I tried the message box containing the word “open” and watched what happened, and looked at what Max objects were connected to the inlets and outlets.

In this case, I had what looked like two ways to specify the patch to be loaded – the message box and the live.drop object connected to the right inlet of the file_selector subpatch. The four outputs were less obvious, so I thought I could figure out some of it by double-clicking on the file_selector subpatch to open it and look at its contents.

Technical digression: Along with a number of other people, I suggest again and again to new Max for Live users that they begin by doing the beginning Max tutorials. Although opening and messing with Max patches is easy and fun, there is simply no substitute for having a good working knowledge of how a Max patch works – objects, messages, and the order and way that data flows through a patch. And there’s no other place where that knowledge is more crucial than when you start porting someone else’s patch knowing the basics makes all the difference. Really.

Don’t get me wrong here – the way Darwin’s subpatch worked wasn’t immediately obvious to me, either. So I did what I always do – I try to straighten the patch a bit and work out what’s going on by paying attention to the way messages travel through the patch. That particular bit of quality time included the liberal use of message box objects that let me see what the message coming from an object or subpatcher looked like

along some judicious use of the trusty Max Clue Window to help me quickly read through the refpage documentation (choose Clue Window from the Window menu to show the Clue Window if it’s not already visible, then hold down the Shift key and mouse over the inlet of an object to display a complete listing of all the various kinds of messages and attributes for the object. When you roll your cursor over any of the listed messages or attributes, you’ll see the description of the message or attribute from the object’s refpage displayed in the Clue Window).

After that quality time, I’d figured out a few useful things:

Technical digression: If you want to slow the transition between patching and presentation down, choose Patcher Inspector from the View menu to see the Patcher Inspector, double click in the Value column for the Box Animate Time attribute, and type in a high number (like 2000).

There was also some stuff in Darwin’s patch I didn’t need or wanted to change.

Armed with this knowledge, I poured myself a nice glass of chilled Rosato and got to work on some remodeling – removing and moving things around, renaming the subpatches with names I’d be more likely to remember, and loading the patch with comments to help me remember what a patch was doing.

After I was all done, the patch I’d copied out from Darwin’s instrument looked like this:

I had a nice drag and drop interface that collapsed in Presentation mode into a simple and clearly labeled file box that displayed instructions, file names (when loaded), and error messages, too:

At this point, you’re probably thinking the same thing that occurred to me – that I would probably be using something like this pretty regularly for creating audio effects and Instruments. This bit of patchery is a prime candidate for what we call a clipping in Max. A clipping is a snippet of a Max patch you can save in a certain place and simply paste into another Max patch with the touch of a key and a click.

Creating a clipping is easy. Choose Save As… from the File menu and save the patch to the clippings folder inside the patches folder inside your Max application folder.

Once you’ve saved your clipping, you can add it to any Max patch by control-clicking (Mac) or right-clicking (Windows) in any blank space in an open Patcher window to show the patcher contextual menu. You then choose your clipping from the Paste From submenu, and the patch will be pasted into your patcher window, ready to use.

The road goes ever on and on….

Things are looking pretty cool now. Am I done?

Don’t be silly. I’m done for now.

And there’s one thing I haven’t mentioned. Once I placed my drag and drop interfaces on the front panel and made room for a preset object, it occurred to me that maybe I might do better with my user interface if all three LFOs were arranged horizontally with their corresponding parameters grouped vertically. The Max for Live audio device included with this tutorial reflects all of those changes. Give it a try, and see if you can think up a few modifications of your own. That should give you some things to do and think about…

…for now, anyway..

Demystifying Expressions in Jitter

One of the most feared and respected objects in the Jitter collection, jit.expr arrived on the scene as part of Jitter 1.5. In some circles, there is a belief that harnessing its power will bring you great powers and enable you to achieve untold wonders.

The fact is, jit.expr is a really amazing tool, but unfortunately many users are intimidated by the syntax, which includes a lot of square brackets, parentheses, and special variables. While these sorts of things are common for programmers, they can seem very esoteric and strange to many Max users. Many avid readers of the Jitter Recipes got stuck when jit.expr was used to generate the quads in the TinyVideo and Shatter recipes. Upon getting familiar with the expressions, however, it will become an extremely handy tool that makes seemingly difficult and complicated tasks much simpler. Through this article, I hope to demystify this elusive object and help you to achieve the wonders that you are dreaming of. We’ll start by covering the basic elements of jit.expr expressions and then use these to create some basic geometry and image masks.

Download the patches used in this tutorial.

Getting Past the Empty Matrix

The jit.expr object doesn’t do much out of the box. In order for it to output anything more than black pixels, you’ll have to give it an expression to work with, using the ‘expr’ attribute. The expressions work in a similar fashion to jit.op where you are performing some arithmetic on each cell of the incoming matrix. If you’d like to just pass through the input from the first inlet of the object, you can type ‘@expr in[0]‘. The in[0] variable stands for the pixel value from the first inlet. The second inlet would be in[1], and if you have more inlets, they are numbered sequentially (in[2],in[3],etc.). If you’d like to add two jit.matrix inputs together (similar to jit.op @op +), you can use ‘@expr in[0]+in[1]‘. Still with me? This is where it starts getting fun.

In addition to accessing specific inputs, the ‘in’ variable also allows you to access a specific plane of the incoming matrix in your expression by using ‘.p’. For example, if you use ‘@expr in[0].p[0]‘, that gives you the first plane of the first input. To get the second plane, you could write ‘@expr in[0].p[1]‘ or ‘@expr in[1].p[2]‘ to get the third plane of the right input matrix. So, if we use ‘@expr in[0].p[1]*in[1].p[2]+in[1].p[0]‘ we would be multiplying the second plane of the first inlet with the third plane of the second inlet, and then adding the first plane of the second inlet. That was quite a mouthful, but hopefully you get the point. This can be really useful when you have an expression that requires multiple variables, and can take the place of using jit.unpack/pack in some cases.

On a related note, you can also create a unique expression for each plane of the output matrix by simply passing a list of expressions to the ‘expr’ attribute. Each expression is passed in as a symbol, so it is often beneficial to put quotes around your expressions, especially if it includes spaces. For the most simple case, we could type ‘@expr in[0].p[0] in[0].p[1] in[0].p[2]‘, which will just pass the appropriate planes from the first inlet. It’s a lot of typing for something so simple, but we’ll be making a lot of use of this feature later, so keep it in mind. It’s especially useful when generating geometry, since you will often need to use different equations for the x,y, and z values.

Making Numbers

When generating geometry or image masks, you will often need to generate a whole matrix full of values based on an equation. For the simple cases, you could probably use an object like jit.gencoord to generate unique values for each cell of your matrix. One of the great features of jit.expr is the ability to generate cell values by working with the norm[],snorm[],cell[], and dim[] variables. Which one you use will depend on what you are trying to accomplish.

These variables each require you to specify which dimension you would like to generate values across (horizontal=0,vertical=1,etc.) between the square brackets. The dim[] variable simply passes the size of your matrix across the specified dimension. This will be the same for all of the cells of the matrix, and is useful for situations where you would like to adjust values in proportion to the size of the incoming matrix.

Click here for a full-sized version of the screen shot.

The simplest of the other three variables is cell[]. This variable generates integer coordinates across the specified dimension. So, if we have ‘@expr cell[0] cell[1]‘, the first plane of the matrix would have values {0.,1.,2.,3.,…} across the horizontal dimension (starting on the left) and the second plane would have values {0.,1.,2.,3.,…} across the vertical dimension (starting from the top). While this might not be so useful as an actual output value, it makes certain things like modulo (%) expressions a lot easier to write when you are working with integers.

Note: You may have noticed the decimal point in all those values. This is to remind you that jit.expr uses floating-point arithmetic internally, and will convert to whatever data type you are using upon output.

Now that we know how to use cell[], norm[] is pretty simple. This handy variable outputs values between 0. and 1. across the specified dimension. Writing ‘@expr norm[0]‘ will generate the numbers {0.,…,1.} across the horizontal dimension, starting on the left. This also creates a nice horizontal linear gradient. This expression is the equivalent of ‘@expr cell[0]/dim[0]‘ but requires much less typing. Our final variable, snorm[] is very similar to norm[], but with the numbers stretched out to cover values between -1. and 1. This is especially useful when generating vertex values for OpenGL geometry.

Making Masks

In working with imagery, it is often necessary to do things like generating an oval mask for an image, or other shapes that allow you to escape the oppression of rectangles. Now that we’ve gone through how to use the built-in variables and put together simple expressions, we’ll use them to create a few different simple mask shapes. To start, let’s try creating a simple oval mask.

Now, in order to create an oval mask shape, we’ll need a way to generate values that radiate out from the center of the matrix, rather than just generating linear values. To do this, we can use the hypot() function built into jit.expr, which calculates the length of the hypotenuse of a right triangle, often used as a distance equation for two points. If we use @expr hypot(snorm[0]\,snorm[1]), we’ll get values that increase as they get further from the center. Remember that snorm[] creates values between -1. and 1. so the center cell will be 0. So, we’re getting close, but we have the opposite of what we really want (although an inverted oval mask can be pretty useful too). To invert the values, all we have to do is alter our expression slightly: @expr 1.-hypot(snorm[0]\,snorm[1]). Now we have a nice radial gradient. Now, you might notice the “\” in that expression. That’s there because Max likes to interpret commas in a special way, and we need to include the comma as part of the expression. The backslash prevents the comma from getting eaten up by Max. Suppose we would rather have a hard-edged mask instead of a soft gradient. We could easily add a threshold value by altering our expression again: @expr (1.-hypot(snorm[0]\,snorm[1]))>in[1]. This little extra portion sets the output value to 1. if our expression result is greater than the value at the second inlet. The parentheses are there to enforce the appropriate order of operations.

We could now take this a step further and create other mask shapes based on simple geometry functions. The first one we will look at is using sin() to generate another gradient shape. If we use ‘sin(norm[0]*TWOPI)’ we will get a full-phase sine wave across the horizontal dimension. In this expression, we are using “TWOPI”, which is one of the built-in constants (2.*PI) for jit.expr, provided for our convenience. There is also PI,HALFPI, etc. Multiplying the “norm[0]” by an input value will change the frequency of the sine-wave, which can be useful for creating repeated shapes. We could then take this expression further by multiplying a horizontal sine gradient by a vertical sine gradient. Now, if we are using this to generate imagery or masks, the negative values aren’t going to do us much good. To invert the negative values, we can use the abs() operator (absolute value) on the result. Now we have a nice repeating lump gradient pattern.

By now you are probably noticing that these expressions can get pretty long and complicated with just a little tweaking. An important thing to remember is that jit.expr is an object like any other object, and there is no rule that you have to do all of your math within a single expression. In fact you will probably find situations where you need multiple jit.expr or jit.op objects to accomplish what you need.

The Shape of Data

As you are experimenting with jit.expr, you will probably want to have some sort of visual feedback to get a better sense of what is going on. For simple cases, jit.cellblock is a great solution, since it allows you to peek at the number values of the output matrix. You can also visualize your jit.expr output using a jit.window which will represent the values as color intensities. Often times this gives the most intuitive feedback. Another way that jit.expr really shines though is in generating 3D geometry that can be visualized using jit.gl.mesh. Without going into too much detail, jit.gl.mesh allows you to create different sorts of 3D forms by passing in a Jitter Matrix. The matrix is then translated in different ways depending on the chosen “draw_mode”. By experimenting with different modes, you can visualize your jit.expr expressions in different ways. And once you get comfortable with the different modes, you can start creating expressions specific to the draw_mode you would like to use. Remember that jit.gl.mesh expects a 3 plane (x,y,z), float32 matrix for the vertex input, so you will need to think about how you would like to generate positions for each of the coordinates. If you would like to apply a texture to your 3D shapes, you will also need to generate texture coordinates for each cell (2 plane float32, 2nd inlet).

Click here for a full-sized version of the screen shot.

A very simple thing, which is very useful in real life, is to create a simple textured plane (similar to jit.gl.videoplane). To do this we can use a 5 plane float32 matrix, and use the following list of expressions in jit.expr: snorm[0] -snorm[1] 0. norm[0] norm[1]. If we break it down, we are just creating a simple grid for the x and y values by using snorm[]. You may have noticed that we left the third expression as “0.” Since we are creating a flat plane, we can just zero out the z values. For texture coordinates, jit.gl.mesh expects values between 0 and 1., so we are just generating a grid of coordinates using norm[]. Simple, right. Now, I’ll leave it up to you to imagine different sorts of equations that might provide more exciting results. You might need to brush up on your trigonometry, or if you are like me, fake it. I’m including a patch called simple-shapes that demonstrates a couple of simple and potentially useful shapes using the tri_grid draw_mode.

Express Yourself

I hope this is enough of a boost to get you started writing your own expressions with jit.expr. In future articles, we’ll look at some of the more advanced features of jit.expr and ways to combine it with other Jitter objects to create unusual and wonderful results. With a little practice and study, you too can learn to tame this mysterious animal.