In the previous tutorials, we've looked at a set of basic objects that we use all the time for constructing patchers in Max. In this tutorial, we'll use these objects (and a few more) to actually control something (in this case, drawing). We will look at a few ways to manipulate messages by routing them (using the
gate object) and manipulating lists (using the
pack and
unpack objects). We will also query the state of the mouse to change the way that our patch works, and we will learn more about getting information on individual objects and changing the appearance of objects and patchcords. We will use these new objects and techniques to control the
lcd object, which allows us to draw simple two-dimensional graphics inside of Max.
One of the most powerful aspects of Max is the ability to create small segments of programming that perform specific functions, and having the ability to route messages to the appropriate portion of a larger patcher. Intra-patch routing is key to that power, and the
gate object provides that functionality in a very flexible way. It is also useful to build complex messages on-the-fly, so we can control complex patch processes with relative ease.
The
pack and
unpack objects are used to create list messages and to split them into their individual components again. Lists are the key to working with objects that require more complex messages, and it's often necessary to construct and deconstruct lists from smaller components (integer and floating-point numbers, for example).
Finally, we will dig into getting more information on object messages. We'll also learn how to color and manipulate patchcords. Visual cues help us figure out other people’s patch functionality, and make patches more readable when we share our patches.
Before we begin looking at what our tutorial patcher does, let’s take a short diversion to look at some of the ways we can get information about the objects that we have in our patch. Unlock the patcher and move your mouse around the objects in the patch. You’ve probably noticed that when we place our mouse on an inlet or outlet, a small box is displayed with information about the use of that inlet or outlet. This assistance text is provided as a reminder for the programmer of what that inlet or outlet does in an object. You will also notice that a small circle is displayed around the inlet/outlet.
If we click on an inlet while the circle is displayed, a contextual menu is displayed that shows all of the supported incoming messages, as well as shortcuts to view the object’s help file, reference pages and even to search our system for relevant matches in the file browser. This provides a greater level of detail if we need to know details about the exact use of the object.
There is another option for on-the-fly information: the clue window. Select Clue Window from the Window menu of Max; a small window will be displayed. Now, when you hover the mouse over an object, we will see a brief explanation of the function of the object. Also, if the contextual menu is displayed, hovering over messages will display a brief clue about how the message will affect the object. Using the clue window to view the use of objects is a great way to examine the objects used within a more complex patch.
If you look at the objects in this tutorial patcher, we notice that the
patchcords look a little different than the ones we've seen earlier. First of all, a number of the patchcords have right-angle
segments; in addition, some of them are different colors. Let’s look at some of the ways we can manipulate the patchcords themselves. Under the
Options menu in Max, check the option
Segmented patchcords. This allows us to create patchcords that have bends in them. We can delete a patchcord by selecting it and hitting the Delete key. Delete one of the patchcords connecting the
message boxes to the
gate object at the top-left of the patch.
Now, reconnect the
message box to the
gate, but instead of making a direct connection between the two, make a
segmented patchcord by clicking the outlet of the
message box and then releasing the mouse; we can add segments by clicking the mouse anywhere while we draw the patchcord; we finish the connection by clicking the inlet of the destination object (the
gate). Whether you use straight or segmented patchcords is largely a matter of personal style, but often you can sometimes make a patch look cleaner by using segmented patchcords.
Max also can help us clean up our patchcords. Click on the patchcord and hit Command-Y on the Mac, Ctrl-Shift-A on the PC (alternately, you can select the Align function under the Arrange menu in Max). Max will segment and reroute the patchcord to avoid overlapping objects. We can also select several patchcords by holding the Shift key while clicking on patchcords - the command sequence will then reroute all of the selected patchcords. There is no difference whatsoever between a regular and segmented patchcord in terms of how messages are passed between objects.
Finally, let’s look at Max’s ability to change the color of objects and patchcords. We can select an object or patchcord (by clicking on it) then select Color from the Object menu. It will display a color picker dialog, where we can select a color for the selected item. Selecting a color returns to the patch editor with the object or patchcord having the newly selected color. We've been coloring objects green as we introduce them in the tutorials; as you can see, it's a great way to focus attention on important parts items within our patch.
Now lets look at what the patcher does. In our tutorial patcher, we find two small patches (on the left) and one very large patch. The patch at the top left is where we will start.
This patch shows the
gate object in action. The
gate object is one of the most important objects used for dynamic message routing within Max. We will start by clicking on the message labeled
1 (the middle
message box), then changing the value of the
number box attached the right inlet of the
gate. When we do this, we see that the value of the
number box is sent out the
left outlet of the
gate (outlet
1). If we click on the
message labeled
2 and alter the
number box again, we see that the changes are now sent out the
right outlet of the
gate (or outlet
2).
As we can see, the number sent into the left inlet determines the routing of the message received in the right inlet; in essence, the left inlet determines which outlet is
opened. Now, click on the
message labeled
0 and change the
number on the right. The message never makes it out of the
gate – the
0 message has
closed all of the outlets. This is useful for situations where we want to suppress messages within our patch, for example when we need to selectively enable and disable numbers flowing from one part of our patch to another.
As an exercise, change the
gate object to have a
4 for an argument (it currently has a
2). We see that the object changes – it now has four outlets. The argument to
gate determines the number of outlets that the object has. If we add a few more messages to the left inlet (by adding a
3 and
4 option to support the new gate outlets) and attaching
number boxes to the new outlets, we can see how easy it is to expand the routing matrix supported by the
gate object.
The next part of patch that we will look at is just below the
gate – it uses the
unpack and
pack objects to split and reassemble
lists of numbers, and the
prepend object to place a
message selector (a symbol) in front of the list. The two
message boxes contain two-number lists; when we click on them, we see the two
number boxes connected to the
unpack object display the individual numbers within the list. The
unpack object has taken the incoming list and split it into individual numeric messages. Since lists are often used to create complex messages, we often use the
unpack object to unwrap these lists into its individual components (called
atoms).
After the
number boxes display the messages, they send out their contents into the
pack object below, which reverses the process by combining them back into lists that are sent to the
prepend object and displayed in the Max window (via the
print object. Notice that only one message is displayed in the Max window, even though the
pack object received two messages (one from each
number box). This is because the
pack object (like most other objects in Max) will only produce a message when the leftmost inlet receives a message. The patch editing environment provides a clue for this: if we unlock the patch and hover the cursor over the right inlet, we see that it displays a blue circle – meaning that it is a
cold (non-message producing) inlet. Hover over the left inlet and we see it circled in red; it is a
hot inlet, and will cause the object to generate output when it receives a message. We can confirm this by typing other numbers into the
number boxes that are sandwiched in between the
unpack and
pack - only the left-hand
number box will cause a list to come out of the
pack object.
The arguments to
pack and
unpack determine both the number of inlets and outlets, respectively, the object will have, but also the
type of message that can be sent into those inlets. In our case here, both of these objects are working with two-element lists made up of
integer numbers (signified by the use of
0 as an initial argument). If the list we were making required floating-point numbers, we could have used
0. (or any other initial floating-point value) as an argument; similarly, if a symbol (a word) was needed in the list, we could have used the letter
s (or any symbol); types of data can be mixed and matched within a list.
Notice that the
prepend object places the word
thelist in front of the list of numbers coming out of the
unpack - this
symbol can be any word we like, but in many cases in Max we use
prepend to place a
message selector at the start of a list before sending it into an object that has a special use for that message.
Now it’s time to attack the big patch to the right. Let’s see what it does by turning on the
metro object at the top of the patch by clicking the
toggle object to
1 (checked).
The large rectangular object in the center of the patch is an
lcd (
liquid crystal display) object: we can use this object to draw pixels, lines, shapes, text, and other simple two-dimensional vector graphics. If you drag the mouse in this area while holding down the mouse button, we see that it draws lines wherever you go. Release the mouse button, and the drawing will stop.
If you hold down the shift key, option/alt key or a combination of both, the
lcd object draws different shapes under the mouse rather than lines. There are three colored
message boxes above the
lcd that can be used to change the foreground color of the drawing (using the
frgb message), and another
message box (to the right) that will send the
clear message to the
lcd, erasing its screen.
One of the key sections of this patch is the handling of the shift and option/alt keys; this is done by the
modifiers object, which is polled using the
metro, and reports the current setting of the various modifier keys on your keyboard. In this case, we use the outlets that report the shift and option/alt keys; we
multiply the option key's state by
2 and
add it to the state of the shift key. The result is that shift alone will give us the value
1, option/alt alone will give the value
2, and the combination will give us
3. If no modifier keys are depressed, the value will be
0. This type of patch circuit is perfect for controlling the state of the
gate object below.
In addition to providing a drawing surface, the
lcd object can give us the current location of the mouse in a manner analogous to the
mousestate object, only relative to the position of the
lcd in the patch. Sending the message
idle 1 to the object allows us to get mouse coordinates regardless of whether or not the mouse is actually clicked inside the
lcd (we enabled idle mousing when we turned on the
toggle box, above).
These coordinates are provided by the second outlet of the
lcd object – we can see the values (a list of two numbers that represent the X and Y coordinates within the LCD object) in the number boxes at the lower right, after they've been split apart by the
unpack object. This list is also sent to the right inlet of the
gate object; we’ve colored that patchcord red to make it easy to see.
By routing the mouse coordinates to different areas of the patcher, the
gate object now controls what type of drawing will occur in the
lcd. If no modifier keys are depressed, the gate receives a
0 and none of the drawing routines are used, though we can still click-drag inside the
lcd to draw lines. If shift, option/alt, or both are depressed, the
gate routes the mouse location to the appropriate section of the patch.
In each of these sections, the X and Y locations are run through
unpack objects to get the coordinates individually. They are then used to create a properly sized shape. In the left-hand (shift) case, a value of
10 is subtracted and added to both coordinates and sent into a
pack object in the order:
X-10 Y-10 X+10 Y+10
This list of four values is then sent to a
prepend, which places a symbol at the front of the list. The
lcd object supports a number of drawing commands which do different things; in this case, we're instructing our
lcd to draw rectangular frames by providing it with a
framerect message followed by four arguments - the left, top, right, and bottom boundaries of the rectangle we'd like to draw.
Looking at the other two pieces of drawing code, we can see that they work in similar ways. The middle outlet of the
gate object (responding to the option/alt key) draws oval-shaped frames (the
frameoval message) that are 10x10 pixels in size (notice the
+ and
- objects). The third drawing alternative (for when both shift and option/alt are held down) draws filled in rectangles with rounded corners (
paintroundrect). In addition to the coordinates of the rectangle, two additional
number boxes are sent into the
packobject - these control how rounded the corners are.
When the coordinates are created and determined (using the math objects and
pack) and given a message selector to determine the drawing routine (using the
prepend object), the message is sent back into the
lcd object. In order to easily see this message routing, we’ve colored the drawing command patchcords in blue. The frgb
message boxes are also colored to match the color it will tell the
lcd to draw with. These are examples of using object and patch cord coloring to make the function of a patch more obvious.
There have been several different (but important) topics covered in this tutorial. We see how the
gate object can be used to activate message passing to sections of your patch. We’ve also seen how to use the
unpack,
pack, and
prepend objects to build and parse complex messages. We’ve also seen how to color and manipulate patchcords and objects to help make patches and message routing more easily visible. Finally, we've seen how to use the
lcd object for simple drawing.
See Also
Name |
Description |
gate |
Pass the input out a specific outlet
|
pack |
Combine numbers and symbols into a list
|
unpack |
Break a list into individual messages
|
prepend |
Put one message at the beginning of another
|
lcd |
Draw graphics in a patcher window
|