20Concepts Lesson 03 - Messages Part 1
(Needed: Example Video)
In this lesson, we will start diving into patching with "standard" Max objects - the low level objects that were used to build the Vizzie modules, and the core tools used for Max programming of any significant complexity. We will also learn a little about the Max environment itself, as well as the kind of data that we use inside of Max. Finally, we will use some of these elements to directly control some of our Vizzie modules.
(Needed: Fixture Patches with download)
One of the first things that you have to understand about how Max works is the concept of messages. A message is data that is sent from one Max object to another over the patch cord that connects them. The most basic message that is used is also a peculiar one: the bang message. A message that contains the statement "bang" has a particular meaning: it tells the receiving object to "do whatever it is meant to do".
The easiest way to create a bang message is using a standard Max object called a button. The button is an on-screen emulation of a simple pushbutton, but when the button is pushed, it sends a bang message from its outlet. It has a secondary purpose as well: whenever it receives a message (like a bang message), it will temporarily light up, then output a bang message as a response.
Let's wire up a very simple "standard" Max patch. First, create a new Max patch, then double-click on the blank space in the patch. This will display an Object Explorer - a scrollable interface for selecting Max objects. The second object shown is the button object; double-click on it to create a button in your patch (you may have to move the Object Explorer to actually see it). Double-click on the button icon to create a second button, then close the Object Explorer. Now, if you lock the patch, you can click either of the buttons and they will light up.
Since the button objects generate messages, let's hook these two buttons together to create a message network. Connect the output of one of the buttons to the input of the other, lock the patch, then click on the first button. You will notice that the second button lights up as well. This is because the first button, when clicked, sends a bang message down the patch cord to the second button. When that second button receives the message, it lights up as well.
Viewing Messages: The Max Window
One of the problems in sending the button a message is that you can't actually see the message. If you want to see the content of any message that is sent between Max objects, you need to use a special object: the print object. The print object will send any message it receives to a special window called "The Max Window", which is your status window for running programs.
You can see the Max Window in one of two ways. If you open the sidebar of your patch, you will see that there is an option to view the Max Window. You can also open the Max Window as a separate window by selecting it from the Window Menu.
Create a print object by typing "N" (for a new object), then entering "print" into the object. When you click off the object, it will instantiate with a single inlet. Disconnect the two buttons, then patch them both into the print object. Lock your patch and click on each button. You will see the "bang" message appear in the Max Window each time you click on a button.
One of the things that is important to understand about Max is the concept of a "data type" - an indication to the system of what kind of data can be found within any message. Max works with several types of data; in this lesson we will focus on three main types: symbols, integers and floating point numbers.
The bang message tells objects to perform their action, but the contents of a bang message is just a small bit of text called a "symbol". Within Max, any textual information can be contained within a symbol. So the words "on", "off", "read" and "start" (all of which we can find in our previous Vizzie experiments) are all considered symbols within Max. Symbols are seen (and created) within many objects, but the primary object for storing and sending symbols is the message box.
You create a message box by selecting it from the Object Palette, or more conveniently by pressing the letter "M". This gives you a blank message box - one that contains no symbol at all. If you click inside the message box and type a word ("open", for example), then click outside the box, you will have stored that word within the message box. Now, connect the message box to a print object, lock the patch and click on the your word. You will see that the symbol is transmitted along the patch cord to the print object, and your word appears in the Max Window. Therefore, the message box not only stores the symbol, it also acts like a button that can send out the symbol as well.
While symbol data is useful for both information and commands, the heart of Max lives in the use of numbers. The primary number data type (and one that is at the heart of most UI elements) is the integer. Integers are numbers that have no fractional portion, so it includes numbers like 550, 0 and -12. Numbers are important within Max because we use them in so many ways, and often interact with hardware using only integer data. As a result, integers provide a privileged place in the Max World.
You can store or generate integers using a number box object. These are most easily created by typing the "I" key while hovering over the Max work area. An integer number box, like the message box, is used for both storing and producing data. You update the number box's content by sending it a value over a patch cord, or by click-dragging when the patch is locked. This last option is quite efficient, and is one of the unique user-interface controls provided by the Max environment.
If you create a number box, connect it to a print object, then click and drag (in a vertical direction), you'll see that you can rapidly change the value in the number box - and output the data as you step through the number range:
Numbers with decimals are another kind of data: floating point numbers (or floats). These are very similar to integers, but they include decimal as well as whole number components. Many of the objects that work with integers will also work with floating point numbers - as long as you tell them to expect floats. When it comes to user interface objects, though, you need to use a different object: the floating point number box.
You create a floating point number box by selecting it off the palette, or by typing "F" on an unlocked patcher. This object looks almost identical to the integer number box, but it has a "dot" in it to remind us that it is for floating point numbers. It also works somewhat different: it still responds to vertical click-drag movement, but the portion of the number that changes is based on the location of the cursor when you click. If you click (then drag) on the whole number portion, it will increment the whole number portion of the float. But if you click on one of the decimal positions, it will increment that column of the decimal contents.
While we can use the type-specific UI objects to store each of the data types, the message box actually has the ability to store, display and output them all. When a number is entered into a message box, it is understood to be a numeric (integer or floating point) value and output as such. But how do we set the value of a message box with incoming data? This is what the right inlet is for: anything that comes into the right inlet of a message box replaces the current value, and that data is used the next time the message box is clicked (or receives a bang message).
Message boxes have another useful function: they can produce messages when a message is received. If we send any message into the left inlet of a message box, it will output the value that is stored in the message box.
However, we can use a special characteristic of the message box to produce variable output based on the contents of incoming message. In order to do this, we have to use a special message formatting device - the replaceable argument ($1):
When a message comes into the message box that has a $1 in it, the object outputs the contained message, but replaces the "$1" entry with the incoming message. Using the patch above, we can see that sending numbers, words or even the bang message produces a message with the incoming value in it.
Using Messages to Control Objects
By combining text with other value, we can create messages that will modify and control other objects. Let's take a look at a simple example.
The comment object has many properties; one of them is the fontsize, which controls the size of the font used for displaying the comment text. You can change this value within the Object Inspector, but you can also change it programmatically using messages. Create the following patch, containing a comment, message box and number box:
You will notice that we are using the $1 replaceable parameter to create a message containing the symbol "fontsize" followed by the incoming value from the number box. If you click and drag on the number box, you will change the font size without having to use the inspector.
(Needed: text and links)
(Needed: text and exercises)