In the previous two articles, Part One, and Part Two, we learned how to interact with Control Surfaces using the Live API, and programmatically move through the API to find what we are looking for. In this final part in this series I will walk you through the basics of writing MIDI Remote Scripts for Live. I thought it would be great if people without a controller that supported a session mode interface could use my Session_Scene_Launcher device to launch scenes and navigate Live’s session view. The resulting script simply creates a ‘redbox’ that you can reference with the device. We will walk through the construction of this script.
This article assumes a rudimentary understanding of python, at least in the context of MIDI Remote Scripts. Writing Remote Scripts can be a frustrating and time consuming process due to the availability of resources and documentation, and the fact that debugging can be very tedious. That being said, the rewards can be worth it.
Live’s MIDI remote scripts are all organized as folders with python files in them. All of the scripts that are distributed with Live are made up of precompiled .pyc files, meaning you can’t open them in your favorite text/code editor. This is a bummer. Fortunately there is a repository on Github maintained by Julien Bayle, that is updated regularly with the decompiled scripts in good old .py format. This allows curious programmers and Live users to see how the scripts are put together, and how to build them from smaller parts.
Those smaller parts are found in the _Framework folder of the repository. There are a ton of files in there, but you may recognize a few, notably the SessionComponent that we focused on finding with the API in the previous articles. These are all classes that embody a lot of different functionality, and are the basis, or framework, of all of the Control Scripts found in Live. I’m not going to get into many specifics in this article, I’m just going to show you the basics of setting up a group of .py files to make up a rudimentary control surface script.
If you haven’t downloaded the ‘Session_Box’ script, you should do that by clicking right HERE. That Session_Box script is a folder containing two python files. These two files are two things common to all Remote Scripts. They all have an __init.__.py file, and secondly they all have a .py file that contains the name of the control surface. Other more complex scripts can have any number of other python files that may be a reclass of a _Framework class, a list of constants, or a file containing MIDI information pertaining to the controller.
Let’s start by taking a look at the __init__.py file. Open it up using your preferred text/code editor (I like Sublime Text, but use whatever you’d like, or have available), and you’ll see this bit of code:
This file imports our Session_Box script (or whatever the name of our script is), then creates an instance of the Session_Box script. This instance now goes through it’s initialization routine to set up all of the classes, interactions, and functionality of our script. This inclusion of an __init__.py file is done in Python to mark a collection of modules as a package. Our main control script file and all the other possible files are all modules, and the folder containing them all is the package.
Now that we know how to invoke a control script, let’s take a look at what we have to do to make a simple 8×8 grid appear in Live’s session view. Open up the Session_Box.py file. At the top you will see all of the importing of modules, functions, and whatever else that we need for the script to run.
Lines 9-10 are two things that you need to import in order for your script to work. Line 9 is making the ‘with_statement’ available to Live’s python interpreter, which is still based on the 2.5 version of Python. The ‘with_statement’ is present in all python versions 2.6 and greater. Import Live tells the python interpreter to import the functions contained in Live (which I am assuming is the Live API, but I am not entirely sure. Just include it alright?).
The next lines are all optional and give us access to things we will want to use in our script. The ‘time’ library grants us access to various time-related functions, such as time stamping messages. The last two imports are coming from our _Framework classes, where all the magic happens. The ControlSurface is our central base class, and it acts as a container that holds all of the functionality we define with other classes. The SessionComponent is a class that gives control over Live’s session view. This allows for clip launching, session navigation, and the the ability to create a session highlight (or ‘red box’, as it is more commonly referred to), among other things. The other two statements are some global variables that won’t be used in this script, but I thought it’d be good to include them just for demonstration.
The next section of the script is where we create and initialize our ControlSurface:
We begin by defining our class ‘Session_Box’ as a ControlSurface, followed by naming our module in line 20, and giving it a documentation string in line 21. In line 23 we define the __init__ function which is called when we create the class in the top level file. We then define our initialization routine for this instance of a ControlSurface. Because all we want to do is create a SessionComponent with a highlighting component, lines 26 and 27 are all we need. These lines call two functions. The first, _setup_session_control, we will define below, and the second set_highlighting_session_component, references an object that will be created by the _setup_session_control function.
These next lines are where we actually define the components of our script:
Here we define the _setup_session_control function, which gets called in our _init_ function. This creates a SessionComponent called ‘session’, with 8 columns and 8 rows, and is offset from the upper left by zero. After __init__ calls this function it creates a highlighting session component, binds it to this session, and our red box is created!
The great thing about leveraging the _Framework classes, is that this SessionComponent we created has all of the properties, functions, and attributes that one would find in a more advanced script. We can change the offset, and poll the location to assign buttons to scenes, just as we could with the SessionComponent contained in the Push, Launchpad or APC scripts.
The last block of code is used to print a time stamped log message when we disconnect the controller from the script. This will appear in our log.txt file that is the main means of debugging these scripts. If you’re interested in coding your own MIDi remote scripts it will be useful to know where to find this file. This page on Ableton’s website gives you the location for a variety of OSes. The log.txt file will hold information regarding why and where your script broke, which is necessary information when trying to track down bugs in the development process.
Hopefully this series gave you an insight into the many different ways that you can use Live, M4L, and a little bit of Python to craft interaction between your software and hardware. As always, any questions, comments and concerns should be directed to firstname.lastname@example.org. I’d love to hear any requests or suggestions for future articles!