Controlling Live with Max for Live Lesson 2
- Live Versions: 9
- Operating System: ALL
How Can I Control Live's API In Max for Live?
Having learned how to find the path to a parameter in Live's API, this article will now demonstrate how to observe and control these parameters.
As you might remember from the last lesson, the path we provide Max for Live to direct it to the volume parameter of track 1's volume is:
path live_set tracks 0 mixer_device volume
We send this using a message to a live.path object as follows:
The live.path object takes the directions we give it and returns a unique ID number (out of its second outlet) for the parameter: track 1, mixer volume. We can now use this ID (in this case id 3) to control or observe the volume.
If you hover your mouse over the first and second outlets of live.path, you will notice that the first one "follows object", while the second "follows path".
Generally, it makes more sense to choose the first one. Why? If you build a Max for Live device that follows the path and drop this on a Track in Live, it will work as expected the first time. However if you then change the Set in any way, for example dropping another device before the Max for Live device or adding a Track before it, the ID will no longer address this parameter.
Obtaining the ID from the "follows object" outlet overcomes this issue as the ID will always be linked to that device, regardless of where you move it or what you change in your Live Set.
Once provided with a valid ID (as above), live.object can be used to control the accessed parameter (in this case, track 1’s volume). We can test this by hooking up a simple slider object to it.
The slider, in conjuction with a set value message, tells Max what value to send to the parameter:
Note that in Max for Live, we often deal with changing values. Using $1 means that the slider value, which is an arbitrary number (known as a replaceable argument), is passed through.
$1 means the first input to the message ($2 would be the second input, etc).
If the slider outputs a value of 25, this message will become "set value 25".
We can see that controlling Live from Max for Live is made very easy.
In some cases, we may not wish to alter the values of a parameter, it might only be necessary to listen to them so we can then do something with their values.
Take the slider for example. We can now use Max for Live to change the value of the volume of Track 1, however when we change the volume of Track 1 in Live, it doesn’t affect the slider in Max for Live.
It would be nice if Live controlled the slider in Max for Live and vice versa, to give us some visual feedback of what's happening.
For these cases, we would use live.observer which actively monitors any change in values of Live objects.
live.observer works quite like before, passing it a valid ID (obtained from live.path) directs it to the parameter you want to listen to.
After we have configured live.observer with the object ID from live.path(so that it is focused on a parameter) we can send it the messageproperty value to tell it to output the value of the parameter it is focused on.
Below is a patch that uses a combination of all these objects to allow a slider in Max for Live to control a Track's volume in Live (and vice versa). We can see that we have it set in such a way that we can both control Live from the slider in Max for Live, as well as represent any changes made in Live.
The first step in our patch generates the parameter ID using live.path, and is then fed to a trigger object, t for short.
In Max talk t b l l is a short way to say Trigger Bang List List
In the real-world this means:
Take the incoming message and send it to 3 outputs, in the form of 2 lists and a bang!
The trigger object takes any input, and sends it to many outputs, formatted according to the object-argument specified, in this case a list, another list, and a bang.
This allows us to do a few things at one time. Let's begin by looking at the list outlets.
The incoming message is our parameter ID. As before, this ID number addresses the parameter we have provided the path to. Since we want to both control the parameter in Max for Live, and to check if anything has been changed from Live, we can save ourselves some time by sending the same ID to both live.observer and live.object.
Max executes messages from right to left, so the order in which the messages arrive allows everything to work in the correct sequence.
Timing is a very important factor to consider when creating patches. If you want to learn more about Max message ordering, have a look at this dedicated tutorial on the Cycling '74 website.
Let's run through the cycle to see what's happening:
Step 1: Using the LOM, we worked out the path to the parameter we want to use. We then send this as a message to live.path.
Step 2: Our live.path object creates a unique ID number from this path message, and sends it on to the trigger object.
Step 3: The trigger takes this ID and sends it as a list out of the right outlet, down to our live.object, below, pointing it to the parameter we want to deal with.
Step 4: The trigger next sends the same ID from the middle outlet, to live.observer, also making this aware of the parameter we want to 'listen' to.
Step 5: Finally, the trigger sends a bang, triggering the property value message. This sends the message to the live.observer object. The messageproperty value tells live.observer to output the current value of the parameter it is listening to.
Now we have learned how to use the LOM and the related Live API Max for Live objects.
We will now take a look at API functions, where we can build a Clip Launcher, in the final lesson: Controlling Live with Max for Live Lesson 3.
Max Object References