I’ve been working with Max for Live (“M4L”) and Max/MSP for quite sometime now and well, now that I’ve ‘finished’ my latest patch (at least until the next good idea for a new feature) I think its time to talk some more about it. I’ll try to easily move this entry from beginner to more intermediate, but if I fail you can always leave a message
What is Max for Live, heck; what is ‘Max’ ?
Well, under normal circumstances I’m always a bit careful with my words, but since this is my blog… Max for Live is pure raw power ready for you to unleash on your Ableton Live environment. Once you get more experience using it you might never want to go back to a “non-Max’ed” Live. If you want to do something which Live cannot do then there’s a good chance that M4L gives you the extra edge allowing you to simply make it happen anyway.
Ok, more seriously: Max is a visual programming environment developed by Cycling ’74. As a programming language its totally different from anything “regular” because you’re not so much programming by writing lines of code, instead you’re placing several kinds of objects on a screen and connect them using cables. As an environment however it shares some of the characteristics of Java; in order to be able and use programs for Max or Java you need to have a so called runtime installed on your computer. This is a program which allows you to execute (“run”or “start”) programs developed for it. So; with a Java runtime you can use Java programs. And with a Max runtime you can use Max programs.
Max is a language which is fully focused on multimedia. The way of programming itself somewhat reveals this since it sort of mimics the process of programming a modular synthesizer with patch cables. It has native support for Midi, Rewire, sampling, and so on…
Max for Live is basically what the name suggests: Max integrated into Ableton Live. In order to blend into Live Max has been extended with support for many native Live devices. As such it allows you to create instruments and midi or audio effects which will perfectly blend into Live. Another very nice feature is that Max for Live will also allow you to control or change many aspects of Live, but more on that in a later post. For a nice overview of M4L just see this introduction movie:
Some Max for Live tips & tricks
Now, there are a lot of very cliche issues when it comes to learning and using M4L. It has a rather steep learning curve, even though the documentation is excellent. Excellent or not; as always things take time to get used to. But I’m not going to write about stuff which I consider obvious, that’s boring. So yes; you’ll get the most out of M4L by checking the tutorials, making yourself familiar with the documentation (‘help patches’ and reference pages) and knowing several keyboard shortcuts from the back of your mind goes a long way too. Just for fun, its what I can recall from mind and use very often: ‘n’; new object, ‘l’; new Live object, ‘m’; new message object, ‘c’; new comment, control-shift-i; call up patcher inspector, control-i; call up inspector for selected object, control-shift-r; call up reference page for selected object, control-alt-e; switch between presentation and patching mode, control-e; lock or unlock your patch, and so on…. I forgot 2 very handy shortcuts here: alt-click on an object and get an example patch (I use this option less and less now) and finally; control-double-click on an object for interesting results. A sub patcher (‘encapsulation’) will open when your patcher is unlocked, on a send/receive object it will allow you to easily find its peers, and there’s probably a lot more. Like adding / removing objects from presentation mode by pressing control-shift-p and control-alt-p.
Anyway, some uncommon Max/M4L tips coming up, here we go…
Don’t blindly follow examples; study and question them.
May sound arrogant but just because it was written by someone else doesn’t make it the perfect solution. Better yet; just because it seems everyone uses a certain style also does not automatically make it good. You’d be amazed how many people will blindly follow and adopt an example simply because it works for them without ever stopping to wonder why or if it could be improved.
Take for starters the example on the right. A regular way to access a live.object is by specifying a path using live.path and then using a ‘trigger’ (“t”) object which connects to both a live.object as well as a message which then gives the live.object a command to perform.
Yet this example shows you something totally different indeed; guess you don’t need that “t” object after all eh?
So like; why doesn’t this seem to work for the last 2 entries (I didn’t include error messages here) after a single click on the first message object ?
Really; this is the way to learn stuff and gain experience. And don’t mind that ‘set’ message object, I’ll get to that later on.
Don’t rely on M4L abstractions for anything else than examples!
Oooh, I can see this going to get some people worked up Seriously; if you’re working with M4L don’t waste your time with thinking “what M4L abstraction might do what I want”. That stuff is just too simple for that; you will save a lot of time by merely doing it yourself.
Ok; strong words… SO.. Lets say we want to get ALL devices within the current live set. No worries; we have the M4L.api.GetAllDeviceIds abstraction ready for usage. Errr, one problem; it requires input of all currently available tracks. Now; maybe there’s an abstraction to get those too? Waste of time and energy right there!
Now, what you see on the left isn’t some fancy “abstraction”. Instead its merely a one on one copy (apart from one object) of a patch I made to grab all tracks.
In general and in the long term you can save yourself lots of time by not relying and/or trying to search for some “ready made” solutions (from the Max window: Extra’s menu -> M4L.api.ListOfAbstractions) but instead write ‘m yourself! You’ll gain more experience, learn more about Max AND save lots of time in the longer run.
Where other people started looking for the previously mentioned M4Labstraction I wrote it myself. Then when they started wondering “how do I come up with a list of track ids?” I merely copied the patch I wrote before and altered one object to do just that. After changing one small part it turned into the patch you can see on the left.
Difficult ? I only changed “get tracks” into “get devices”, how difficult can it be ?
Its the same issue all over.. My main background when it comes to programming is Java. A language which is also modular build just like M4L. See the the so called API documentation (sorry if the link suddenly doesn’t work; I’m following the old Sun Microsystem URL and totally refuse to commit to “Whoracle standards”).
Yet; if the link worked for you you’ll see many “classes” in the lower left window. Just think of a ‘class’ as a M4L component which can be seen on the left just ready for usage. So many classes, so many options…
And still people go on about not being able to find class X which should do option Y. My stance on all that? I am generalizing and very well aware of it but really; if you can’t find something right: do it yourself !
Too many times have I seen people struggling to find Java solutions which were only a few lines of code away…. A waste of time and effort in my book.
Keep your patch clean, commented and tight!
And this goes double if you plan to continue working on some of your patches. The problem with programming is that if you’re working on something you’ll know exactly what you did. Most of all you’ll know why you did it too. After you leave a patch lying around for a couple of weeks (or months) and then open it up again chances are high that you’ll need to check upon those details again. No problem for a small patch, but what about a huge one ? Before you know it you’ll spend 2 out of your 3 available hours on re-inventing the wheel you build yourself!
I (try to) work by applying 3 simple rules:
1) Chop up your work (“Divide and conquer“).
When I wrote the patch I mentioned in the previous tip I was actually working on the patch you see to the right. Notice the 2 sub patches (‘encapsulations‘) called get_tracks and get_devices ?
Patches shouldn’t turn into a big mess of objects and patch cables; it makes them harder to read and most of all much harder to expand on. Instead try applying some logic right from the start.
To me the main patcher should only handle global logic as well as the user interface. Nothing more. So in the case of the patch here the logic is easily followed: it gets all the tracks from a liveset, then sends this data to a patch which gets all devices and that data is then send to a patch called dev_proc (which stands for “device processing”). Simple huh?
You can create sub patchers by using the “patcher” object. Just create a new object (press ‘n’) and then type p followed by a name.
Once you pressed enter a new patcher window will open which then allows you to populate it with the objects you need to make it work. The “inlet” and “outlet” objects allow you to create ‘connectors’ for input and output (see the screenshot in the previous tip; the objects with the number ‘1’ in it) and after that you’re all set to go.
2) Commenting your patches; it goes a long way.
When I wrote my most difficult patch to date (the so called LOM.Navigator) the most important thing for me was to make sure its work flow would be as easy to follow as possible. Especially because I knew I wasn’t going to write it all at once; the main basis (Navigator 0.9 beta) took me one evening (say 3 – 4 hours) to finish. But there have also been weeks between the moments I actually got to work on it some more. Without proper documentation I might have needed to open up all my sub patches one by one to see what they did and how I should use them. And I’m not talking about simply flooding your patch with comment objects; that in itself might create a new mess.
Here you see the main patching screen of the LOM.Navigator. I just hoovered the mouse over the “control_surfaces” sub patch and as you can see a hint text appears which tells me exactly what this sub patch does.
That is the kind of documentation I’m talking about. With big patches like these (the LOM.Navigator has 10 sub patches in the main screen you see here) it just would take up way too much time to open up a sub patch every time you want to know something about it.
As a sub-hint, also considering using colors to separate different sections of your patch as well. This will make it a lot more easier to follow the applied logic in your patch.
But there are 2 ways to provide good documentation for your sub patches. When using sub patches you should also consider documenting its inlets and outlets as well. The result can be seen in the picture here.
When you hoover your mouse over an objects inlet or outlet a red circle will appear as well as a pop up message which tells you exactly what you need in order to use it. In case of an inlet you usually get to see what kind of messages can be used whereas an outlet shows you what kind of data is generated.
Every object in Max supports this behavior, and this can make your live a lot easier.
So I think its only natural that you should consider doing the same for any sub patch you create. It will save you a lot of time in the longer run. And lets not forget about situations where you might be able to use a subpatch in a completely new patch.. At least you’ll always know what it does exactly.
So how does one provide documentation like this ? That’s easy…
All you need to do is to select a patcher object and call up its inspector, like I’ve shown on the right. Click on the hint tab and just provide any information you want to share about the behavior of the patcher object in the hint field.
After you’ve done so this text will appear as soon as you hoover your mouse over the patcher object. Do keep in mind that this only works when your patcher is locked, in an unlocked state nothing will happen during ‘hoovering’.
Another quick sub-hint… If you do use comment objects to provide your patch with documentation, consider making them part of the background. On the “Appearance” tab there is an option “Include in background”. While this doesn’t appear to do anything special it actually allows you to make Max consider those objects part of the background and as such won’t allow you to select them by clicking or dragging a selection field.
This can make it very easy to provide certain information without risking that you’ll accidentally delete or move it. Once you’ve placed objects in the background, you can use the “Lock background” in the View menu to actually lock these objects (or press control-alt L).
Commenting inlets and outlets is also very easy, as is shown here…
As can be seen here you need the “Behavior” tab here to provide a comment. A hint, as can be seen above, is something which appears when you hoover over an object. But in this case you’re not really hoovering over the inlet object, but over its manifestation. So providing a hint won’t cut it, you need to change its behavior. And that’s where the comment field comes in.
The style in which you provide a comment is entirely up to you. Personally I like to mimic the style which Max applies itself. So I start by specifying the kind of data which is required (or sent) followed by a dash (-) and a short description on the why and how.
For me this is the best way to keep up with the way my sub patches work, and it will make sure that even if I copy and place a sub patch in an entirely different patch I’ll still be able to see what it does and why it does it.
3) Take care not to clutter your cables…
In order to understand what a patch does one needs to be able to follow the signal flow. Obviously this is a rough thing to do when you allow the cables to go everywhere and no where. Personally I also prefer the cables to get colored in order to indicate what kind of data is being send out. But apart from that I’d suggest to always lay out your cables in a decent way. Look at the example below; would this patch be easier to check up on ?
And it doesn’t have to be too hard to do either. Just keep shift pressed before you click on an objects outlet and after that the cable will snap in a vertical position and allow you to create bends as well. Just clicking on a place in your patcher window will create a new cable junction.
Keep your message objects clean in the final result, ‘set’ is your friend..
I’m often using message objects, especially when I’m working with data which needs to get ‘constructed’ before it gets used. For example when working with live.objects; often the command which I want to give them gets constructed by my patch itself and setup in a message object. When its done a mere bang signal is enough to make it send out its value which can then be used.
Now, its very tempting to simply leave those objects as they are considering that their contents are “dynamic”. In other words; their contents will be created automatically, so who cares what their current value is ?
Yet I’ve discovered that in more complex patches sometimes a pre-filled message object can make your patch behave inconsistently. Remember that set message in one of the screenshots above? I always keep a set message object around the very moment that I’m working with “dynamic” message objects. I’ll test, use and study the results of my patches but the moment when its time to save my work for a final release I always use ‘set’ to clean out my message objects one by one, after which I remove the set message object itself as well.
This is the best way to make sure that your patch doesn’t suddenly start behaving in an inconsistent manner.
When working on a sub-patch, save its current status for easier access…
As you may know by now I’m always heavily utilizing sub-patchers to keep my patches more manageable. However, when working on a subpatch it can be quite tedious to having to open it up every time when you’re opening your patch in edit mode after testing it in Live. This is especially true when the subpatch you’re working on is somewhere inside another subpatch which in itself is also part of yet another subpatch.
No need for all that, as I demonstrated in the screenshot above…
This is what it looked like when I opened up my LOM.Navigator in edit mode. It immediately opened up the main patch window as well as 2 sub patches which I was working on at that time. And its very easy to set this up as well; when you have several windows open just go to your main patch window and hit save (control-s or using the option in the File menu).
Now it didn’t only save your work, but the layout as well. All the sub-patcher positions have been saved. So as soon as you leave a sub-patch open when saving your work it will return to this state the next time you open your patch again for editing.
Always expect the unexpected.
And this behavior can be seen in the Max window to the right. Its what leads up to the screenshot I used above. If you look right (if it can be seen that is) the tracks in the background are called ‘1 Audio’ and ‘2 Midi’, yet the menu lists the names in the opposite order, as can be seen here as well.
The paths are printed in the right order, yet the names seem to have been inverted somehow.
This was quite a puzzle for me, and in the end it turned out that it was caused by timing. Max was sending commands to the Live API in such a fast way that it just couldn’t keep up anymore. So when it started to cope again it started with the last bit of information and worked its way up to the results which I think it had cached somewhere. Thus giving the result you see above. At first such things seem impossible, hence my tip to always expect the unexpected.
Try helping others, by doing so you’ll also help yourself.
Another possible cliche sounding tip, but heck.. I think the best way to gain more experience with M4L is by trying to help out other people. When you see a request for something start thinking if you would be able to set it up for them. And if it sounds very hard to do it might be even more reason to try and pick up the challenge.
Other people may have totally different ideas on what they want and why they want it for than you. So by trying to help them out you might even gain some experience on topics you wouldn’t even have touched otherwise. And who knows… Something good might come from it as well. I cooked up some pretty interesting subpatchers (or so I like to think) while making patches for other people. Some of those subpatchers are still used by me today. Its one of those advantages of using with Max and M4L; its very easy to re-use your work.
Credit where credit’s due!
The final tip for today, but quite possible also the most important part I think. Programming and stuff is all fun and all, but it still takes up time and effort to set something up. So if you’re using patches or routines which were made by someone else its always a good idea to give them credit for it.
Not only is it polite but also much more ethical to do. Who cares if the end result looks very simple and in the end its a classic “why didn’t I think of it” kind of thing ?
People put time and effort into making and sharing patches and as such should be credited for their work the moment you’re using it.
I used the patch you see to the left in my LOM.Navigator, and it looks exactly like you see here.
When I designed the routines which show you the types and names of several list objects (in the so called “cs_mode” as well as the regular mode) they appear between brackets. Initially there was a space between them; that is a side effect when using the ‘append’ and ‘prepend’ objects.
And that is where this critter came along. Simple, to the point, and I hadn’t thought of it. So instead of trying to re-do stuff I simply copied it one on one and added a simple disclaimer.
Right now I think I might be able to streamline it a little and make it behave a little more efficient, but that’s for a later time. Once that happens the disclaimer obviously will also disappear, but until that time…
And there you have it….
Several tips which might help you along in the wonderful world of Max for Live.
More to come at a later time for sure!