This tutorial covers two of the most useful objects in the Max world:
coll and
route. The
coll object allows for the indexed collection of data; you can think of it as a small and fast database for message data. The
route object is also tied to the concept of indexing – it will send data out of a specific outlet based on the index (first entry) of a list.
Indexed data is very useful for complex routing of information. Often data is already indexed for you: MIDI controllers normally index the value with the controller number, while note information is often indexed by the MIDI channel. Using indexing for data can also help when sending messages throughout a complex patch – by creating an indexing system, you can send data around indiscriminately, and have the
route object find and decode the data as necessary.
There are several small- to medium-sized patches scattered throughout the interface for this tutorial. We will be starting with the patch at the top-left side.
The first patch (labeled
1) introduces the
coll object. Three
message boxes are connected to it. If you click all three, you will load the
coll object with three value sets. The easiest way to see what is stored in the
coll is to double-click on it; it will open an editing window that will show you that the first number was stored as an
index, and the second number was stored as a
value. To programmatically retrieve a value, you send an index value into the inlet – the output will be the value (or values) stored at that index location. If you use the
number box to send a
0 to the
coll object, it will output
20 (the value at index location 0);
1 and
2 will output
-50 and
33 respectively. This is the most basic, and most common, use of the
coll object – as a storage mechanism for indexed value sets.
The patch labeled
2 is slightly different in that it uses
symbols, rather than numbers, as the index value. Click on the three
store message boxes, and again double-click on the
coll to see the stored data. The data is similar to the first
coll, but the indexes are symbols (words) rather than numbers. Now, if you click on the
message boxes to the left (
foo,
bar,
biz), the
coll object will output the correct value for each of the symbols.
The third patch (labeled
3) has already-stored data in it. If you select any number between
0 and
3, the
coll will output the data for that index. In this case, rather than a single number, the
coll is storing a string of symbols (in this case, the opening soliloquy of Shakespeare's
Richard III); all of the symbols are output as a list. Prepending a
set message to the list allows us to display the value string in a
message box.
In order to store the data within the patcher (as we’ve done with this example), you have to set an attribute in the
coll object's Inspector. Unlock the patcher, and open the Inspector for the
coll in patch 3. You will notice that the attribute labeled “Save Data With Patcher” is selected. When this attribute is set, any information stored in the
coll will be written to the patcher file when it is saved, and is immediately accessible when the patch is opened again.
The center section of our patch (section
4) uses a
coll to control both a drawing and a MIDI playback function. In this case, the
coll is loaded with some pre-defined data; however, instead of having been stored in the patcher, this data is loaded from an external file containing data from an EEG readout. The filename is “eeg.txt”, and that filename is used as the argument for the
coll, so the data is read into the
coll when it is first initialized.
At the top of the patch is a simple little “self-incrementing” counter system. Each time a number is generated, it increments itself by an amount determined by the upper-right
number box. By default, the increment is one, since that is what the
+ object contains. Playing through the data set at this speed, however, can take quite a while, as our data file contains many thousands of lines. If you change the
number box to
15 (meaning that you increment the steps by
15 at each
bang generated by the
metro ), you will see the EEG pattern much more clearly. The output of this number generator is used to retrieve the indexed data from the
coll, and is sent to both the
drawit subpatcher and a simple MIDI player (
makenote/
noteout). The MIDI player just uses the number (scaled to the
0-127 range of MIDI) as the MIDI note, while the
drawit subpatcher uses the incoming value as the vertical offset of a scrolling drawn circle. Start the
metro (with the
toggle) and notice how different "increment" values for the counting change the way the EEG data unfolds. If you need to restart the file at the beginning, the
message box labeled
0 will reset the
int box to
0 again.
Storing data into a
coll for later use is the best way to deal with large datasets. This EEG capture, which represents over 18,000 data points, would cause your patcher to be very large if it was stored in the patcher's file. Instead, the data can be captured into a
coll, saved in a text file (using the
write message), and read into the
coll at runtime (used either as an argument, or using the
read message).
The next patch segment, labeled
5, shows a few more tricks that
coll has up its sleeve. This
coll has a name –
cues – that manages 8 different cues handled by the rest of the patch (double-click the
coll object to look at what's stored inside). You can use the connected
number box to fire off the messages, but you can also use the three
message boxes to walk through the cues. The
start message moves you to the beginning of the
coll contents, while the
next and
previous messages move forward and backward through the cues. This allows you to step through the
coll in sequence, even if the entries are not numbered sequentially, and will automatically loop back to the start when the end is reached. This is the easiest way to implement a sequential step-through of a
coll’s contents. Without worrying about the
route object just yet, step through the sequence using the
start,
next and
previous messages and observe how different actions are triggered by the output of the
coll object.
There is also a small patch just to the right, where another
coll is also named “cues”. If you double-click on this
coll, you will see that it has the same contents. In fact, because it is
named the same as the previously viewed
coll, it is actually sharing the contents of the
coll – much like the
value object shared data through a naming convention. Using named colls that share their information allows you to have easy access to a dataset in different places in your patch, or even within subpatchers.
The small patch in the lower-right shows the functionality of the
route object: as you click on the
message boxes, the messages are matched based on their identifier (the first item in their list); if the identifier matches one of the arguments to the
route object, the message is stripped of its identifier and the remaining data (in this case, an integer) is sent out the outlet. The
route object has one outlet for each argument, as well as a final outlet for items that don't match. This patch shows what happens if an unrecognized message is received: the
zeppo message is not enumerated in the
route object, and therefore cannot be routed. Rather than ignoring the message, it sends the entire message out the right outlet – possibly to be used by another
route object, or perhaps to be sent (as we have in this case) to the Max window with the
print object.
Patch segment
5 also uses the
route object to take messages from the
coll and parse them to perform actions on different objects in the patch. As we saw inside the
coll, the data contains a symbol (
m1,
m2,
m3 and
pick) and a data item (
0/1 for
m1-m3, and
bang for the
pick symbol). When this message is received by the
route object, it uses the
first element (the symbol) to determine the output routing, and sends the rest of the message through that outlet. Hence, a message that begins with
m1 will be routed through the first outlet, while a message that begins with
pick will be routed through the fourth.
If we use the start and next messages to walk through the cues
coll, we will see that a sequence of actions is performed based on the first segment of the message. The
metro objects are started and stopped, and the
random object is triggered twice. You can see that the
route object is useful for taking undifferentiated message contents and routing them where they might be useful.
The
coll object is a powerful way to work with indexed messages and data; the object provides way to get specific messages or to step sequentially through the contents. You can share the contents between named
coll objects – letting you have access to this data throughout your patch;
coll can also read its data from external files. We also saw how the
route object allows you to track and move messages based on the contents of the message, helping you to route the data that you need to different objects based on an index.
See Also
Name |
Description |
coll |
Store and edit a collection of different messages
|
route |
Selectively pass the output out a specific outlet
|