Page 1 of 1
[SOLVED] Map relative encoders (2s complement) to positional controllers
Posted: Sun Mar 26, 2023 3:33 pm
by alex.cherg
Hello fellow Linux musicians,
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.
My question is, is there a JACK plugin that I can use to map the relative encoders to positional controllers, so that Ardour only sees positional controllers (and I can freely use the MIDI learn functionality)?
This plugin's job would be very simple:
Thanks for the help!
Re: Map relative encoders (2s complement) to positional controllers
Posted: Sun Mar 26, 2023 3:59 pm
by bluebell
I think it can be done with mididings but I didn't find a sample script.
Function calls look most promising:
https://mididings.github.io/mididings/u ... tion-calls
Re: Map relative encoders (2s complement) to positional controllers
Posted: Sun Mar 26, 2023 4:06 pm
by erlkönig
Re: Map relative encoders (2s complement) to positional controllers
Posted: Sat Apr 08, 2023 8:37 am
by alex.cherg
Thanks both for your suggestions! I gave mididings
a try, since it looks like a very flexible tool. After some playing around here is the mididings
script that solves my problem and correctly maps relative encoders (with 2s complement encoding) to positional controllers. I hope someone else might find it useful as well:
Code: Select all
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))