Although the APC40 is the de-facto MIDI controller for Ableton Live its also one which has a shroud of mystery surrounding it. Basically there is little to no documentation, not much explanation and the only options you had left when you wanted to use it more indepth with Max for Live was going through trial and error.
Up until now that is.
Please keep in mind that this is work in progress. To get the latest discoveries you need to check my blog posts which were tagged APC40. Also note that although I’m focussing explicitly on the APC40 my tutorial can most likely also be applied to other control surfaces. Also keep in mind that my approach fully involves around Max for Live (“M4L”). So while there are more options (sending MIDI data directly) these will most likely not be covered.
SynthFan’s guide to APC40 access
V1.2 – Latest update: March 14, 2013
Warning: With the release of Live 9 and Max for Live 6 the trick I show here which allows you to ‘enter’ a function no longer works. So if you want to try this out yourself make sure to use Live 8 and Max for Live 5.
The APC40 consists of 2 major sections: Components and Controls, this can also be seen when checking the chart of the Live Object Model:
Components – These represent virtual sections of the APC40. For example the 8 x 5 button matrix is a single component (control_surfaces x components 0). Not all available component options are being used by the APC40. For example the APC doesn’t use the ‘ClipSlotComponent’.
Like all other objects (“classes”) components have properties and functions.
Controls – These represent the physical hardware of the APC40. From the shift button to a tracks solo button or even the rotaries on the device controls. Controls can overlap with components, for example the button matrix is both a component (components 0) as well as a control (controls 5).
All sections in the APC40 can be identified through IDs. With the notable difference that all IDs are negative.
It is therefor my theory that the ‘software side’ (Ableton environment; the tracks, scenes, devices, etc.) is using positive IDs (“ID 5”) whereas the ‘hardware side’ (The classes which are defined by the MIDI remote scripts) only uses negative IDs (“ID -5”). I think this is done to keep a clear separation and avoid any possibility of overlap.
Properties and ‘function properties’
Some components have usable properties (which actually return a useful value) while most objects (Components and Controls) have properties which only seem to refer to or represent functions. Their component type is ‘function’ and in most cases these functions are system related.
For example: ‘set_song_and_application‘ is a function which appears with many components and seems to be used to point the component to the right application. In general most of the time you’ll be using functions instead of properties when accessing control surfaces within M4L.
Almost every function contains identifiers which describe how many parameters the function expects and what their names or types are. In order to use the function you need to match the right parameter amount, otherwise the function call will not work.
In order to reach this information you need to goto the function, and then continue ‘into’ its “child functions” im_func and func_code. Here you’ll find properties such as co_argcount which gives you the amount of required parameters (+1, it also counts the function itself). co_varnames gets you an overview of the parameter names and / or types. By using these two properties it should be possible to identify most functions.
To the right you can see a patch which I use to identify these two property types. It should be pretty self explaining; I’ll provide a working solution in my upcoming release of the LOM.Navigator.
Many components and controls are directly related to each other and also need to be used this way. An example of that is the ‘SpecialChanStripComponent’ which represents a channel strip on the APC40 (so; the slider, the arm section, select button and the clip matrix). This class is directly tied into the ‘SliderElement’ control which represents the physical fader on the APC40. In order to turn the fader on or off you need to use ‘id 0’ as parameter for the “set_volume_control” function. To re-enable the fader again you need to use the id value of the SliderElement control.
Many components are directly associated with their control counterpart(s). So apart from components and controls pointing to the same section it also occurs that components use functions which need to be pointed to specific controls. So; components make up the virtual control surface whereas the controls represent the physical hardware.
Controlling the leds on the button matrix
If you want to use the leds on the matrix, or any button which has a led, then you could use the functions “turn_on” or “turn_off” on any ButtonElement control. However, this will only use the buttons default colour: green.
To use the rest of the colours and attributes (blinking) you need to use the “send_value” function where you can use the following values:
- 0 – Turn button off.
- 1 – Turn button on, colour is green.
- 2 – Turn button on, button is flashing green.
- 3 – Turn button on, colour is red.
- 4 – Turn button on, button is flashing red.
- 5 – Turn button on, colour is orange.
- 6 – Turn button on, button is flashing orange.
So, if you want to change the first button on the second row of the matrix (the one which represents the 2nd clipslot of the first track), and make it flashing orange then you’d point a [live.object] to “control_surfaces x controls 28”. Then use the “send_value” function with 6 as parameter. So: “call send_value 6”.
Now the button flashes. Either using the same function with 0 as parameter or the “turn_off” function will turn the button off.