20Concepts Lesson 05 - Time
(Needed: Example Video)
So far, everything that we've done has required user action (mouse clicking, dragging or text entry) in order to generate events. But Max is often used to generate event. This tutorial will be all about generated events, with a variety of objects that are made for that purpose.
Max Time - An Introduction
Generally, time within Max is measured in milliseconds - 1/1000th of a second. A millisecond is a useful timeframe for most media types; for example, video frames are generally produced around 1/30th of a second (33 milliseconds). In this tutorial, we are going to look at the main timer system provided by Max, the metro object, and some new objects that help us make useful, automatically-generated systems.
The metro object is the most popular way to generate events. Given a time interval, it will create bang messages in a metronomic fashion (which makes sense, given its name). Create a patch like this:
(Image: Simple metro patch)
The argument for the metro object is the interval between bang message in milliseconds. Since millisecond is 1/1000th of a second, the argument of 500 represents a half-second interval. Click on the "1" message box to start the metro output, and click on the "0" message box to stop it. The metro object uses numbers rather than symbols (like "stop" and "start") to turn it on and off, allowing us some flexibility in the objects we can use for the on/off function.
You probably noticed that there is a second inlet to the metro object. As you may have already guessed, this inlet allows us to change the metro's event interval with a numeric entry (such as a number box). Let's connect an integer number box to the metro to see how it works:
(Image: Metro patch with numeric interval)
Now you can change the interval by entering a new value into the number box. Very small numbers will create very fast pulses (in some cases, faster than the output button can display them), while very long intervals create very slow output times. If you are used to working with "tempo" for timing, you may find this counter-intuitive. However, it is important to remember that this is "programming", and programs prefer to work with interval timing.
One object that you will see next to almost every metro is the toggle object. This is a checkbox-like object, and outputs a 1 when turned on and a 0 when turned off. You can see why this would be useful for metro - that is exactly the message that the metro needs to turn it on and off. Let's replace the message boxes from our earlier patch with a toggle object:
(Image: Metro patch with toggle)
This patch is a lot more obvious, and makes our patch more user-friendly. The toggle object has another, less-obvious function: when it receives a bang message, it will reverse its current setting. Connect a toggle to the output of the display button, turn on the metro, and watch the toggle change its state:
(Image: Metro patch with bang leading into the toggle)
Now, creating bang message can be useful, and we can connect this to other objects to create generative work. However, there is nothing built into the metro object that lets us know how long it has been running, or keeps any sort of count. For this, we need to learn about another new object: the counter object.
As this object's name implies, it counts things - bang messages, to be precise. Each time the counter object receives a bang message, it will increment its internal counter and output the new value. Here is a simple example:
(Image: Simple couner patch)
The counter object takes a varying number of arguments, based on what you need to tell is. If you give it a single numeric argument, it will count from 0 to the number you enter:
(Image: One-argument counter patch)
If you give it two numbers, it will count starting at the first value until it reaches the second value:
(Image: Two-argument counter patch)
Finally, if you give it three values, it will use the first as a "direction" flag:
(Image: Three-argument counter patch)
The direction flag supports the following options:
0 = "up": counts upward from the low value to the high value, then resets.
1 = "down": counts downward from the high value to the low value, then resets.
2 = "up-down": counts upward from low to high, then downward from high to low.
Hint: If you want a little pop-up menu to display these options, look in the counter help file...
In addition to using arguments, you can also send messages to the counter object to change its settings, or use some of the inlets to directly control the current counter value. Let's make a patch let's us check how this works:
(Image: Counter-to-numberbox patch, with values coming into inputs)
The left outlet of the counter object sends the value, which we show in the number box. The other outputs of the counter are for tracking the "carry" flag - the flag that shows we have hit our maximum. We won't use this in our example, but the counter help file can show you how it is used.
The combination of metro, toggle and counter provide many of the tools we need to have Max generate events for complex Max patching. If you start investigating other people's patches, you will see these few objects at the heart of many of the most interesting programs. We will be using these objects constantly throughout the rest of the lessons, so make sure that you know them cold! Also, remember to dig into the help patches so that you understand the nuances of the arguments, inlet and outlet use, and potential output messages.
- A handy time converter: UnitConversion.org
- Create a patch that uses a metro to produce the following phrase: "The metronome is producing bang messages every NN milliseconds.", using the current interval setting.
- Create a patch with several metro objects. Have each metro start with a different interval, but connect them together so that they turn each other on and off based on their bang outputs affecting toggle objects. You may also want to intersperse some delay objects throughout the patch to alter the timing.
- Create a metro/counter combo that runs between 10 and 20, and prints the phrase "The current counter value is NN." each time a number is produced. Hint: Think about using replaceable parameters to do this.