Supported plug & play MIDI controllers
1 Introduction
Zynthian can be connected to almost any existing MIDI device and you can use the MIDI learning mechanism, as described in the UI user's guide, to assign parameters to faders and knobs in your MIDI controller, for instance. You could also assign pad trigger to notes, etc. But MIDI learning process takes time, it's limiting and you can't get feedback easily. Sometimes it's a lot better to plug a well-known (supported) MIDI controller and get everything mapped automatically. For having this, Zynthian implements a controller driver API that allows developers to create specific drivers for specific devices.
1.1 Supported Drivers and Guides
- After expanding greatly, the driver page has been split into multiple pages according to similar devices. See Driver Pages for a categorised list of device driver pages.
- There is also a sortable table of devices to get a glance of what devices have drivers and what functions are available for them. Click the title link to go to the device driver page.
- As with the rest of the wiki, some information here may be slightly out of date, there may be devices available that aren't shown here. For more up to date info on driver development, see the forum. For a list of drivers currently integrated into Zynthian you can check the (Vangelis version) list on github.
1.2 Accessing Drivers in Zynthian
As the title hints, if you connect your device (via USB), Zynthian will automatically load the driver if a compatible one exists. Where there are multiple drivers for a given device (or to use a generic driver such as Mackie Control, the active driver mode can be selected from within the Midi Input Devices menu from the Chain Manager screen or the individual chain options screen (also the admin menu). Bold press the driver entry for further options.
1.3 Driver Functions
This section contains documentation for some of these controller drivers. There are two core driver functions which control the primary screens in the Zynthian UI:
- Launcher mode (Zynpad): Launch patterns in the launcher grid interface (as with DAWs like Ableton or Logic)
- Mixer mode (ZynMixer): Control chain levels, mutes and solo. Different devices may have some additional controls and functions.
There are also additional driver modes/functions depending on the device and driver:
- UI Navigation: Adds some degree of UI navigation control via arrow buttons or by emulating encoders & buttons on the device
- SuperLooper Mode: Provides an interface to the native SuperLooper UI within Zynthian for looping live performance.
- Sequencer Mode (ZynSeq): (Sequencer functionality for the device depends on the Zynthian version installed) Provides some degree of control over the sequencer or pattern editor.
- Moder Mode: Adjusts device note inputs to stay in scale or provides some chord functionality
2 Driver Pages
- Akai APC Series
- Akai MIDI MIX
- Akai MPK Series
- Arturia Keylab Series
- Novation Launchpad Series
- Novation Launchkey Series
- Behringer MOTÖR 61 / 49
- Korg nanoKONTROL Series
- Fostex Mixtab
- Mackie Control
- Teenage Engineering OP-1
- SooperLooper CCx10, for Behringer FCB1010 & others
- Worlde Mini Moder Driver
- Sinco smk25
3 Table of Device Features
| Device | Launcher mode (ZynPad) | Mixer mode (ZynMixer) | UI Navigation | SuperLooper mode | Sequencer mode (ZynSeq) | Moder (chords/scales) | Extra features / notes |
|---|---|---|---|---|---|---|---|
| Akai APC Key25 MK2 | yes | yes | no | no | yes | no | Mixpad (default) controls Mixer + ZynPad; also Step Sequencer / pattern editor; Device mode controls the Zynthian UI. |
| Akai APC Key25 MK2 + SL | yes | yes | yes | yes | yes | no | Adds SooperLooper looper controls + Levels/Pan/Sync&Quantize/Session save+load; base modes otherwise match the non-SL driver. |
| Akai MIDI MIX | no | yes | no | no | no | no | Maps mixer functionality (chains 1–16 via banks, master slider, balance, mute/solo, rec-arm). |
| Akai MPK mini MK3 | yes | yes | no | no | yes | no | Modes: Mixer (default), Device UI, Pattern (ZynPad + Pattern Editor), NotePad; plus User and Config modes. |
| Akai MPK mini MK3 Moder | no | no | no | no | no | yes | This is a very simple "Mode Enforcer" driver for the Akai MPK mini MK3. |
| Novation LAUNCHPAD MINI MK1 | yes | no | no | no | no | no | ZynPad driver. |
| Novation LAUNCHPAD MINI MK3 | yes | no | no | no | no | no | ZynPad driver. |
| Novation LAUNCHPAD PRO MK2 | yes | yes | yes | no | no | no | Three modes using the top row buttons:
|
| Novation LAUNCHPAD PRO MK3 | yes | no | no | no | no | no | ZynPad driver. |
| Novation LAUNCHPAD X | yes | no | no | no | no | no | ZynPad driver. |
| Novation LAUNCHKEY MINI MK3 | yes | yes | no | no | no | no | Mixer + ZynPad. |
| Novation LAUNCHKEY 88 MK3 | yes | yes | no | no | no | no | Mixer + ZynPad. |
| Behringer MOTÖR 61 / 49 | yes | no | no | no | no | no | This driver is focused in stage control of setBfree and Pianoteq engines. It also includes the mode enforcer that can be controlled from the pads (notes). |
| Korg nanoKONTROL | no | no | no | no | no | no | Not currently available. |
| Korg nanoKONTROL-2 | no | yes | no | no | no | no | ZynMixer driver with UI navigation. |
| Mackie Control | no | yes | no | no | no | no | This driver can be loaded for devices that support MCU protocol and variants. |
| Fostex Mixtab | no | yes | no | no | no | no | This driver maps the hardware controls to relevant parameters in zynthian (mostly zynmixer). |
| Teenage Engineering OP-1 | no | no | no | no | no | no | Encoder control of parameters and UI navigation via encoders and buttons. |
| SooperLooper CCx10, for Behringer FCB1010 & others | no | no | yes | yes | no | no | SooperLooper CCx10 controller support. |
| Worlde Mini Moder Driver | tbc | tbc | tbc | no | no | yes | |
| Akai MPK249 | tbc | tbc | tbc | no | no | no | |
| Launchkey Mini Mk4 37 | tbc | tbc | tbc | no | no | no | |
| Launchkey Mini Mk3 | yes | yes | tbc | no | no | no | |
| Launchkey Mk3 88 | yes | yes | tbc | no | no | no | |
| Launchkey Mk4 37 | tbc | tbc | tbc | no | no | no | |
| Sinco smk25 | tbc | tbc | tbc | no | no | no | |
| Arturia Keylab Mk2 61 | yes | tbc | tbc | no | no | no |
4 Technical Info For Driver Developers
Drivers are python modules implementing a class. This class can call internal zynthian-ui API, so it has full access to Zynthian functionality. It’s not limited by CUIA. No limits, so you can break the UI too 😉
NOTE: the name of the class should be identical to that of the file name. This is a common pitfall when developing new drivers.
dev_ids is a list of identifiers that the driver will match. You can find this by looking at the name of the device in the MIDI Input view in Zynthian. If you bold press the corresponding input to see its options menu, the "Rename port" option shows its USB port / MIDI input name. Use the MIDI input name for your dev_ids list, e.g. Rename port 'USB:2.2/Launchkey Mini MK3 In 2' would provide the device id: "Launchkey Mini MK3 In 2".
You can check the full code here:
zynthian-ui/zyngui/zynthian_ctrldev_manager.py zynthian/zyngine · GitHub
and some example drivers here:
zynthian-ui/zyngine/ctrldev/ · GitHub
All drivers must inherit from zynthian_ctrldev_base, implementing the needed functionality as commented in the base code:
#------------------------------------------------------------------------------------------------------------------
# Control device base class
#------------------------------------------------------------------------------------------------------------------
class zynthian_ctrldev_base():
dev_id = None # String that identifies the device (class variable!)
dev_zynpad = False # Can act as a zynpad trigger device
dev_zynmixer = False # Can act as an audio mixer controller device
dev_pated = False # Can act as a pattern editor device
# Function to initialise class
def __init__(self):
self.idev = 0 # Slot index where the device is connected, starting from 1 (0 = None)
self.zyngui = zynthian_gui_config.zyngui
# Setup the device connected in slot #idev
# Before calling this, the caller (ctrldev-manager) should check that driver's ID string matches device's ID string
def setup(self, idev=None):
if idev != self.idev:
# Release currently selected device, if any ...
self.release()
# Init new selected device
if idev > 0:
self.idev = idev
logging.info("Setting-up {} in slot {}".format(self.dev_id, self.idev))
# Setup routing
lib_zyncore.zmip_set_route_extdev(self.idev - 1, 0)
zynautoconnect.midi_autoconnect(True)
# Initialize new selected device
self.init()
self.refresh(force=True)
def release(self):
if self.idev > 0:
logging.info("Releasing {} in slot {}".format(self.dev_id, self.idev))
# If device is still connected, call end
dev_id = zynautoconnect.get_midi_device_name(self.idev)
if dev_id and dev_id == self.dev_id:
self.end()
# Restore routing
lib_zyncore.zmip_set_route_extdev(self.idev - 1, 1)
zynautoconnect.midi_autoconnect(True)
self.idev = 0
# Refresh device status (LED feedback, etc)
# It *SHOULD* be implemented by child class
def refresh(self, force=False):
logging.debug("Refresh LEDs for {}: NOT IMPLEMENTED!".format(self.dev_id))
# Device MIDI event handler
# It *SHOULD* be implemented by child class
def midi_event(self, ev):
logging.debug("MIDI EVENT FROM '{}'".format(self.dev_id))
# Light-Off LEDs
# It *SHOULD* be implemented by child class
def light_off(self):
logging.debug("Lighting Off LEDs for {}: NOT IMPLEMENTED!".format(self.dev_id))
# Sleep On
# It *COULD* be improved by child class
def sleep_on(self):
self.light_off()
# Sleep On
# It *COULD* be improved by child class
def sleep_off(self):
self.refresh(True)
Quite simple, right? This is for basic “generic” drivers. Zynpad enabled drivers inherit from this base class:
# ------------------------------------------------------------------------------------------------------------------ # Zynpad control device base class # ------------------------------------------------------------------------------------------------------------------ class zynthian_ctrldev_zynpad(zynthian_ctrldev_base): dev_zynpad = True # Can act as a zynpad trigger device def __init__(self): super().__init__() self.zynpad = self.zyngui.screens["zynpad"] def refresh(self, force=False): # When zynpad is shown, this is done by refresh_status, so no need to refresh twice if force or not self.zynpad.shown: self.refresh_pads(force) self.refresh_zynpad_bank() if force: self.refresh_zynpad_bank() # It *SHOULD* be implemented by child class def refresh_zynpad_bank(self): pass def refresh_pads(self, force=False): if force: self.light_off() for pad in range(self.zyngui.zynseq.col_in_bank ** 2): # It MUST be called for cleaning the dirty bit changed_state = self.zyngui.zynseq.libseq.hasSequenceChanged(self.zynpad.bank, pad) if changed_state or force: mode = self.zyngui.zynseq.libseq.getPlayMode(self.zynpad.bank, pad) state = self.zynpad.get_pad_state(pad) self.update_pad(pad, state, mode) def refresh_pad(self, pad, force=False): # It MUST be called for cleaning the dirty bit!! changed_state = self.zyngui.zynseq.libseq.hasSequenceChanged(self.zynpad.bank, pad) if changed_state or force: mode = self.zyngui.zynseq.libseq.getPlayMode(self.zynpad.bank, pad) state = self.zynpad.get_pad_state(pad) self.update_pad(pad, state, mode) # It *SHOULD* be implemented by child class def update_pad(self, pad, state, mode): pass #------------------------------------------------------------------------------
If you kind-of-understand this, you shouldn’t have problem to understand the driver examples and program your own drivers. Simply copy your driver file in the the zyngui/ctrldev folder and restart zynthian-ui. Refer to this thread for more information NEW: Control-device manager + controller device “drivers”
5 Driver Discussion on the Forum
Refer to some threads discussing driver development on different devices:
- https://discourse.zynthian.org/t/akai-apc-key25-mk2-driver/9082/168
- https://discourse.zynthian.org/t/seeking-help-refactoring-midi-controller-device-drivers-for-vangelis/13218/29
- https://discourse.zynthian.org/t/akai-mpk249-support/11825/45
- https://discourse.zynthian.org/t/novation-launchkey-88-mk3-driver/13359
- https://discourse.zynthian.org/t/akai-mpk-mini-plus-driver/9441
- https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/63
- https://discourse.zynthian.org/t/ctrldev-driver-how-to-bypass-audio-processor-in-chain-solved/13095/9