Ableton Live Control Surface Development Adventure: EP-01
EP-01: HELLO, WORLD! I bought a budget M-VAVE SMK25-II MIDI controller a few days ago and later found out that it cannot control Ableton Live out of the box. I did some research and got a few options: Select "MackieControl" for Control Surface in the Live's setting Use an unofficial MidiSuite preset and remote script that I found online. Write a custom MIDI remote script from scratch As a software developer myself, I chose option 3. What a great learning opportunity! Ableton Live loads remote scripts from multiple directories. Some information regarding the control surface can be found at https://help.ableton.com/hc/en-us/articles/206240184-Creating-your-own-Control-Surface-script. Also Live loads from [USER_LIBRARY_PATH]/Remote Scripts folder. For me, I chose [USER_LIBRARY_PATH]/Remote Scripts and created a folder called SMK25II there. Basically, that folder is a python package which exports a function called create_instance. And that function returns a Control Surface object, which controls Ableton Live and do other stuff. To get started, I created __init__.py, logger.py and SMK25II.py. Here's the current folder structure: . ├── __init__.py ├── SMK25II.py └── logger.py logger.py is pretty simple. It uses logging package and exports a logger. from logging import getLogger logger = getLogger(__name__) As I mentioned before, __init__.py should export a function called create_instance and that function should return a Control Surface object. Since there's no documentation for ControlSurface object, I had to do research and read some codes. And here's the minimal ControlSurface object which does not throw an error. from .logger import logger class SMK25II: def __init__(self, _): logger.info("Hello, World!") def disconnect(self): pass def refresh_state(self): """ Live is calls this method. But I have no idea what it is for (at the moment). """ pass def update_display(self): """ Live is calls this method. But I have no idea what it is for (at the moment). """ pass def connect_script_instances(self, _): """ Live is calls this method. But I have no idea what it is for (at the moment). """ pass def can_lock_to_devices(self): """ Live is calls this method. But I have no idea what it is for (at the moment). """ return False def build_midi_map(self, _): """ Live is calls this method. But I have no idea what it is for (at the moment). """ pass Then, I fired up Ableton Live and select my Control Surface SMK25II in the settings. Input/Output are not important as of now. The "Hello, World!" is logged in the Ableton Live's Log.txt file. Log.txt path can be found at https://help.ableton.com/hc/en-us/articles/5301568366354-Reading-Live-Crash-Reports. Well, this is the end of EP-01. Even though this series is written based on the M-VAVE SMK25-II, some concepts can be applied to other controllers as well. Thanks for reading! See you in the next episode.

EP-01: HELLO, WORLD!
I bought a budget M-VAVE SMK25-II MIDI controller a few days ago and later found out that it cannot control Ableton Live out of the box. I did some research and got a few options:
- Select "MackieControl" for Control Surface in the Live's setting
- Use an unofficial MidiSuite preset and remote script that I found online.
- Write a custom MIDI remote script from scratch
As a software developer myself, I chose option 3. What a great learning opportunity!
Ableton Live loads remote scripts from multiple directories. Some information regarding the control surface can be found at https://help.ableton.com/hc/en-us/articles/206240184-Creating-your-own-Control-Surface-script. Also Live loads from [USER_LIBRARY_PATH]/Remote Scripts
folder.
For me, I chose [USER_LIBRARY_PATH]/Remote Scripts
and created a folder called SMK25II
there. Basically, that folder is a python package which exports a function called create_instance
. And that function returns a Control Surface
object, which controls Ableton Live and do other stuff.
To get started, I created __init__.py
, logger.py
and SMK25II.py
. Here's the current folder structure:
.
├── __init__.py
├── SMK25II.py
└── logger.py
logger.py
is pretty simple. It uses logging
package and exports a logger.
from logging import getLogger
logger = getLogger(__name__)
As I mentioned before, __init__.py
should export a function called create_instance
and that function should return a Control Surface
object.
Since there's no documentation for ControlSurface
object, I had to do research and read some codes. And here's the minimal ControlSurface
object which does not throw an error.
from .logger import logger
class SMK25II:
def __init__(self, _):
logger.info("Hello, World!")
def disconnect(self):
pass
def refresh_state(self):
"""
Live is calls this method. But I have no idea what it is for (at the moment).
"""
pass
def update_display(self):
"""
Live is calls this method. But I have no idea what it is for (at the moment).
"""
pass
def connect_script_instances(self, _):
"""
Live is calls this method. But I have no idea what it is for (at the moment).
"""
pass
def can_lock_to_devices(self):
"""
Live is calls this method. But I have no idea what it is for (at the moment).
"""
return False
def build_midi_map(self, _):
"""
Live is calls this method. But I have no idea what it is for (at the moment).
"""
pass
Then, I fired up Ableton Live and select my Control Surface SMK25II
in the settings. Input/Output are not important as of now.
The "Hello, World!" is logged in the Ableton Live's Log.txt
file. Log.txt
path can be found at https://help.ableton.com/hc/en-us/articles/5301568366354-Reading-Live-Crash-Reports.
Well, this is the end of EP-01. Even though this series is written based on the M-VAVE SMK25-II, some concepts can be applied to other controllers as well. Thanks for reading! See you in the next episode.