ALSA MIDI Velocity Mapper

Adjust keystroke dynamics of MIDI NOTEON events from arbitrary input devices by mapping velocity values between ALSA sequencer i/o ports.

Some MIDI sequencer hardware (or software) come with undocumented or poorly configurable velocity settings. Both is the case for example for the AKAI MPK Mini MK3. However, the ALSA sequencer API provides a simple interface that allows to adjust the sensitivity curve on-the-fly.

On startup, avelmap registers ALSA MIDI sequencer i/o ports and starts transforming velocity values of proxied NOTEON events. As this is a common use-case, only a small C source and binary is needed, which even largely bases on libalsa documentation examples. Supporting similar usecases, the amidimap or qmidiroute projects might be worth a look as alternatives.

Discrete input and output velocity values generally range until 127. Given a power exponent, linear factor, and constant offset, the new velocity value is calculated as a simple polynomial:

velocity= 127× (velocity127)power ×factor+offset

The predominant exponent, such as 0.5 or 2, would give a square root or quadratic shape, respectively. Linear scaling can be achieved by the constant factor. For example for defining a global minimum value, a static offset can be added – a value of 127 yields always full level without dynamics. In order to adhere to the 127 interval again, the result is subject to applying minimum, maximum, and rounding. Zero values are emitted as NOTEOFF events instead. The overall mapping can be verified by the -d flag, as stated below.

Installation & Usage

The tool comes in plain C99, so merely a standard gcc toolchain is required to build. ALSA library headers are the only extra dependency and can come with a libasound2-dev package or similar. Simply calling make creates the avelmap binary. Optionally, sudo make install copies it into a system folder.

usage: ./avelmap [-h] [-d] [-p power] [-f factor] [-c offset]

Map velocity values of NOTEON events between ALSA MIDI sequencer i/o ports.

optional arguments:
  -h         show this help and exit
  -d         debug dump computed velocity mapping
  -p power   velocity power function, for example 0.5 or 2 (default: 1.0)
  -f factor  linear scaling factor (default: 1.0)
  -c offset  constant offset (default: 0.0)

All arguments support negative values and can be in both integer or float notation. The defaults result in the identity function and thus no changes: 1, 1, and 0, respectively.

After startup, avelmap will print its assigned client id – alternatively, all registered MIDI inputs/outputs on the system can be listed via the aconnect -i/-o flags. Also with aconnect or qjackctl, these ports can then be arbitrarily plugged together as usual.

With the -d flag, the whole result mapping can be printed for verification. For live inspecting all MIDI events, such as velocity values of the original sequencer or avelmap, aseqdump can be useful.

Control/Program Mapper

A tool for mapping between CONTROLLER and/or PGMCHANGE events is also included.

make NAME=actlmap
sudo make NAME=actlmap install

Input events are matched according to a list of rules with a channel, param, and value each. A wildcard can be used at any place in both the source and destination.

./actlmap -h
actlmap: List of event mappings expected.

Map CONTROLLER or PGMCHANGE events between ALSA MIDI sequencer i/o ports.
A wildcard can be used in place of a channel, param, or value - for example:
'CTL[0,77,*] -> PGM[9,0,*]'
Modifier events let the configured rules apply until matched otherwise, such as:
'CTL[*,99,0] + PGM[9,0,*] -> CTL[0,77,127]'

With a modifier event prefix, certain controls can be “overloaded”, creating completely new banks. The entered mode remains active as long as one source mapping matches.

In case passing arguments is inconvenient, xargs can be used to read from a file instead:

xargs -a ctlmap.txt -d '\n' -- ./actlmap

Code & Download