Max has a wide variety of objects for storing and managing data. Objects such as table
, and umenu
all store information that you can set manually or via a mechanism within a patch itself. The preset
object, which also stores data, is useful for capturing and recalling the ‘states’ of user-interface objects within a patcher, giving you the ability to rapidly restore settings to multiple parts of your patch in one step.
Often a project in Max will require a more sophisticated state management system than the basic data structures objects allow for. The pattr
family of objects (pattr
, and pattrstorage
) provides the functionality of the preset
object and adds a more extensive set of state management features:
- We can maintain sets of data from objects throughout a Max patch hierarchy. For example, with pattr you can control the state of objects inside of patcher and bpatcher objects all from the top level of the patch.
- We can store any type of data used by any type of object (including data simply stored inside a pattr itself, without any other objects involved).
- We can use pattr objects to remotely set and query the state of objects controlled by the pattr system from anywhere within the patch.
- The pattr objects store groups of settings as XML files, allowing us to easily read and edit saved data outside of Max.
- The pattr objects can recall the state of objects in a specific order, avoiding difficulties with, for example, the recalling of a toggle object that starts a process before all the variables are in place for the process to function correctly.
- Not only can we store the states of many objects under a single address, we can also interpolate between these states, allowing for a seamless crossfade between multiple settings.
- The pattr objects feature a high-level interface for viewing and managing the current state of controlled objects and the states that have been saved.
In this tutorial, we’ll look at some of the basic features of pattr
, showing how the objects can be used to communicate remotely with objects anywhere in a Max patch.
Take a look at the tutorial patcher. Turn on the metro
object with the toggle
object box labeled ‘start’. You should hear some music if you double-click the noteout
object and select a valid output synthesizer. The number box attached to the metro
object controls the speed of the generated pattern. Click on the colored boxes to the right of the patch and note that they change the value of that number
box even though there are no patch cords or send
, or receive
objects in the patch.
Clicking in a colored message
box changes the metro
object’s time value.
object to the right of the metro
object is controlling the value in the number
box above it. In the language of patcher storage, we say that our pattr
object is bound
to the number
box. When we send messages to that pattr
object, it will at all times refer to the data stored in the number
box, allowing us to ask the pattr
object what the number is currently set to, as well as tell the pattr
object to set the number to a specific value remotely.
object has a name
- - which is set by the object’s argument and allows other pattr
-family objects to communicate with it. The pattrhub
object at the bottom of the patch can receive messages and forward them to any pattr
objects in the patch. By sending the message to the pattrhub
, we are telling the object to find the pattr
with the name . If it finds the relevant pattr
object, it will instruct the object to send the message to whatever object it is bound to (in this case, our number
Unlock the patch and click on the number
box attached to the metro
object. Select Name…
from the Object
object is bound to our number
box because the attribute of our pattr
object is set to the name of our number
box ( ). The act of naming
Max objects allows us easier access to them via the pattr
system. Note that the pattrhub
object controls our number
box via the name of the pattr
object to which it is bound ( ), not the name of the number
box itself ( ).
Rename the number
box to something else and close the Inspector. Try changing settings for the patch by clicking on the message boxes again.
Note that if we rename our referred object, our pattr
object can no longer bind to it. In order to rebind it, we need to tell pattr
to bind to our number
Open the Inspector for the number
box and name it back to . Close the inspector and recreate the pattr
object binding to (either delete the object and undo the deletion, or create a new pattr
object). Verify that it is receiving updates from the pattrhub
object by clicking on the message
Instead of recreating the pattr
object, we could have sent our newly ‘unbound’ pattr
object a message with the name of the number
box, setting the attribute to a valid object.
Naming a Max object and explicitly binding a pattr
to it with its attribute is only one way to get a pattr
to refer to an object in our patch. It has the advantage of requiring no connecting patchcords between the two objects, allowing them to communicate from spatially disparate parts of the patcher.
Open the subpatch patcher
object containing it. This subpatch contains eight pattr
box objects that define the four pitches in our pattern generator, as well as the number of beats between each trigger of the pitch. This is the part of the patch that allows us to construct a polyrhythmic pattern off of a single counter
object (driven by the metro
object in the main patcher).
by double-clicking the
Click on the message
boxes back in the main patcher with this window open and notice that the number
box objects in the subpatch update correctly when you click on the different patterns. Clicking on the message
box updates the subpatch values, too!
In addition to binding objects to pattr
through explicit naming and the bindto attribute, pattr
objects can control other Max objects through patchcord connections.
The notes subpatch shows two possible ways to do this:
1. Using the pattr
object itself to store the data
2. Automatically binding
object to an object using the pattr
object’s middle outlet.
If a pattr
object is unbound, it will store any messages sent in its left inlet and recall them from its left outlet. Messages sent to an unbound pattr
object from a pattrhub
object will echo out of the left outlet as well.
Unlock the notes subpatch and attach an slider
object to the left outlet of one of the pattr
objects named , , , or . Recall the pattr
objects’ states by clicking on the message
boxes in the main patch. Scroll the number
box attached to the pattr
object. The slider
object should move as well.
objects controlling our pitches are not bound to any single object, and are maintaining the values of the number
box objects attached to them not by referring to the objects directly, but by receiving their values as messages. As a result, the number
box objects attached to these pattr
objects can be deleted and replaced with other objects (or more than one object). Because the pattr
object outputs its values when changed (either directly or remotely) we can easily attach multiple objects to the pattr
object to set and display values stored in the object.
The use of the prepend
object with ‘set’ argument in pattr
connections is to prevent the triggering of MIDI events when we recall the pattr
object’s state. Unlike most Max objects, pattr
objects can be connected to other objects that are directly connected to them in turn without causing a stack overflow.
In the same subpatch, try to connect a slider
object to the middle outlet of one of the pattr
objects labeled , , , or . The Max window should print an error message and the program should prevent you from making the connection.
The middle outlet of pattr
allows for the automatic binding of the pattr
to a single object in the same patcher. The number
box objects controlling the %
objects are communicating with their respective pattr
objects just as if we had named them and bound the pattr
objects to them manually.
Look at the names for the number
box objects by selecting Name…
from the Object
objects automatically gives the referring object a name if it doesn’t have one already. The name is based on the class of object attached, and multiple objects of the same class in a patch will be given incrementing notation to uniquely identify them (e.g. , , , etc.).
(middle) outlet of
Back in the main patch, open the patcher
object containing it. Observe that the two pattr
objects in there ( and ) have been bound to two number
box objects through their middle outlets.
subpatch of the main patch by double-clicking the
Close the subpatchers and go back to the main tutorial patch. Look at the message
boxes again and notice the notation used in them to refer to pattr
objects inside subpatchers.
Because most of our pattr
objects are inside subpatchers, the pattrhub
object refers to them using a colon-separated
notation that takes the form
We can communicate to pattr
objects in nested subpatchers by the same convention, e.g. a pattr
named in a patcher called in a bpatcher called would be accessed through pattrhub
with the name:
Using the umenu
object in the main tutorial patch, select one of the pattr
objects in the patch.
In addition to setting the state of pattr
objects through pattrhub
, we can also query
the state of pattr
objects, which will then tell pattrhub
their internal state or the value of the object to which they’re bound. We do this by sending pattrhub
the message followed by the name of the pattr
object we want to query, with no space in the message, e.g. will poll the state of the pattr
box to the right of the umenu
reflects the current value of the selected pattr
, output by the second outlet of pattrhub
as a message beginning with the name of the queried pattr
Change the value of the selected pattr
by changing the number
box next to the umenu
. Check to see that the value changed by looking at the number
box controlled by that pattr
. Select some other pattr
objects and change their values, familiarizing yourself with how the system allows you to query and set the states of objects anywhere in the patch.
objects provide a powerful way to manage data from multiple objects in a Max patch. The pattr
object can maintain its own internal information (sent and returned through its leftmost inlet and outlet), or it can bind to a Max user interface object either by naming that object and using the pattr
object’s bindto attribute, or by using the middle outlet of the pattr
object to automatically name and bind to an object. Each pattr
object can only bind to one object at a time. The pattrhub
object allows you to control the state of all pattr
objects within a patch, including those within subpatchers, which can be accessed through a hierarchical notation system of successive patcher names separated by colons ( ) followed by the name of the appropriate pattr
object. By sending a message (followed by the name of a pattr
with no intervening space) you can query the state of any pattr
object within a patch from a pattrhub
Patcher-specific, named data wrapper
Access all of the pattr objects in a patcher
Create a subpatch within a patch
Store and recall the settings of other objects