Hello fellow Ardour-ers,
I recently bought the Akai APC key 25 Mk2. I turns out the knobs are relative encoders, rather than positional controllers (i.e. the
enc-2 option in Ardour). Sadly, Ardour doesn’t support MIDI learn for relative encoders, which is something I might find myself using.
I wanted to find a JACK/ALSA plugin, which handles the conversion between relative encoders and positional controllers before MIDI reaches Ardour and Ardour sees only positional controller values. This plugin’s job would be simple:
keep a 0-127 value representing the controller’s current state
on each MIDI encoder event, increase/decrease the current state according to the event, and
send the newly updated state as output
After some playing around with mididings, here is my script that does exactly this:
from mididings import * from mididings.extra import * from mididings.extra.inotify import AutoRestart from mididings.event import CtrlEvent from collections import defaultdict import numpy as np config( backend='alsa', # backend='jack', ) BIT7_MIN = 0 BIT7_MID = 64 BIT7_MAX = 127 BIT7_MODULO = 128 class CtrlsState: def __init__(self): self.states = defaultdict(lambda: np.int(BIT7_MID)) ctrls_state = CtrlsState() def twos_complement_to_signed_7bit(num): return ((num + BIT7_MID) % BIT7_MODULO) - BIT7_MID def process_ctrl(ev): if ev.type == CTRL: ctrl_key = (ev.port, ev.channel, ev.ctrl) ctrl_value = ctrls_state.states[ctrl_key] delta_2s = ev.value delta = twos_complement_to_signed_7bit(delta_2s) ctrl_value += delta ctrl_value = np.clip(ctrl_value, BIT7_MIN, BIT7_MAX) ctrls_state.states[ctrl_key] = ctrl_value return CtrlEvent(ev.port, ev.channel, ev.ctrl, int(ctrl_value)) else: return ev run(Process(process_ctrl))
I hope that someone else might find that useful as well!