The LOM.Navigator is a Max for Live (‘M4L’) device which I created to make it easier to navigate through the so called Live Object Model (‘LOM’). The LOM is basically a road map which shows you how the several Live objects are related to each other and how you can access them.
For example; say you want to access a clip in the session view. The first thing to determine is your starting point. In this case this is the Live set which is currently active. Now, your Live set will most likely contain several tracks. You have the regular audio and MIDI tracks, the return tracks and a master track. So the next ‘hop’ towards accessing a clip is determining on which track it resides.
In the “session view grid” you’ll notice colored ‘blocks’ which indicate some kind of material being present and the regular ‘greyish’ blocks which indicate that nothing is present. These greyish blocks are so called clip slots. Each slot can hold a clip. So the next step towards accessing a clip is determining in which clip slot the clip is located.
And then, finally, we’ve reached our destination. This whole route is shown in the so called LOM Chart which you can see below. Note that this isn’t the complete chart, I cut out the bottom section which covers control surfaces because these work a little different. I’ll explain more about accessing control surfaces below; in the section which covers the LOM.Navigator itself.
The most important thing in working with Max for Live is understanding how you can read the above chart; if you grasp that concept then you should have no problem anymore to access anything you want. Even when using “arcane” routes.
Let’s re-trace the example I’ve illustrated above: accessing a clip.
The LOM knows several root objects, two of them are displayed above. In our case we obviously need the “live_set” root node. This gives us direct access to ‘Song’. Song is a so called class object. Think of a class object as a portal which gives you access to everything around it as well as a doorway to all of its children.
For example; the Song class symbolizes your whole Live set. As such it gives you access to tracks, scenes, cue points and so on. You can see as much by merely following the lines in the diagram. These lines show you the so called children.
But ‘Song’ also has its own properties and functions. A property is basically a value which can tell you something about the class itself. For example; the Song class knows properties such as “current_song_time” which indicates the current playing position. Or “tempo” which indicates what the current tempo is.
Functions on the other hand are best approached as being ‘commands’ which you use to tell the current class to ‘do’ something for you. For example; Song knows functions such as “continue_playing”. This tells the Song to… you guessed it; continue playing from the current position. Or “is_cue_point_selected”; this commands Song to tell you if the current playback position is at a cue point (in the arranger).
From Song to Track(s)
As you can see in the diagram above there is a child called “Tracks” which leads us to the ‘Track’ class. Notice how the line ends in a small trifork? This indicates that we’re dealing with a so called “One to many” relation.
Sounds difficult but its not: One (single) live set usually contains many tracks; “One to many”. So in order to get to the right track we need to specify which one we need. That is what this indicator is telling us: the child “tracks” has many members and you need to specify which one you want.
The next step is “clip_slots” where the same logic as above can be applied. One track usually contains many clip slots, thus here is another “One to many” relationship.
Now we’re almost there but there is still something to be aware off. Notice how the line between the ClipSlot class and the Clip class is bold and dotted? This tells us that we’re dealing with an optional relationship. Its easily explained too: a clip slot doesn’t always contain a clip. If there’s no clip present then obviously you can’t access it.
If you keep these simple “rules” in mind when working with the LOM then you should be perfectly fine.
I originally made my Navigator because I considered it quite tedious to always having to keep the original LOM chart around in order to find whatever I needed. And when I started using it I also quickly learned that some of the documentation is incomplete. For example; the ‘color’ property of the Track class isn’t mentioned in the documentation yet, but still discoverable using tools such as my Navigator.
The interface is setup to make navigating as easy as possible. As I explained above you first start with a so called root device. From there you can select a child device. This section has 2 menu’s because of the sometimes occurring “One to many” relationships; in that case you need to select a specific child object using the 2nd (smaller) menu. And finally there is the section which gives access to the properties and functions.
Let’s start by looking at the root devices, there are 4 in total:
- live_app – This gives you access to specific information about the Ableton Live program (‘application’).
- live_set – This gives you access to the currently loaded liveset (‘Song’).
- this_devices – This also gives you access to the current liveset, however the navigation starts with the M4L patch itself (I’ll demonstrate this later in the tutorial).
- control_surfaces – This gives you access to all the control surfaces which you configured within Ableton Live. (I’ll go into a little more detail later on).
After you have selected a root device you can then proceed by selecting one of its child objects. The child section contains 2 pull down menus, this is to get access to any “One to many” relationships (see my LOM explanation earlier).
Selecting a Child object
After you selected a root object you navigate further by accessing its child objects. I already showed you how to select the root object. In order to get access to the liveset we need the “live_set” root object. Note that this root object will be selected by default (as soon as you drag the LOM.Navigator into your liveset).
Next we need to start by selecting one of the child objects. First you need to select the right child from the menu on the left, you can see an overview of all the children of the Song class in the left picture. First it shows you the name of the child followed by its class. As you can see “Tracks” eventually leads us to the Track class, but a liveset’s master track does exactly the same.
As a rule of thumb: whenever a child object refers to a multiple (“tracks”, “scenes”, “visible_tracks”) you’re dealing with the previously explained “One to many” relationship. Which means that you need to specify which child you want using the smaller menu on the right side (see the picture on the right). It will fill up with all the available child objects so all that’s left to do is select the one you need.
My liveset only contained 2 tracks; an audio track and a MIDI track with an Operator instrument on it. As you can see it starts by showing you the number of the child object followed by its full name between brackets.
Keep in mind that the number is simply that. Max for Live counts these objects differently, namely starting from 0, but to make this as accessible as possible I decided to use normal numbers in the menus. So if you need to access the second track then you simply select track number 2.
Note: If there is only 1 entry in a “one to many” relation then the LOM.Navigator will automatically select it for you. For example: if you have a track with 1 device on it and navigate from Track to Devices then it will be automatically selected. If the track has two or more devices then these will be shown as demonstrated above.
After you selected the right child object you’ll notice that the displayed path at the bottom changes; this shows you the current location using the path notation as its being used in Max for Live. So although I selected the 2nd track (MIDI track with Operator on it) you can see that the Max for Live path mentions “tracks 1”.
Properties and functions
Every class will have a selection of properties and also some functions associated with it. Properties are usually used to get or set specific values. Keep in mind however that not all properties can be used to set a value. For example the “is_visible” track property indicates if a track has been hidden which could be the case with return tracks, or tracks which are part of a group. However you can’t use it to actually hide a track yourself.
The Navigator can be used to show the value of a Class’ properties as well as set them. Note however that the Navigator does not check if a property can actually be set; it will simply try to set the value and ignore any possible errors.
To change the value of a property you must start by selecting the property you want. In the picture on the left you can see all the properties of the Track class.
Properties are displayed by their name followed by their object type. So ‘arm’ is of type ‘bool’ which indicates a so called Boolean value. This means that this value can be true or false; a track can be armed or unarmed.
Next you have integers, floats, unicode, etc.
After you select a property its name and value will be displayed in the property field as follows:
Here I selected the “is_visible” property and as you can see its value is ‘1’ meaning that the currently selected track (see the path at the bottom) is indeed visible. Note that if you now would like to check the value of a different property then all you need to do is select it from the properties menu. Because you haven’t changed your location nothing has changed in the Navigator. This makes it easy to quickly check up on multiple properties.
Apart from displaying a properties value the Navigator can also change a property (if applicable, see above). In order to do that you simply need to click on the property value button when it shows you the value of a property. After you did that an input dialog will appear where you can enter the new value:
Note that the input dialog can appear anywhere on the screen, and if you want to you can also drag it to another location. In the dialog you can enter a value and press OK, after that the Navigator will try to change the value of the property. This new value won’t be displayed in the properties window; if you want to make sure that the value has changed then either look at some indicator changing (for example when you change the ‘solo’ or ‘is_armed’ property) or simply select the property again from the property menu.
Functions work in the same way as properties, except for one small difference. As you can see in the pictures you select a function just like you select a property. The big difference however is that a function will not be called or become ‘active’ after you selected it. I implemented that behavior as a form of precaution; because there are functions which can give some very unwanted effects if you select them by accident. So in order to use a function you must first select it, then click the round ‘call function’ button at the bottom. After you did that the function will be called and if applicable you will get to see a return value appear in the field behind the button.
Sometimes a function needs a parameter to work properly. A good example of that is the “set_fire_button_state” function which is associated with the ClipSlot class. This function is used to trigger the fire button of a clipslot. Usable when you want a MIDI clipslot to start recording.
This works basically the same as when dealing with a property. First you select the function as above, but before you press the ‘call function’ button you need to click on the function value field behind it. A same dialog will appear as shown above with the properties. Enter a value, click ok and then click the ‘call function’ button.
Now the function will be called with the value you entered as a parameter.
Keep in mind that just as with the properties the Navigator does not check if a function actually requires or can use a parameter. So use this at your own risk / discretion.
Navigating “up the ladder”
If you selected a class, say the ClipSlot class, and now wish to select something else (perhaps another track or another ClipSlot) then there are 2 things which you can do.
First you can simply start all over. So select a root object, then the right child object and continue until you’ve reached the object which you wanted to access.
Another option is to use the “canonical_parent” child object which most class objects have (root objects obviously do not have this child since there is nothing ‘above’ them).
In a regular situation the ‘canonical_parent’ child will show you the object “before” or “above” the one you have currently selected. So if you have the ClipSlot class selected then the canonical_parent will be the Track class; a track contains the clip slots after all. You will notice that this child will always show the class which it points to behind its name.
A very specific use for this child object is in combination with the “this_device” root object. As I mentioned earlier this root object will start the navigation with the current M4L patch. Here you can see to what class the canonical_parent child points when the device is sitting on a track or inside an instrument rack.
A track can contain devices, such as instruments or effects. In the above example it contains the Navigator. Thus the canonical_parent is the Track class. But when placed inside a rack you have an extra ‘layer’ to content with; a rack device contains one (or more) chain classes. As such the canonical_parent when sitting inside a rack is the so called Chain class.
Ableton Live provides support for control surfaces through the use of so called control scripts. These scripts reside in the directory “Resources \ MIDI Remote scripts” which you can find inside the Ableton Live program folder.
When you access a control surface you’re basically navigating through whatever the control script for that surface provides you with. This is also the reason why you can easily access a control surface using the Navigator, even if the device has been turned off. That’s because all the Navigator does is access the control scripts resources (classes, properties and functions) and as soon as it tries to access a property or call a function only then will the control script try to access the device directly.
Accessing control surfaces works almost the same as accessing regular classes or properties which I’ve shown above, however there are several differences to keep in mind.
For starters: you’ll notice that the interface has turned yellow. This is to warn you that you’re currently accessing the control surfaces section. As you can see in this picture the start is also different because you need to begin in the “One to many” child section. That’s because control surfaces work quite different than the rest. In my case I have both the APC40 as well as an MPD24. However; both are root objects, just like the “control_surfaces” class itself is.
That is why you have to start here; once you select a control surface then the only way to select another is to start by selecting the “control_surfaces” root object again.
The other difference can be seen as soon as you have selected a control surface and then selected one of the available child objects, this can be seen on the picture at the right.
There are basically 2 major child objects: Components and Controls. The only problem is that there are often lots of them, especially with control surfaces such as the APC40 or Launchpad. So it takes some time before the menu on the right is fully filled with every available component or control. That is why the menu will flash red when it is being filled up. As long as its red you’ll know that a little more patience is required.
Note that you can easily open the menu if you want to. Just don’t expect everything to show up there at that time. If you simply close and re-open the menu you’ll see that many more objects have been added.
After you selected a control or component you’ll notice that the children menu remains empty. That’s because there are no real relationships which can also be seen on the LOM chart above.
Just like within a liveset you still have access to properties and functions. One property is special though: the canonical_parent. This property basically provides access to the parent class even though there is no real relationship.
Be careful with accessing functions and properties!
The properties and functions of the control surfaces often behave much different than those in the liveset. So be extra careful when using this part of the navigator because I cannot rule out if some of the changes you make here could become permanent.
For example; some control elements have the “disconnect” function. Calling this function will result in the specific element no longer responding to user input. So say you use this on “control_surfaces 0 controls 0”; this is the shift button on the APC40. That would result in the shift button no longer working until I turn the APC40 off and back on again.
While this change isn’t a permanent one it is one of the reasons I’m sending out this warning since you can never be too careful.
So once again: be careful with accessing these!