2018-11-16 21:16:00 +01:00
|
|
|
.\" Automatically generated by Pandoc 2.4
|
2018-08-16 18:34:02 +02:00
|
|
|
.\"
|
|
|
|
.TH "midizap" "1" "" "" ""
|
|
|
|
.hy
|
2018-08-20 01:13:53 +02:00
|
|
|
.SH Name
|
|
|
|
.PP
|
2018-08-20 21:50:44 +02:00
|
|
|
midizap \[en] control your multimedia applications with MIDI
|
2018-08-16 18:34:02 +02:00
|
|
|
.SH Synopsis
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
midizap [\-hkn] [\-d[rskmj]] [\-j \f[I]name\f[R]] [\-ost[\f[I]n\f[R]]]
|
|
|
|
[\-P[\f[I]prio\f[R]]] [[\-r] \f[I]rcfile\f[R]]
|
2018-08-16 18:34:02 +02:00
|
|
|
.SH Options
|
|
|
|
.TP
|
|
|
|
.B \-h
|
2018-09-08 22:32:27 +02:00
|
|
|
Print a short help message and exit.
|
|
|
|
.TP
|
|
|
|
.B \-d[rskmj]
|
|
|
|
Enable various debugging options: r = regex (print matched translation
|
|
|
|
sections), s = strokes (print the parsed configuration file in a
|
|
|
|
human\-readable format), k = keys (print executed translations), m =
|
2018-09-20 14:26:31 +02:00
|
|
|
midi (MIDI monitor, print all recognizable MIDI input), j = jack (print
|
|
|
|
information about the Jack MIDI backend).
|
2018-11-16 21:16:00 +01:00
|
|
|
Just \f[C]\-d\f[R] enables all debugging options.
|
|
|
|
See Section \f[I]Basic Usage\f[R].
|
2018-09-08 22:32:27 +02:00
|
|
|
.TP
|
2018-11-16 21:16:00 +01:00
|
|
|
.B \-j \f[I]name\f[R]
|
2018-09-08 22:32:27 +02:00
|
|
|
Set the Jack client name.
|
|
|
|
This overrides the corresponding directive in the configuration file.
|
|
|
|
Default: \[lq]midizap\[rq].
|
2018-11-16 21:16:00 +01:00
|
|
|
See Section \f[I]Jack\-Related Options\f[R].
|
2018-08-16 18:34:02 +02:00
|
|
|
.TP
|
|
|
|
.B \-k
|
2018-09-18 07:27:12 +02:00
|
|
|
Keep track of key (on/off) status.
|
|
|
|
This may occasionally be useful to deal with quirky controllers sending
|
|
|
|
repeated on or off messages.
|
2018-11-16 21:16:00 +01:00
|
|
|
See Section \f[I]Key and Data Translations\f[R].
|
2018-08-16 18:34:02 +02:00
|
|
|
.TP
|
2018-09-12 10:52:47 +02:00
|
|
|
.B \-n
|
|
|
|
No automatic feedback.
|
2018-09-12 20:57:45 +02:00
|
|
|
By default, midizap keeps track of controller feedback from the second
|
2018-11-16 21:16:00 +01:00
|
|
|
input port if it is enabled (\f[C]\-o2\f[R]).
|
2018-09-12 20:57:45 +02:00
|
|
|
This option lets you disable this feature if the second port is being
|
|
|
|
used for other purposes.
|
2018-11-16 21:16:00 +01:00
|
|
|
See Section \f[I]Automatic Feedback\f[R].
|
2018-09-12 10:52:47 +02:00
|
|
|
.TP
|
2018-11-16 21:16:00 +01:00
|
|
|
.B \-o[\f[I]n\f[R]]
|
|
|
|
Enable MIDI output and set the number of output ports \f[I]n\f[R] (1 by
|
2018-09-02 00:12:24 +02:00
|
|
|
default).
|
2018-11-16 21:16:00 +01:00
|
|
|
Use \f[I]n\f[R] = 2 for a second pair of MIDI ports, e.g., for
|
|
|
|
controller feedback, or \f[I]n\f[R] = 0 to disable MIDI output.
|
2018-09-02 00:12:24 +02:00
|
|
|
This overrides the corresponding directive in the configuration file.
|
2018-11-16 21:16:00 +01:00
|
|
|
See Section \f[I]Jack\-Related Options\f[R].
|
2018-08-16 18:34:02 +02:00
|
|
|
.TP
|
2018-11-16 21:16:00 +01:00
|
|
|
.B \-P[\f[I]prio\f[R]]
|
2018-09-02 00:12:24 +02:00
|
|
|
Run with the given real\-time priority (default: 90).
|
2018-11-16 21:16:00 +01:00
|
|
|
See Section \f[I]Jack\-Related Options\f[R].
|
2018-08-31 02:15:56 +02:00
|
|
|
.TP
|
2018-11-16 21:16:00 +01:00
|
|
|
.B [\-r] \f[I]rcfile\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
Set the configuration file name.
|
2018-11-16 21:16:00 +01:00
|
|
|
The \f[C]\-r\f[R] is optional, but still supported for backward
|
2018-10-15 06:23:23 +02:00
|
|
|
compatibility.
|
2018-08-20 21:50:44 +02:00
|
|
|
Default: taken from the MIDIZAP_CONFIG_FILE environment variable if it
|
2018-11-16 21:16:00 +01:00
|
|
|
exists, or \[ti]/.midizaprc if it exists, /etc/midizaprc otherwise.
|
|
|
|
See Section \f[I]Configuration File\f[R].
|
2018-08-16 18:34:02 +02:00
|
|
|
.TP
|
2018-11-16 21:16:00 +01:00
|
|
|
.B \-s[\f[I]n\f[R]]
|
|
|
|
Pass through system messages from MIDI input to output; \f[I]n\f[R]
|
2018-09-18 22:31:22 +02:00
|
|
|
optionally specifies the port (0 = none, 1 = first, 2 = second port
|
|
|
|
only), default is pass\-through on both ports (if available).
|
|
|
|
This overrides the corresponding directive in the configuration file.
|
2018-11-16 21:16:00 +01:00
|
|
|
See Section \f[I]Jack\-Related Options\f[R].
|
2018-09-20 01:24:52 +02:00
|
|
|
.TP
|
2018-11-16 21:16:00 +01:00
|
|
|
.B \-t[\f[I]n\f[R]]
|
2018-09-20 01:24:52 +02:00
|
|
|
Pass through untranslated (non\-system) messages from MIDI input to
|
2018-11-16 21:16:00 +01:00
|
|
|
output; the meaning of the optional parameter \f[I]n\f[R] is the same as
|
|
|
|
with the \f[C]\-s\f[R] option.
|
2018-09-20 01:24:52 +02:00
|
|
|
This overrides the corresponding directive in the configuration file.
|
2018-11-16 21:16:00 +01:00
|
|
|
See Section \f[I]Jack\-Related Options\f[R].
|
2018-08-16 18:34:02 +02:00
|
|
|
.SH Description
|
|
|
|
.PP
|
2018-08-31 02:15:56 +02:00
|
|
|
midizap lets you control your multimedia applications using
|
2018-10-15 06:23:23 +02:00
|
|
|
MIDI (https://www.midi.org/), the venerable \[lq]Musical Instrument
|
|
|
|
Digital Interface\[rq] protocol which has been around since the 1980s.
|
2018-11-16 21:16:00 +01:00
|
|
|
Modern MIDI controllers are usually USB class devices which don\[cq]t
|
2018-10-15 06:23:23 +02:00
|
|
|
require any special interface or driver, and they are often much cheaper
|
|
|
|
than more specialized gear.
|
|
|
|
With midizap you can leverage these devices to control just about any
|
2018-09-20 01:24:52 +02:00
|
|
|
X11\-based application.
|
|
|
|
To these ends, it translates Jack MIDI input into X keyboard and mouse
|
|
|
|
events, and optionally MIDI output.
|
2018-10-15 06:23:23 +02:00
|
|
|
It does this by matching the class and title of the focused window
|
|
|
|
against the regular expressions for each application section in its
|
|
|
|
configuration (midizaprc) file.
|
2018-08-16 18:34:02 +02:00
|
|
|
If a regex matches, the corresponding set of translations is used.
|
2018-11-16 21:16:00 +01:00
|
|
|
If a matching section cannot be found, or if it doesn\[cq]t define a
|
2018-10-15 06:23:23 +02:00
|
|
|
suitable translation, the program falls back to a set of default
|
|
|
|
translations.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
|
|
|
The midizaprc file is just an ordinary text file which you can edit to
|
2018-08-18 00:09:48 +02:00
|
|
|
configure the program.
|
2018-09-02 00:12:24 +02:00
|
|
|
The configuration language is fairly straightforward, basically the file
|
|
|
|
is just a list of MIDI messages (denoted with familiar human\-readable
|
2018-10-15 06:23:23 +02:00
|
|
|
mnemonics, no hex numbers!) and their translations.
|
2018-09-20 01:24:52 +02:00
|
|
|
An example.midizaprc file is included in the sources to get you started,
|
2018-10-15 06:23:23 +02:00
|
|
|
and you can find more examples of configuration files for various
|
|
|
|
purposes in the examples subdirectory.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Even if your target application already supports MIDI, midizap\[cq]s
|
|
|
|
MIDI output option will be useful if your controller can\[cq]t work
|
|
|
|
directly with the application because of protocol incompatibilities.
|
2018-10-15 06:23:23 +02:00
|
|
|
In particular, you can use midizap to turn any MIDI controller with
|
|
|
|
enough faders and buttons into a Mackie\-compatible device ready to be
|
|
|
|
used with most DAW (digital audio workstation) programs.
|
|
|
|
Another common use case is photo and video editing software.
|
|
|
|
This kind of software often lacks built\-in MIDI support, and midizap
|
|
|
|
can then be used to map the faders, encoders and buttons of your MIDI
|
|
|
|
controller to keyboard commands for adjusting colors, cutting, marking,
|
|
|
|
playback, scrolling, zooming, etc.
|
2018-08-16 18:34:02 +02:00
|
|
|
In other words, as long as the target application can be controlled with
|
2018-08-17 01:44:26 +02:00
|
|
|
simple keyboard shortcuts and/or MIDI commands, chances are that midizap
|
2018-08-20 01:13:53 +02:00
|
|
|
can make it work (at least to some extent) with your controller.
|
2018-08-16 18:34:02 +02:00
|
|
|
.SH Installation
|
|
|
|
.PP
|
|
|
|
First, make sure that you have the required dependencies installed.
|
|
|
|
The program needs a few X11 libraries and Jack.
|
|
|
|
And of course you need GNU make and gcc (the GNU C compiler).
|
|
|
|
On Ubuntu and other Debian\-based systems you should be able to get
|
2018-11-16 21:16:00 +01:00
|
|
|
everything that\[cq]s needed by running this command:
|
2018-08-16 18:34:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
sudo apt install build\-essential libx11\-dev libxtst\-dev libjack\-dev
|
|
|
|
\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Then just run \f[C]make\f[R] and \f[C]sudo make install\f[R].
|
2018-08-16 18:34:02 +02:00
|
|
|
This installs the example.midizaprc file as /etc/midizaprc, and the
|
|
|
|
midizap program and the manual page in the default install location.
|
|
|
|
Usually this will be under /usr/local, but the installation prefix can
|
2018-11-16 21:16:00 +01:00
|
|
|
be changed with the \f[C]prefix\f[R] variable in the Makefile.
|
|
|
|
Also, package maintainers can use the \f[C]DESTDIR\f[R] variable to
|
2018-09-08 22:32:27 +02:00
|
|
|
install into a staging directory for packaging purposes.
|
2018-11-10 23:46:20 +01:00
|
|
|
.PP
|
|
|
|
For users of the Emacs text editor we provide a midizap mode which does
|
|
|
|
syntax\-highlighting of midizaprc files and also lets you launch a
|
|
|
|
midizap session in an Emacs buffer.
|
2018-11-16 21:16:00 +01:00
|
|
|
If Emacs was found during installation, the midizap\-mode.el file is
|
|
|
|
installed into the share/emacs/site\-lisp directory along with the other
|
|
|
|
files.
|
|
|
|
The Makefile tries to guess the proper installation prefix, but if
|
|
|
|
necessary you can also set the \f[C]elispdir\f[R] variable or copy the
|
|
|
|
file manually to a directory on your Emacs load\-path.
|
|
|
|
Please check midizap\-mode.el for more detailed instructions.
|
2018-08-16 18:34:02 +02:00
|
|
|
.SH Configuration File
|
|
|
|
.PP
|
|
|
|
After installation the system\-wide default configuration file will be
|
|
|
|
in /etc/midizaprc, where the program will be able to find it.
|
|
|
|
We recommend copying this file to your home directory, renaming it to
|
|
|
|
\&.midizaprc:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
cp /etc/midizaprc \[ti]/.midizaprc
|
|
|
|
\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
The \[ti]/.midizaprc file, if it exists, takes priority over
|
|
|
|
/etc/midizaprc, so it becomes your personal default midizap
|
|
|
|
configuration.
|
2018-08-18 00:09:48 +02:00
|
|
|
The midizaprc file included in the distribution is really just an
|
2018-11-16 21:16:00 +01:00
|
|
|
example; you\[cq]re expected to edit this file to adjust the bindings
|
|
|
|
for the MIDI controllers and the applications that you use.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
|
|
|
It is also possible to specify the configuration file to be used, by
|
2018-10-15 06:23:23 +02:00
|
|
|
invoking midizap with the name of the midizaprc file on the command
|
|
|
|
line.
|
2018-08-16 18:34:02 +02:00
|
|
|
This is often used with more specialized configurations dealing with
|
|
|
|
specific applications or MIDI controllers.
|
2018-10-16 08:33:48 +02:00
|
|
|
E.g., to try one of the sample configurations in the sources:
|
2018-10-15 06:23:23 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
midizap examples/APCmini.midizaprc
|
|
|
|
\f[R]
|
2018-10-15 06:23:23 +02:00
|
|
|
.fi
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-08-23 12:17:05 +02:00
|
|
|
The program automatically reloads the midizaprc file whenever it notices
|
|
|
|
that the file has been changed.
|
2018-08-16 18:34:02 +02:00
|
|
|
Thus you can edit the file while the program keeps running, and have the
|
|
|
|
changes take effect immediately without having to restart the program.
|
|
|
|
When working on new translations, you may want to run the program in a
|
|
|
|
terminal, and employ some or all of the debugging options explained
|
|
|
|
below to see exactly how your translations are being processed.
|
|
|
|
.SH Basic Usage
|
|
|
|
.PP
|
|
|
|
The midizap program is a command line application, so you typically run
|
2018-08-20 07:09:52 +02:00
|
|
|
it from the terminal.
|
|
|
|
However, it is also possible to launch it from your Jack session manager
|
2018-11-16 21:16:00 +01:00
|
|
|
(see \f[I]Jack\-Related Options\f[R] below) or from your desktop
|
|
|
|
environment\[cq]s startup files once you\[cq]ve set up everything to
|
|
|
|
your liking.
|
|
|
|
If you\[cq]re an Emacs user, you can conveniently edit and launch
|
|
|
|
midizap configurations using midizap\[cq]s Emacs mode; please check the
|
2018-11-10 23:46:20 +01:00
|
|
|
midizap\-mode.el file included in the sources for details.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Try \f[C]midizap \-h\f[R] for a brief summary of the available options
|
2018-08-16 18:34:02 +02:00
|
|
|
with which the program can be invoked.
|
|
|
|
.PP
|
|
|
|
midizap uses Jack (http://jackaudio.org/) for doing all its MIDI input
|
|
|
|
and output, so you need to be able to run Jack and connect the Jack MIDI
|
|
|
|
inputs and outputs of the program.
|
2018-09-08 22:32:27 +02:00
|
|
|
We recommend using a Jack front\-end and patchbay program like
|
|
|
|
QjackCtl (https://qjackctl.sourceforge.io/) for this purpose.
|
2018-11-16 21:16:00 +01:00
|
|
|
In QjackCtl\[cq]s setup, make sure that you have selected \f[C]seq\f[R]
|
|
|
|
as the MIDI driver.
|
2018-08-16 18:34:02 +02:00
|
|
|
This exposes the ALSA sequencer ports of your MIDI hardware and other
|
|
|
|
non\-Jack ALSA MIDI applications as Jack MIDI ports, so that they can
|
|
|
|
easily be connected to midizap.
|
2018-10-11 20:03:10 +02:00
|
|
|
As an alternative, you can also run
|
2018-08-16 18:34:02 +02:00
|
|
|
a2jmidid (http://repo.or.cz/a2jmidid.git) as a separate ALSA\-Jack MIDI
|
2018-10-11 20:03:10 +02:00
|
|
|
bridge.
|
2018-10-15 06:23:23 +02:00
|
|
|
The latter method works well with both Jack1 and Jack2.
|
2018-11-16 21:16:00 +01:00
|
|
|
Jack\[cq]s built\-in bridge also does the job in Jack1, but in Jack2 it
|
|
|
|
doesn\[cq]t list the ALSA ports by their name, so it\[cq]s better to use
|
2018-10-15 06:23:23 +02:00
|
|
|
a2jmidid in that case.
|
|
|
|
When in doubt, just use a2jmidid.
|
|
|
|
You can have QJackCtl autostart a2jmidid by placing the command
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]a2jmidid \-e &\f[R] into the \[lq]Execute script after Startup\[rq]
|
|
|
|
field which can be found under \[lq]Options\[rq] in QJackctl\[cq]s Setup
|
|
|
|
dialog.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
|
|
|
Having that set up, start Jack, make sure that your MIDI controller is
|
2018-11-16 21:16:00 +01:00
|
|
|
connected, and try running \f[C]midizap\f[R] from the command line
|
2018-08-16 18:34:02 +02:00
|
|
|
(without any arguments).
|
2018-08-19 21:14:49 +02:00
|
|
|
In QjackCtl, open the Connections dialog and activate the second tab
|
2018-08-16 18:34:02 +02:00
|
|
|
named \[lq]MIDI\[rq], which shows all available Jack MIDI inputs and
|
|
|
|
outputs.
|
|
|
|
On the right side of the MIDI tab, you should now see a client named
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]midizap\f[R] with one MIDI input port named \f[C]midi_in\f[R].
|
|
|
|
That\[cq]s the one you need to connect to your MIDI controller, whose
|
|
|
|
output port should be visible under the \f[C]alsa_midi\f[R] client on
|
|
|
|
the left side of the dialog (or the \f[C]a2j\f[R] client, if you\[cq]re
|
|
|
|
using a2jmidid).
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
|
|
|
To test the waters, you can hook up just about any MIDI keyboard and
|
|
|
|
give it a try with the default section in the distributed midizaprc
|
|
|
|
file, which contains some basic translations for mouse and cursor key
|
|
|
|
emulation.
|
|
|
|
Here is the relevant excerpt from that section:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
|
|
|
[Default]
|
|
|
|
|
2018-11-16 21:16:00 +01:00
|
|
|
C5 XK_Button_1
|
|
|
|
D5 XK_Button_2
|
|
|
|
E5 XK_Button_3
|
2018-08-16 18:34:02 +02:00
|
|
|
|
2018-11-16 21:16:00 +01:00
|
|
|
F5 XK_Left
|
|
|
|
G5 XK_Up
|
|
|
|
A5 XK_Down
|
|
|
|
B5 XK_Right
|
2018-08-16 18:34:02 +02:00
|
|
|
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1+ XK_Scroll_Up
|
|
|
|
CC1\- XK_Scroll_Down
|
|
|
|
\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
We refer to Section \f[I]Translation Syntax\f[R] below for a discussion
|
2018-08-17 01:44:26 +02:00
|
|
|
of the syntax being used here, but it should be fairly obvious that
|
|
|
|
these translations map the white keys of the middle octave (MIDI notes
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]C5\f[R] thru \f[C]B5\f[R]) to some mouse buttons and cursor
|
|
|
|
commands.
|
2018-08-16 18:34:02 +02:00
|
|
|
Switch the keyboard focus to some window with text in it, such as a
|
|
|
|
terminal or an editor window.
|
|
|
|
Pressing the keys C, D and E should click the mouse buttons, while F
|
|
|
|
thru B should perform various cursor movements.
|
2018-11-16 21:16:00 +01:00
|
|
|
Also, moving the modulation wheel (\f[C]CC1\f[R]) on your keyboard
|
|
|
|
should scroll the window contents up and down.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-09-20 14:26:31 +02:00
|
|
|
You can invoke the program with various debugging options to get more
|
|
|
|
verbose output.
|
2018-11-16 21:16:00 +01:00
|
|
|
E.g., try running \f[C]midizap \-drk\f[R] to have the program print the
|
2018-08-16 18:34:02 +02:00
|
|
|
recognized configuration sections and translations as they are executed.
|
|
|
|
Now press some of the keys and move the modulation wheel.
|
2018-11-16 21:16:00 +01:00
|
|
|
You\[cq]ll see something like:
|
2018-08-16 18:34:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
$ midizap \-drk
|
|
|
|
Loading configuration: /home/user/.midizaprc
|
|
|
|
translation: Default for emacs\[at]hostname (class emacs)
|
|
|
|
CC1\-1\-: XK_Scroll_Down/D XK_Scroll_Down/U
|
|
|
|
CC1\-1\-: XK_Scroll_Down/D XK_Scroll_Down/U
|
|
|
|
G5\-1[D]: XK_Up/D
|
|
|
|
G5\-1[U]: XK_Up/U
|
|
|
|
A5\-1[D]: XK_Down/D
|
|
|
|
A5\-1[U]: XK_Down/U
|
|
|
|
\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-20 19:09:07 +02:00
|
|
|
The debugging output tells you pretty much everything you need to know
|
2018-11-16 21:16:00 +01:00
|
|
|
about what\[cq]s going on inside midizap, and helps you along when you
|
|
|
|
start developing your own configurations.
|
|
|
|
The \f[C]\-d\f[R] option can be combined with various option characters
|
|
|
|
to choose exactly which kinds of debugging output you want; \f[C]r\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
(\[lq]regex\[rq]) prints the matched translation section (if any) along
|
2018-11-16 21:16:00 +01:00
|
|
|
with the window name and class of the focused window; \f[C]s\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
(\[lq]strokes\[rq]) prints the parsed contents of the configuration file
|
2018-11-16 21:16:00 +01:00
|
|
|
in a human\-readable form whenever the file is loaded; \f[C]k\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
(\[lq]keys\[rq]) shows the recognized translations as the program
|
2018-11-16 21:16:00 +01:00
|
|
|
executes them, in the same format as \f[C]s\f[R]; \f[C]m\f[R]
|
|
|
|
(\[lq]MIDI\[rq]) prints \f[I]any\f[R] received MIDI input, so that you
|
2018-09-20 14:26:31 +02:00
|
|
|
can figure out which MIDI tokens to use for configuring the translations
|
2018-11-16 21:16:00 +01:00
|
|
|
for your controller; and \f[C]j\f[R] adds some useful information about
|
2018-09-20 14:26:31 +02:00
|
|
|
the Jack backend, so that you see when the Jack client is ready, and
|
|
|
|
which MIDI ports it gets connected to.
|
2018-11-16 21:16:00 +01:00
|
|
|
You can also just use \f[C]\-d\f[R] to enable all debugging output.
|
2018-09-20 14:26:31 +02:00
|
|
|
Moreover, most of these options are also available as directives in the
|
|
|
|
midizaprc file, so that you can turn them on and off as needed without
|
|
|
|
having to exit the program; please check the comments at the beginning
|
|
|
|
of example.midizaprc for a list of these directives.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-09-12 10:52:47 +02:00
|
|
|
Most of the other translations in the distributed midizaprc file assume
|
|
|
|
a Mackie\-like device with standard playback controls and a jog wheel.
|
|
|
|
There are also a few more generic examples, like the one above, which
|
2018-08-23 12:17:05 +02:00
|
|
|
will work with almost any kind of MIDI keyboard.
|
|
|
|
The examples are mostly for illustrative and testing purposes, though,
|
|
|
|
to help you get started.
|
|
|
|
You will want to edit them and add translations for your own controllers
|
|
|
|
and favorite applications.
|
2018-08-16 18:34:02 +02:00
|
|
|
.SH MIDI Output
|
|
|
|
.PP
|
|
|
|
As already mentioned, the midizap program can also be made to function
|
|
|
|
as a MIDI mapper which translates MIDI input to MIDI output.
|
2018-11-16 21:16:00 +01:00
|
|
|
MIDI output is enabled by running the program as \f[C]midizap \-o\f[R].
|
2018-08-16 18:34:02 +02:00
|
|
|
This equips the Jack client with an additional MIDI output port named
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]midi_out\f[R] (visible on the left side of QjackCtl\[cq]s
|
|
|
|
Connection window).
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
|
|
|
The example.midizaprc file comes with a sample configuration in the
|
2018-11-16 21:16:00 +01:00
|
|
|
special \f[C][MIDI]\f[R] default section for illustration purposes.
|
|
|
|
This section is only active if the program is run with the \f[C]\-o\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
option.
|
|
|
|
It allows MIDI output to be sent to any connected applications, no
|
|
|
|
matter which window currently has the keyboard focus.
|
|
|
|
This is probably the most common way to use this feature, but of course
|
|
|
|
it is also possible to have application\-specific MIDI translations, in
|
|
|
|
the same way as with X11 key bindings.
|
|
|
|
In fact, you can freely mix mouse actions, key presses and MIDI messages
|
|
|
|
in all translations.
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
You can try it and test that it works by running \f[C]midizap \-o\f[R]
|
2018-08-28 00:02:49 +02:00
|
|
|
along with a MIDI synthesizer such as
|
2018-08-16 18:34:02 +02:00
|
|
|
FluidSynth (http://www.fluidsynth.org/) or its graphical front\-end
|
2018-08-28 00:02:49 +02:00
|
|
|
Qsynth (https://qsynth.sourceforge.io/).
|
2018-11-16 21:16:00 +01:00
|
|
|
Use QjackCtl to connect FluidSynth\[cq]s MIDI input to midizap\[cq]s
|
|
|
|
output port.
|
|
|
|
In the sample configuration, the notes \f[C]C4\f[R] thru \f[C]F4\f[R] in
|
2018-08-31 02:15:56 +02:00
|
|
|
the small octave have been set up so that you can use them to operate a
|
2018-11-16 21:16:00 +01:00
|
|
|
little drumkit, and a binding for the volume controller (\f[C]CC7\f[R])
|
2018-08-31 02:15:56 +02:00
|
|
|
has been added as well.
|
2018-08-16 18:34:02 +02:00
|
|
|
The relevant portion from the configuration entry looks as follows:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
|
|
|
[MIDI]
|
|
|
|
|
2018-11-16 21:16:00 +01:00
|
|
|
C4 C3\-10
|
|
|
|
D4 C#3\-10
|
|
|
|
E4 D3\-10
|
|
|
|
F4 D#3\-10
|
2018-08-16 18:34:02 +02:00
|
|
|
|
2018-11-16 21:16:00 +01:00
|
|
|
CC7= CC7\-10
|
|
|
|
\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Note the \f[C]\-10\f[R] suffix on the output messages in the above
|
2018-08-16 18:34:02 +02:00
|
|
|
example, which indicates that output goes to MIDI channel 10.
|
|
|
|
In midizaprc syntax, MIDI channels are 1\-based, so they are numbered
|
|
|
|
1..16, and 10 denotes the GM (General MIDI) drum channel.
|
2018-11-16 21:16:00 +01:00
|
|
|
E.g., the input note \f[C]C4\f[R] is mapped to \f[C]C3\-10\f[R], the
|
|
|
|
note C in the third MIDI octave, which on channel 10 will produce the
|
|
|
|
sound of a bass drum, at least on GM compatible synthesizers like
|
|
|
|
Fluidsynth.
|
|
|
|
The binding for the volume controller (\f[C]CC7\f[R]) at the end of the
|
|
|
|
entry sends volume changes to the same drum channel (\f[C]CC7\-10\f[R]),
|
2018-08-31 02:15:56 +02:00
|
|
|
so that you can use the volume control on your keyboard to change the
|
|
|
|
volume on the drum channel.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Besides MIDI notes and control change (\f[C]CC\f[R]) messages, the
|
|
|
|
midizap program also recognizes key and channel pressure (\f[C]KP\f[R],
|
|
|
|
\f[C]CP\f[R]), program change (\f[C]PC\f[R]), and pitch bend
|
|
|
|
(\f[C]PB\f[R]) messages, which should cover most common use cases.
|
|
|
|
These are discussed in more detail in the \f[I]Translation Syntax\f[R]
|
2018-08-27 04:23:32 +02:00
|
|
|
section below.
|
2018-09-20 01:24:52 +02:00
|
|
|
In addition, unrecognized MIDI messages can be simply passed through
|
2018-11-16 21:16:00 +01:00
|
|
|
with the \f[C]\-t\f[R] option.
|
2018-09-20 01:24:52 +02:00
|
|
|
Also, while midizap cannot translate system messages such as system
|
2018-11-16 21:16:00 +01:00
|
|
|
exclusive, you can pass them through as well with the \f[C]\-s\f[R]
|
2018-09-20 01:24:52 +02:00
|
|
|
option, see the following section for details.
|
2018-08-27 04:23:32 +02:00
|
|
|
.SH Jack\-Related Options
|
|
|
|
.PP
|
|
|
|
There are some additional directives (and corresponding command line
|
2018-11-16 21:16:00 +01:00
|
|
|
options) to configure midizap\[cq]s Jack setup in various ways.
|
2018-09-20 19:09:07 +02:00
|
|
|
If both the command line options and directives in the midizaprc file
|
2018-11-16 21:16:00 +01:00
|
|
|
are used, the former take priority, so that it\[cq]s possible to
|
|
|
|
override the configuration settings from the command line.
|
2018-10-13 03:27:07 +02:00
|
|
|
Note that all these options can only be set at program startup.
|
|
|
|
If you later edit the corresponding directives in the configuration
|
2018-11-16 21:16:00 +01:00
|
|
|
file, the changes won\[cq]t take effect until you restart the program.
|
2018-10-13 03:27:07 +02:00
|
|
|
.SS Jack Client Name and MIDI Port Setup
|
2018-08-27 04:23:32 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Firstly, there\[cq]s the \f[C]\-j\f[R] option and the
|
|
|
|
\f[C]JACK_NAME\f[R] directive which change the Jack client name from the
|
|
|
|
default (\f[C]midizap\f[R]) to whatever you want it to be.
|
2018-08-27 04:23:32 +02:00
|
|
|
To use this option, simply invoke midizap as
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]midizap \-j client\-name\f[R], or put the following directive into
|
2018-08-27 04:23:32 +02:00
|
|
|
your midizaprc file:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
JACK_NAME \[dq]client\-name\[dq]
|
|
|
|
\f[R]
|
2018-08-27 04:23:32 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
This option is useful, in particular, if you\[cq]re running multiple
|
2018-08-27 04:23:32 +02:00
|
|
|
instances of midizap with different configurations for different
|
|
|
|
controllers and/or target applications, and you want to have the
|
2018-09-20 19:09:07 +02:00
|
|
|
corresponding Jack clients named differently, so that they can be
|
|
|
|
identified more easily.
|
2018-08-27 04:23:32 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Secondly, we\[cq]ve already seen the \f[C]\-o\f[R] option which is used
|
|
|
|
to equip the Jack client with an additional output port.
|
|
|
|
This can also be achieved with the \f[C]JACK_PORTS\f[R] directive in the
|
2018-08-27 04:23:32 +02:00
|
|
|
midizaprc file, as follows:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
JACK_PORTS 1
|
|
|
|
\f[R]
|
2018-08-27 04:23:32 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-02 00:12:24 +02:00
|
|
|
The given number of output ports must be 0, 1 or 2.
|
2018-09-20 01:24:52 +02:00
|
|
|
Zero means that MIDI output is disabled (which is the default).
|
2018-11-16 21:16:00 +01:00
|
|
|
You may want to use \f[C]JACK_PORTS 1\f[R] if the configuration is
|
|
|
|
primarily aimed at doing MIDI translations, so you\[cq]d like to have
|
|
|
|
MIDI output enabled by default.
|
|
|
|
\f[C]JACK_PORTS 2\f[R] or the \f[C]\-o2\f[R] option indicates that
|
|
|
|
\f[I]two\f[R] pairs of input and output ports are to be created.
|
2018-09-20 01:24:52 +02:00
|
|
|
The second port is typically used to deal with controller feedback from
|
2018-11-16 21:16:00 +01:00
|
|
|
the application, see the \f[I]MIDI Feedback\f[R] section for details.
|
2018-09-20 01:24:52 +02:00
|
|
|
.PP
|
2018-09-20 19:09:07 +02:00
|
|
|
Not very surprisingly, at least one output port is needed if you want to
|
|
|
|
output any MIDI at all; otherwise MIDI messages on the right\-hand side
|
|
|
|
of translations will be silently ignored.
|
2018-10-13 03:27:07 +02:00
|
|
|
.SS MIDI Connections
|
|
|
|
.PP
|
|
|
|
Setting up all the required connections for the Jack MIDI ports can be a
|
|
|
|
tedious and error\-prone task, especially if you have to deal with
|
|
|
|
complex setups involving feedback and/or multiple midizap instances.
|
2018-11-16 21:16:00 +01:00
|
|
|
It\[cq]s all to easy to mess this up when doing it manually, and end up
|
|
|
|
with a dysfunctional setup or, even worse, MIDI feedback loops crashing
|
|
|
|
your Jack MIDI clients.
|
|
|
|
While it\[cq]s possible to automatize the MIDI connections, e.g., with
|
|
|
|
QjackCtl\[cq]s persistent MIDI patchbay facility, this is often
|
|
|
|
inconvenient if you need to accommodate multiple midizap configurations
|
|
|
|
and you already have a complicated studio setup which you don\[cq]t want
|
|
|
|
to mess with.
|
2018-10-13 03:27:07 +02:00
|
|
|
.PP
|
|
|
|
As a remedy, midizap offers its own built\-in patchbay functionality
|
2018-11-16 21:16:00 +01:00
|
|
|
using the \f[C]JACK_IN\f[R] and \f[C]JACK_OUT\f[R] directives, which let
|
2018-10-13 03:27:07 +02:00
|
|
|
you specify the required connections in the configuration itself and be
|
|
|
|
done with it.
|
|
|
|
The port number is tacked on to the directive, so, e.g.,
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]JACK_IN2\f[R] connects the second input port.
|
2018-10-15 06:23:23 +02:00
|
|
|
If the port number is omitted then it defaults to 1, so both
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]JACK_OUT1\f[R] and just \f[C]JACK_OUT\f[R] connect the first output
|
2018-10-15 06:23:23 +02:00
|
|
|
port.
|
|
|
|
The directive is followed by a regular expression to be matched against
|
|
|
|
the Jack MIDI ports of your devices and applications.
|
|
|
|
Please see the regex(7) manual page for a discussion of the syntax and
|
|
|
|
meaning of regular expressions.
|
|
|
|
Note that regular expressions come in two different flavors,
|
|
|
|
\[lq]basic\[rq] and \[lq]extended\[rq]; midizap uses the latter kind.
|
|
|
|
.PP
|
2018-10-13 03:27:07 +02:00
|
|
|
A connection will be established automatically by midizap whenever a
|
2018-10-15 06:23:23 +02:00
|
|
|
MIDI port belonging to another Jack client matches the regular
|
|
|
|
expression, as well as the port type and I/O direction.
|
2018-10-13 03:27:07 +02:00
|
|
|
This also works dynamically, as new devices get added and new
|
|
|
|
applications are launched at runtime.
|
|
|
|
.PP
|
|
|
|
For instance, the following lines (from the XTouchONE.midizaprc example)
|
2018-11-16 21:16:00 +01:00
|
|
|
connect midizap to an X\-Touch One device on one side and Ardour\[cq]s
|
2018-10-13 03:27:07 +02:00
|
|
|
Mackie control port on the other:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
JACK_IN1 X\-Touch One MIDI 1
|
|
|
|
JACK_OUT1 ardour:mackie control in
|
|
|
|
JACK_IN2 ardour:mackie control out
|
|
|
|
JACK_OUT2 X\-Touch One MIDI 1
|
|
|
|
\f[R]
|
2018-10-13 03:27:07 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
To break this down, the X\-Touch One device will be connected to
|
2018-11-16 21:16:00 +01:00
|
|
|
midizap\[cq]s first input port, midizap\[cq]s first output port to
|
|
|
|
Ardour\[cq]s Mackie control input, Ardour\[cq]s Mackie control output to
|
|
|
|
midizap\[cq]s second input port, and midizap\[cq]s second output port
|
|
|
|
back to the device.
|
2018-10-13 03:27:07 +02:00
|
|
|
This is a typical setup for bidirectional communication between
|
2018-11-16 21:16:00 +01:00
|
|
|
controller and application as described in the \f[I]MIDI Feedback\f[R]
|
2018-10-13 03:27:07 +02:00
|
|
|
section.
|
|
|
|
The sample configurations in the examples folder in the sources have all
|
|
|
|
been set up in this manner, so that they will create the required
|
|
|
|
connections automatically.
|
|
|
|
.PP
|
2018-10-15 06:23:23 +02:00
|
|
|
Please note that in the present implementation, the built\-in patchbay
|
|
|
|
is only available through these directives, there are no corresponding
|
|
|
|
command line options.
|
2018-10-13 03:27:07 +02:00
|
|
|
Also, only one directive can be specified for each port, but since
|
|
|
|
midizap will connect to all ports matching the given regular expression,
|
|
|
|
you can connect to more than one application or device by just listing
|
|
|
|
all the alternatives.
|
2018-11-16 21:16:00 +01:00
|
|
|
For instance, to have midizap\[cq]s output connected to both Ardour and
|
|
|
|
Pd, you might use a directive like:
|
2018-10-13 03:27:07 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
JACK_OUT1 ardour:MIDI control in|Pure Data Midi\-In 1
|
|
|
|
\f[R]
|
2018-10-13 03:27:07 +02:00
|
|
|
.fi
|
2018-10-15 06:23:23 +02:00
|
|
|
.PP
|
|
|
|
All matches are done against full port names including the
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]client\-name\f[R]\f[C]:\f[R] prefix, so you can specify exactly
|
|
|
|
which ports of which clients should be connected.
|
2018-10-15 06:23:23 +02:00
|
|
|
However, note that in contrast to the QJackCtl patchbay, midizap does
|
2018-11-16 21:16:00 +01:00
|
|
|
substring matches by default, so that, e.g., \f[C]MIDI control\f[R] will
|
|
|
|
match \f[I]any\f[R] Ardour MIDI control port, in any instance of the
|
2018-10-15 06:23:23 +02:00
|
|
|
program (and also ports with the same name in other programs).
|
2018-11-16 21:16:00 +01:00
|
|
|
If you want to specify an exact match, you need to use the
|
|
|
|
\f[C]\[ha]\f[R] and \f[C]$\f[R] anchors as follows:
|
2018-10-15 06:23:23 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
JACK_OUT1 \[ha]ardour:MIDI control in$
|
|
|
|
\f[R]
|
2018-10-15 06:23:23 +02:00
|
|
|
.fi
|
2018-10-13 03:27:07 +02:00
|
|
|
.SS Pass\-Through
|
2018-09-20 01:24:52 +02:00
|
|
|
.PP
|
|
|
|
If at least one output port is available then it also becomes possible
|
|
|
|
to pass through MIDI messages from input to output unchanged.
|
2018-11-16 21:16:00 +01:00
|
|
|
Two options are available for this: \f[C]\-t\f[R] which passes through
|
2018-09-20 01:24:52 +02:00
|
|
|
any ordinary (non\-system) message for which there are no translations
|
2018-11-16 21:16:00 +01:00
|
|
|
(not even in the default section), and \f[C]\-s\f[R] which passes
|
|
|
|
through all system messages.
|
2018-09-20 19:09:07 +02:00
|
|
|
The former is convenient if the incoming MIDI data only needs to be
|
|
|
|
modified in a few places to deal with slight variations in the protocol.
|
2018-09-20 01:24:52 +02:00
|
|
|
The latter may be needed when the input data may contain system
|
|
|
|
messages; midizap cannot translate these, but it can pass them on
|
|
|
|
unchanged when necessary.
|
|
|
|
You can find examples for both use cases in the examples folder in the
|
|
|
|
sources.
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
The corresponding directives are named \f[C]PASSTHROUGH\f[R] and
|
|
|
|
\f[C]SYSTEM_PASSTHROUGH\f[R], respectively.
|
2018-09-20 01:24:52 +02:00
|
|
|
In either case, you can optionally specify which port the pass\-through
|
2018-09-20 19:09:07 +02:00
|
|
|
should apply to (0 means none, 1 the first, 2 the second port; if no
|
|
|
|
number is given, both ports are used).
|
2018-09-18 22:31:22 +02:00
|
|
|
For instance, if you only need system pass\-through on the feedback
|
2018-11-16 21:16:00 +01:00
|
|
|
port, you might write \f[C]SYSTEM_PASSTHROUGH 2\f[R], or use the
|
|
|
|
\f[C]\-s2\f[R] option on the command line; and to have unrecognized MIDI
|
2018-09-20 19:09:07 +02:00
|
|
|
messages passed through in either direction, simply use
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]PASSTHROUGH\f[R], or \f[C]\-t\f[R].
|
2018-10-13 03:27:07 +02:00
|
|
|
.SS Jack Sessions
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
midizap also supports \f[I]Jack session management\f[R] which provides a
|
2018-10-13 03:27:07 +02:00
|
|
|
convenient alternative way to launch your midizap instances.
|
2018-11-16 21:16:00 +01:00
|
|
|
Once you\[cq]ve finished a configuration, instead of running midizap
|
2018-10-13 03:27:07 +02:00
|
|
|
manually each time you need it, you just invoke it once with the right
|
|
|
|
command line options, and use a Jack session management program to
|
|
|
|
record the session.
|
|
|
|
The session manager can then be used to relaunch the program with the
|
|
|
|
same options later.
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Various Jack session managers are available for Linux, but if you\[cq]re
|
2018-10-13 03:27:07 +02:00
|
|
|
running QjackCtl already, you might just as well use it to record your
|
|
|
|
sessions, too.
|
2018-11-16 21:16:00 +01:00
|
|
|
QjackCtl\[cq]s built\-in Jack session manager is available in its
|
|
|
|
Session dialog.
|
2018-10-13 03:27:07 +02:00
|
|
|
To use it, launch midizap and any other Jack applications you want to
|
2018-08-27 04:23:32 +02:00
|
|
|
have in the session, use QjackCtl to set up all the connections as
|
2018-08-31 02:15:56 +02:00
|
|
|
needed, and then hit the \[lq]Save\[rq] button in the Session dialog to
|
|
|
|
have the session recorded.
|
2018-09-20 19:09:07 +02:00
|
|
|
Now, at any later time you can rerun the recorded session with the
|
|
|
|
\[lq]Load\[rq] button in the same dialog.
|
2018-09-02 00:12:24 +02:00
|
|
|
Also, your most recent sessions are available in the \[lq]Recent\[rq]
|
|
|
|
menu from where they can be launched quickly.
|
2018-10-13 03:27:07 +02:00
|
|
|
.SS Realtime Priorities
|
2018-09-18 22:31:22 +02:00
|
|
|
.PP
|
|
|
|
Finally, midizap also offers an option to run the program with
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]real\-time priorities\f[R].
|
|
|
|
Jack itself usually does that anyway where needed, but midizap\[cq]s
|
|
|
|
main thread won\[cq]t unless you run it with the \f[C]\-P\f[R] option.
|
2018-09-18 22:31:22 +02:00
|
|
|
Using this option, midizap should be able to get down to MIDI latencies
|
2018-09-20 01:24:52 +02:00
|
|
|
in the 1 msec ballpark which should be good enough for most purposes.
|
2018-11-16 21:16:00 +01:00
|
|
|
(Note that there\[cq]s no need to use this option unless you actually
|
|
|
|
notice high latencies or jitter in the MIDI output.)
|
2018-08-17 01:44:26 +02:00
|
|
|
.SH Translation Syntax
|
|
|
|
.PP
|
2018-08-18 00:09:48 +02:00
|
|
|
The midizap configuration file consists of sections defining translation
|
|
|
|
classes.
|
2018-08-20 21:50:44 +02:00
|
|
|
Each section generally looks like this, specifying the name of a
|
|
|
|
translation class, optionally a regular expression to be matched against
|
|
|
|
the window class or title, and a list of translations:
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
[name] regex
|
|
|
|
<A..G><#b><0..12> output # note
|
|
|
|
KP:<note> output # key pressure (aftertouch)
|
|
|
|
PC<0..127> output # program change
|
|
|
|
CC<0..127> output # control change
|
|
|
|
CP output # channel pressure
|
|
|
|
PB output # pitch bend
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
The \f[C]#\f[R] character at the beginning of a line and after
|
|
|
|
whitespace is special; it indicates that the rest of the line is a
|
|
|
|
comment, which is skipped by the parser.
|
2018-08-18 00:09:48 +02:00
|
|
|
Empty lines and lines containing nothing but whitespace are also
|
|
|
|
ignored.
|
2018-08-17 01:44:26 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Lines beginning with a \f[C][\f[R]\f[I]name\f[R]\f[C]]\f[R] header are
|
|
|
|
also special.
|
|
|
|
Each such line introduces a translation class \f[I]name\f[R], which may
|
|
|
|
be followed by an extended regular expression \f[I]regex\f[R] to be
|
2018-10-13 03:27:07 +02:00
|
|
|
matched against window class and title.
|
2018-11-16 21:16:00 +01:00
|
|
|
A \f[C]CLASS\f[R] or \f[C]TITLE\f[R] token may precede \f[I]regex\f[R]
|
|
|
|
to indicate that \f[I]only\f[R] the class or title is to be matched,
|
2018-09-22 21:21:10 +02:00
|
|
|
respectively; otherwise both are matched.
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that the \f[I]regex\f[R] part is always taken verbatim, ignoring
|
2018-09-22 21:21:10 +02:00
|
|
|
leading and trailing whitespace, but including embedded whitespace and
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]#\f[R] characters (so you can\[cq]t place a comment on such lines).
|
2018-09-22 21:21:10 +02:00
|
|
|
.PP
|
|
|
|
To find a set of eligible translations, midizap matches class and/or
|
|
|
|
title of the window with the keyboard focus against each section, in the
|
|
|
|
order in which they are listed in the configuration file.
|
2018-11-16 21:16:00 +01:00
|
|
|
If neither \f[C]CLASS\f[R] nor \f[C]TITLE\f[R] is specified, then both
|
|
|
|
are tried; in this case, midizap first tries to match the window class
|
|
|
|
(the \f[C]WM_CLASS\f[R] property), then the window title (the
|
|
|
|
\f[C]WM_NAME\f[R] property).
|
2018-09-14 09:58:57 +02:00
|
|
|
The first section which matches determines the translations to be used
|
|
|
|
for that window.
|
2018-11-16 21:16:00 +01:00
|
|
|
An empty \f[I]regex\f[R] for the last class will always match, allowing
|
2018-09-14 09:58:57 +02:00
|
|
|
default translations.
|
|
|
|
If a translation cannot be found in the matched section, it will be
|
|
|
|
loaded from the default section if possible.
|
|
|
|
In addition, there are two special default sections labeled
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C][MIDI]\f[R] and \f[C][MIDI2]\f[R] which are used specifically for
|
|
|
|
MIDI translations, please see the \f[I]MIDI Output\f[R] and \f[I]MIDI
|
|
|
|
Feedback\f[R] sections for details.
|
2018-09-14 09:58:57 +02:00
|
|
|
If these sections are present, they should precede the main default
|
|
|
|
section.
|
|
|
|
All other sections, including the main default section, can be named any
|
2018-11-16 21:16:00 +01:00
|
|
|
way you like; the given \f[I]name\f[R] is only used for debugging output
|
|
|
|
and diagnostics, and needn\[cq]t be unique.
|
2018-09-14 09:58:57 +02:00
|
|
|
.PP
|
|
|
|
This means that when you start writing a section for a new application,
|
2018-11-16 21:16:00 +01:00
|
|
|
the first thing you\[cq]ll have to do is determine its window class and
|
2018-09-14 09:58:57 +02:00
|
|
|
title, so that you can figure out a regular expression to use in the
|
|
|
|
corresponding section header.
|
2018-11-16 21:16:00 +01:00
|
|
|
The easiest way to do this is to run midizap with the \f[C]\-dr\f[R]
|
2018-09-14 09:58:57 +02:00
|
|
|
option.
|
|
|
|
Make sure that your controller is hooked up to midizap, click on the
|
|
|
|
window and wiggle any control on your device.
|
2018-11-16 21:16:00 +01:00
|
|
|
You\[cq]ll get a message like the following, telling you both the title
|
|
|
|
and the class name of the window (as well as the name of the translation
|
2018-09-14 09:19:37 +02:00
|
|
|
class if the window is already recognized):
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
translation: Default for mysession \- Ardour (class ardour_ardour)
|
|
|
|
\f[R]
|
2018-09-14 09:19:37 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
Here, the class name is \[lq]ardour_ardour\[rq] and the window title
|
|
|
|
\[lq]mysession \- Ardour\[rq].
|
|
|
|
Either can be used for the regular expression, but the class name
|
|
|
|
usually provides the more specific clues for identifying an application.
|
2018-09-22 21:21:10 +02:00
|
|
|
So we might begin a translation section for Ardour as follows:
|
2018-09-14 09:19:37 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
[Ardour] CLASS \[ha]ardour_ardour$
|
|
|
|
\f[R]
|
2018-09-14 09:19:37 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-22 21:21:10 +02:00
|
|
|
Here we explicitly specified that only the window class is to be matched
|
2018-11-16 21:16:00 +01:00
|
|
|
and we employed the \f[C]\[ha]\f[R] and \f[C]$\f[R] anchors to ensure
|
|
|
|
that the entire string is matched, so this section will match precisely
|
|
|
|
Ardour windows and nothing else.
|
2018-09-22 21:21:10 +02:00
|
|
|
We could also write, rather sloppily:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
[Ardour] [Aa]rdour
|
|
|
|
\f[R]
|
2018-09-22 21:21:10 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
This will match any window which has the string \[lq]Ardour\[rq] or
|
2018-11-16 21:16:00 +01:00
|
|
|
\[lq]ardour\[rq] \f[I]anywhere\f[R] in its class or title, so it will
|
2018-09-22 21:21:10 +02:00
|
|
|
match Ardour windows, but also, say, the window of a text editor which
|
|
|
|
happens to have a file named \[lq]Ardour.txt\[rq] loaded.
|
|
|
|
So while regular expressions give you a lot of leeway in identifying
|
2018-11-16 21:16:00 +01:00
|
|
|
windows, it\[cq]s always a good idea to be as specific with the regex as
|
2018-09-22 21:21:10 +02:00
|
|
|
possible.
|
|
|
|
.PP
|
2018-09-14 09:58:57 +02:00
|
|
|
The header is followed by a list of translations which define what
|
|
|
|
output should be produced for the given MIDI input.
|
2018-08-20 21:50:44 +02:00
|
|
|
Each translation must be on a line by itself.
|
2018-08-28 18:07:31 +02:00
|
|
|
The left\-hand side (first token) of the translation denotes the MIDI
|
2018-08-17 01:44:26 +02:00
|
|
|
message to be translated.
|
2018-08-28 18:07:31 +02:00
|
|
|
The corresponding right\-hand side (the rest of the line) is a sequence
|
2018-09-13 19:37:43 +02:00
|
|
|
of zero or more tokens, separated by whitespace, indicating MIDI and X11
|
|
|
|
keyboard and mouse events to be output.
|
2018-11-16 21:16:00 +01:00
|
|
|
The output sequence may be empty, or just the special token
|
|
|
|
\f[C]NOP\f[R] (which doesn\[cq]t produce any output), to indicate that
|
|
|
|
the translation outputs nothing at all; this suppresses the default
|
|
|
|
translation for this input.
|
2018-09-04 07:53:18 +02:00
|
|
|
Translation classes may be empty as well (i.e., not provide any
|
2018-11-16 21:16:00 +01:00
|
|
|
translations), in which case \f[I]only\f[R] the default translations are
|
2018-09-04 07:53:18 +02:00
|
|
|
active, even if a later non\-default section matches the same window.
|
2018-08-28 18:07:31 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[B]NOTE:\f[R] Translations may be listed in any order, but they
|
|
|
|
\f[I]must be determined uniquely\f[R], i.e., each input message may be
|
2018-09-14 09:58:57 +02:00
|
|
|
bound to at most one output sequence in each translation class.
|
|
|
|
Otherwise, the parser will print an error message, and the extra
|
|
|
|
translations will be ignored.
|
|
|
|
This restriction makes it easier to detect inconsistencies, and it also
|
2018-11-16 21:16:00 +01:00
|
|
|
ensures that midizap\[cq]s operation is completely
|
|
|
|
\f[I]deterministic\f[R].
|
2018-09-14 09:58:57 +02:00
|
|
|
That is, for each input sequence on a given window the program will
|
|
|
|
always generate exactly the same output sequence.
|
|
|
|
.PP
|
2018-09-03 23:33:37 +02:00
|
|
|
Example:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
[Terminal] CLASS \[ha](.*\-terminal.*|konsole|xterm)$
|
|
|
|
F5 XK_Up
|
|
|
|
F#5 \[dq]pwd\[dq]
|
|
|
|
G5 XK_Down
|
|
|
|
G#5 \[dq]ls\[dq]
|
|
|
|
A5 XK_Return
|
|
|
|
\f[R]
|
2018-09-03 23:33:37 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-04 07:53:18 +02:00
|
|
|
This binds a few keys in the middle octave to the Up, Down and Return
|
|
|
|
keys as well as some frequently used shell commands, in a section named
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]Terminal\f[R] which matches some common types of terminal windows
|
|
|
|
by their class names.
|
2018-09-04 07:53:18 +02:00
|
|
|
The bindings in this translation class will let you operate the shell
|
|
|
|
from your MIDI keyboard when the keyboard focus is on a terminal window.
|
2018-08-28 18:07:31 +02:00
|
|
|
.SS MIDI Message Notation
|
2018-08-17 01:44:26 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
There\[cq]s no real standard for symbolic designations of MIDI messages,
|
|
|
|
but we hope that most users will find midizap\[cq]s notation easy to
|
|
|
|
understand and remember.
|
2018-09-12 10:52:47 +02:00
|
|
|
Notes are specified using a format which musicians will find familiar: a
|
2018-11-16 21:16:00 +01:00
|
|
|
note name \f[C]A\f[R], \f[C]B\f[R], \&..., \f[C]G\f[R] is followed by an
|
|
|
|
(optional) accidental (\f[C]#\f[R] or \f[C]b\f[R]), and a (mandatory)
|
|
|
|
MIDI octave number.
|
|
|
|
Note that all MIDI octaves start at the note C, so \f[C]B0\f[R] comes
|
|
|
|
before \f[C]C1\f[R].
|
|
|
|
By default, \f[C]C5\f[R] denotes middle C (you can change this if you
|
|
|
|
want, see \f[I]Octave Numbering\f[R] below).
|
|
|
|
Enharmonic spellings are equivalent, so, e.g., \f[C]D#5\f[R] and
|
|
|
|
\f[C]Eb5\f[R] denote exactly the same MIDI note.
|
2018-09-02 11:47:08 +02:00
|
|
|
.PP
|
|
|
|
The other messages are denoted using short mnemonics:
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]KP:\f[R]\f[I]note\f[R] (aftertouch a.k.a.\ key pressure for the
|
|
|
|
given note); \f[C]CC\f[R]\f[I]n\f[R] (control change for the given
|
|
|
|
controller number); \f[C]PC\f[R]\f[I]n\f[R] (program change for the
|
|
|
|
given program number); \f[C]CP\f[R] (channel pressure); and \f[C]PB\f[R]
|
|
|
|
(pitch bend).
|
2018-08-28 00:02:49 +02:00
|
|
|
We will go into the other syntactic bits and pieces of MIDI message
|
2018-11-16 21:16:00 +01:00
|
|
|
designations later, but it\[cq]s good to have the following grammar in
|
|
|
|
EBNF notation handy for reference.
|
2018-08-25 22:55:02 +02:00
|
|
|
(To keep things simple, the grammar is somewhat abridged, but it covers
|
|
|
|
all the frequently used notation.
|
2018-08-28 18:07:31 +02:00
|
|
|
There is some additional syntax for special forms of translations which
|
2018-09-18 00:06:55 +02:00
|
|
|
will be introduced later.
|
|
|
|
Also, at the end of the manual you can find a complete grammar for the
|
|
|
|
entire configuration language.)
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
token ::= msg [ \[dq][\[dq] number \[dq]]\[dq] ] [ \[dq]\-\[dq] number ] [ flag ]
|
|
|
|
msg ::= ( note | other ) [ number ]
|
|
|
|
note ::= ( \[dq]A\[dq] | ... | \[dq]G\[dq] ) [ \[dq]#\[dq] | \[dq]b\[dq] ]
|
|
|
|
other ::= \[dq]CH\[dq] | \[dq]PB\[dq] | \[dq]PC\[dq] | \[dq]CC\[dq] | \[dq]CP\[dq] | \[dq]KP:\[dq] note
|
|
|
|
flag ::= \[dq]\-\[dq] | \[dq]+\[dq] | \[dq]=\[dq] | \[dq]<\[dq] | \[dq]>\[dq] | \[dq]\[ti]\[dq]
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Case is ignored here, so \f[C]CC\f[R], \f[C]cc\f[R] or even \f[C]Cc\f[R]
|
2018-08-19 12:19:48 +02:00
|
|
|
are considered to be exactly the same token by the parser, although by
|
|
|
|
convention we usually write them in uppercase.
|
2018-08-17 01:44:26 +02:00
|
|
|
Numbers are always integers in decimal.
|
2018-11-16 21:16:00 +01:00
|
|
|
The meaning of the \f[C]msg\f[R] number depends on the context (octave
|
2018-08-31 02:15:56 +02:00
|
|
|
number for notes and key pressure, controller or program number in the
|
|
|
|
range 0..127 for other messages, MIDI channel number in the range 1..16
|
2018-11-16 21:16:00 +01:00
|
|
|
for the special \f[C]CH\f[R] token).
|
2018-08-17 01:44:26 +02:00
|
|
|
This can optionally be followed by a number in brackets, denoting a
|
|
|
|
nonzero step size.
|
2018-08-31 02:15:56 +02:00
|
|
|
Also optionally, a suffix with a third number (after the dash) denotes
|
|
|
|
the MIDI channel in the range 1..16; otherwise the default MIDI channel
|
|
|
|
is used (which is always 1 on the left\-hand side, but can be set on the
|
2018-11-16 21:16:00 +01:00
|
|
|
right\-hand side with the \f[C]CH\f[R] token).
|
2018-08-30 14:46:44 +02:00
|
|
|
The optional \[lq]increment\[rq] flag at the end of a token indicates a
|
2018-08-23 12:17:05 +02:00
|
|
|
\[lq]data\[rq] translation which responds to incremental (up/down) value
|
2018-11-16 21:16:00 +01:00
|
|
|
changes rather than key presses, cf.\ \f[I]Key and Data
|
|
|
|
Translations\f[R] below.
|
2018-08-17 01:44:26 +02:00
|
|
|
.SS Octave Numbering
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
|
|
|
A note on the octave numbers in MIDI note designations is in order here.
|
|
|
|
There are various different standards for numbering octaves, and
|
|
|
|
different programs use different standards, which can be rather
|
|
|
|
confusing.
|
2018-11-16 21:16:00 +01:00
|
|
|
E.g., there\[cq]s the ASA (Acoustical Society of America) standard where
|
2018-08-16 18:34:02 +02:00
|
|
|
middle C is C4, also known as \[lq]scientific\[rq] or \[lq]American
|
|
|
|
standard\[rq] pitch notation.
|
|
|
|
At least two other standards exist specifically for MIDI octave
|
|
|
|
numbering, one in which middle C is C3 (so the lowest MIDI octave starts
|
|
|
|
at C\-2), and zero\-based octave numbers, which start at C0 and have
|
|
|
|
middle C at C5.
|
2018-11-16 21:16:00 +01:00
|
|
|
There\[cq]s not really a single \[lq]best\[rq] standard here, but the
|
|
|
|
latter seems intuitive to mathematically inclined and computer\-savvy
|
|
|
|
people, and is also what is used by default in the midizaprc file.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
However, you may want to change this, e.g., if you\[cq]re working with
|
2018-08-23 12:17:05 +02:00
|
|
|
documentation or MIDI monitoring software which uses a different
|
|
|
|
numbering scheme.
|
|
|
|
To do this, just specify the desired offset for the lowest MIDI octave
|
2018-11-16 21:16:00 +01:00
|
|
|
with the special \f[C]MIDI_OCTAVE\f[R] directive in the configuration
|
2018-08-16 18:34:02 +02:00
|
|
|
file.
|
|
|
|
For instance:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
MIDI_OCTAVE \-1 # ASA pitches (middle C is C4)
|
|
|
|
\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that this transposes \f[I]all\f[R] existing notes in translations
|
2018-08-23 12:17:05 +02:00
|
|
|
following the directive, so if you add this option to an existing
|
|
|
|
configuration, you probably have to edit the note messages in it
|
|
|
|
accordingly.
|
2018-09-13 19:37:43 +02:00
|
|
|
.SS Key and Data Translations
|
2018-08-19 12:19:48 +02:00
|
|
|
.PP
|
2018-09-13 19:37:43 +02:00
|
|
|
Translations come in two flavors or \[lq]modes\[rq], \f[I]key
|
2018-11-16 21:16:00 +01:00
|
|
|
translations\f[R] and \f[I]data translations\f[R], which differ in the
|
|
|
|
way the extra data payload of the input message, called the
|
|
|
|
\f[I]parameter value\f[R] (or just \f[I]value\f[R] for short), is
|
|
|
|
processed.
|
2018-08-28 10:41:36 +02:00
|
|
|
The parameter value depends on the type of MIDI message.
|
2018-11-16 21:16:00 +01:00
|
|
|
Program changes (\f[C]PC\f[R]) have no value at all.
|
|
|
|
For notes, as well as key and channel pressure messages (\f[C]CP\f[R],
|
|
|
|
\f[C]KP\f[R]), it is a velocity value; for control changes
|
|
|
|
(\f[C]CC\f[R]), a controller value; and for pitch bend messages
|
|
|
|
(\f[C]PB\f[R]), a pitch bend value.
|
2018-09-02 11:47:08 +02:00
|
|
|
The latter is a 14 bit value composed of the two data bytes in the
|
|
|
|
message, which is considered as a signed quantity in the range
|
2018-08-28 10:41:36 +02:00
|
|
|
\-8192..8191, where 0 denotes the center value.
|
|
|
|
In all other cases, the parameter value consists of a single data byte,
|
|
|
|
which denotes an unsigned 7 bit quantity in the range 0..127.
|
2018-08-18 00:09:48 +02:00
|
|
|
.PP
|
2018-09-02 11:47:08 +02:00
|
|
|
Note that since translations must be determined uniquely in each
|
2018-11-16 21:16:00 +01:00
|
|
|
translation class, you can\[cq]t have both key \f[I]and\f[R] data
|
|
|
|
translations for the same input in the same section; it\[cq]s either one
|
|
|
|
or the other.
|
2018-08-28 18:07:31 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]Key mode\f[R] is the default mode and is available for all message
|
2018-08-18 00:09:48 +02:00
|
|
|
types.
|
2018-08-19 12:19:48 +02:00
|
|
|
In this mode, MIDI messages are considered as keys which can be
|
|
|
|
\[lq]pressed\[rq] (\[lq]on\[rq]) or \[lq]released\[rq] (\[lq]off\[rq]).
|
|
|
|
Any nonzero data value means \[lq]pressed\[rq], zero \[lq]released\[rq].
|
|
|
|
Two special cases need to be considered here:
|
|
|
|
.IP \[bu] 2
|
2018-11-16 21:16:00 +01:00
|
|
|
For pitch bends, any positive \f[I]or\f[R] negative value means
|
2018-08-18 00:09:48 +02:00
|
|
|
\[lq]pressed\[rq], while 0 (the center value) means \[lq]released\[rq].
|
2018-08-19 12:19:48 +02:00
|
|
|
.IP \[bu] 2
|
|
|
|
Since program changes have no parameter value associated with them, they
|
2018-11-16 21:16:00 +01:00
|
|
|
don\[cq]t really have an \[lq]on\[rq] or \[lq]off\[rq] status.
|
2018-08-19 12:19:48 +02:00
|
|
|
But they are treated in the same key\-like fashion anyway, assuming that
|
|
|
|
they are \[lq]pressed\[rq] and then \[lq]released\[rq] immediately
|
|
|
|
afterwards.
|
|
|
|
.PP
|
2018-09-18 07:27:12 +02:00
|
|
|
Key mode can optionally keep track of the current key (on/off) status,
|
|
|
|
so that a key translation is only triggered when its status actually
|
|
|
|
changes.
|
2018-11-16 21:16:00 +01:00
|
|
|
Normally this shouldn\[cq]t be necessary and thus it is disabled by
|
|
|
|
default.
|
|
|
|
You usually want to keep it that way, unless you\[cq]re dealing with a
|
2018-09-18 22:31:22 +02:00
|
|
|
quirky controller or an unreliable transmission line.
|
2018-11-16 21:16:00 +01:00
|
|
|
In such cases it may useful to enable this option with the \f[C]\-k\f[R]
|
2018-09-18 07:27:12 +02:00
|
|
|
option on the command line, so that, e.g., repeated note\-ons or \-offs
|
|
|
|
are filtered out automatically.
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]Data mode\f[R] is available for all messages with a parameter
|
|
|
|
value, i.e., anything but \f[C]PC\f[R].
|
2018-08-28 00:02:49 +02:00
|
|
|
In this mode, the actual value of the message is processed rather than
|
|
|
|
just the on/off state.
|
2018-08-19 12:19:48 +02:00
|
|
|
Data mode is indicated with a special suffix on the message token which
|
2018-08-28 10:41:36 +02:00
|
|
|
denotes a step size and/or the direction of the value change which the
|
2018-11-16 21:16:00 +01:00
|
|
|
rule should apply to: increment (\f[C]+\f[R]), decrement (\f[C]\-\f[R]),
|
|
|
|
or both (\f[C]=\f[R]).
|
2018-08-28 00:02:49 +02:00
|
|
|
The two parts are both optional, but at least one of them must be
|
|
|
|
present (otherwise the rule is interpreted as a key translation).
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
In the following, we concentrate on \f[I]incremental\f[R] data mode
|
2018-09-13 19:37:43 +02:00
|
|
|
messages, i.e., the kind which has an increment suffix.
|
2018-08-27 16:01:19 +02:00
|
|
|
In this case, the optional step size in brackets indicates the amount of
|
|
|
|
change required to trigger the translation, so its effect is to
|
|
|
|
downscale the amount of change in the input value.
|
2018-09-13 19:37:43 +02:00
|
|
|
The variant without an increment suffix is more complicated and mostly
|
2018-11-16 21:16:00 +01:00
|
|
|
intended for more specialized uses, so we\[cq]ll have a look at it later
|
|
|
|
in the \f[I]Mod Translations\f[R] section.
|
2018-08-19 12:19:48 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Data mode usually tracks changes in the \f[I]absolute\f[R] value of a
|
2018-08-19 12:19:48 +02:00
|
|
|
control.
|
2018-11-16 21:16:00 +01:00
|
|
|
However, for \f[C]CC\f[R] messages there\[cq]s also an alternative mode
|
|
|
|
for so\-called \f[I]relative\f[R] controllers which can found on some
|
2018-09-18 22:31:22 +02:00
|
|
|
devices.
|
2018-08-28 00:02:49 +02:00
|
|
|
These usually take the form of jog wheels or rotary encoders which can
|
2018-09-18 22:31:22 +02:00
|
|
|
be turned endlessly in either direction, therefore we also just call
|
2018-11-16 21:16:00 +01:00
|
|
|
them \f[I]encoders\f[R] for short in the following.
|
2018-09-18 22:31:22 +02:00
|
|
|
There are various kinds of these which differ in the way they represent
|
|
|
|
relative changes, but these days most encoders found on MIDI controllers
|
2018-11-16 21:16:00 +01:00
|
|
|
employ the \f[I]sign bit\f[R] format; this is also the only kind
|
2018-09-18 22:31:22 +02:00
|
|
|
supported by midizap in the present implementation.
|
|
|
|
In the sign\-bit representation, a value <64 denotes an increment
|
|
|
|
(representing clockwise rotation), and a value >64 a decrement
|
|
|
|
(counter\-clockwise rotation); the actual amount of change is in the
|
|
|
|
lower 6 bits of the value.
|
|
|
|
In the message syntax, sign\-bit values are indicated by using the
|
2018-11-16 21:16:00 +01:00
|
|
|
suffixes \f[C]<\f[R], \f[C]>\f[R] and \f[C]\[ti]\f[R] in lieu of
|
|
|
|
\f[C]\-\f[R], \f[C]+\f[R] and \f[C]=\f[R], respectively.
|
|
|
|
These flags are only permitted with \f[C]CC\f[R] messages.
|
2018-09-13 19:37:43 +02:00
|
|
|
.SS Keyboard and Mouse Events
|
2018-08-17 01:44:26 +02:00
|
|
|
.PP
|
2018-08-28 18:07:31 +02:00
|
|
|
Keyboard and mouse output consists of X key codes with optional up/down
|
|
|
|
indicators, or strings of printable characters enclosed in double
|
|
|
|
quotes.
|
2018-11-16 21:16:00 +01:00
|
|
|
The syntax of these items, as well as the special \f[C]RELEASE\f[R] and
|
|
|
|
\f[C]SHIFT\f[R] tokens which will be discussed later, are described by
|
2018-08-19 12:19:48 +02:00
|
|
|
the following grammar:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
token ::= \[dq]RELEASE\[dq] | \[dq]SHIFT\[dq] [ number ] |
|
|
|
|
keycode [ \[dq]/\[dq] keyflag ] | string
|
|
|
|
keycode ::= \[dq]XK_Button_1\[dq] | \[dq]XK_Button_2\[dq] | \[dq]XK_Button_3\[dq] |
|
|
|
|
\[dq]XK_Scroll_Up\[dq] | \[dq]XK_Scroll_Down\[dq] |
|
|
|
|
\[dq]XK_...\[dq] (X keysyms, see /usr/include/X11/keysymdef.h)
|
|
|
|
keyflag ::= \[dq]U\[dq] | \[dq]D\[dq] | \[dq]H\[dq]
|
|
|
|
string ::= \[aq]\[dq]\[aq] { character } \[aq]\[dq]\[aq]
|
|
|
|
\f[R]
|
2018-08-19 12:19:48 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Here, case \f[I]is\f[R] significant (except in character strings, see
|
|
|
|
the remarks below), so the special \f[C]RELEASE\f[R] and \f[C]SHIFT\f[R]
|
|
|
|
tokens must be in all caps, and the \f[C]XK\f[R] symbols need to be
|
2018-08-19 21:14:49 +02:00
|
|
|
written in mixed case exactly as they appear in the
|
|
|
|
/usr/include/X11/keysymdef.h file.
|
2018-08-19 12:19:48 +02:00
|
|
|
Besides the key codes from the keysymdef.h file, there are also some
|
2018-08-31 02:15:56 +02:00
|
|
|
special additional key codes to denote mouse button and scroll wheel
|
2018-11-16 21:16:00 +01:00
|
|
|
events (\f[C]XK_Button_1\f[R], \f[C]XK_Scroll_Up\f[R], etc.).
|
2018-08-17 01:44:26 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Any keycode can be followed by an optional \f[C]/D\f[R], \f[C]/U\f[R],
|
|
|
|
or \f[C]/H\f[R] flag, indicating that the key is just going down
|
|
|
|
(without being released), going up, or going down and being held until
|
|
|
|
the \[lq]off\[rq] event is received.
|
|
|
|
So, in general, modifier key codes will be followed by \f[C]/D\f[R], and
|
2018-08-19 21:14:49 +02:00
|
|
|
precede the keycodes they are intended to modify.
|
|
|
|
If a sequence requires different sets of modifiers for different
|
2018-11-16 21:16:00 +01:00
|
|
|
keycodes, \f[C]/U\f[R] can be used to release a modifier that was
|
|
|
|
previously pressed with \f[C]/D\f[R].
|
2018-08-19 21:14:49 +02:00
|
|
|
Sequences may also have separate press and release sequences, separated
|
2018-11-16 21:16:00 +01:00
|
|
|
by the special word \f[C]RELEASE\f[R].
|
2018-08-17 01:44:26 +02:00
|
|
|
Examples:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
C5 \[dq]qwer\[dq]
|
|
|
|
D5 XK_Right
|
|
|
|
E5 XK_Alt_L/D XK_Right
|
|
|
|
F5 \[dq]V\[dq] XK_Left XK_Page_Up \[dq]v\[dq]
|
|
|
|
G5 XK_Alt_L/D \[dq]v\[dq] XK_Alt_L/U \[dq]x\[dq] RELEASE \[dq]q\[dq]
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-13 19:37:43 +02:00
|
|
|
Translations are handled differently depending on the input mode
|
2018-11-16 21:16:00 +01:00
|
|
|
(cf.\ \f[I]Key and Data Translations\f[R] above).
|
|
|
|
In \f[I]key mode\f[R], there are separate press and release sequences.
|
2018-08-20 21:50:44 +02:00
|
|
|
The former is invoked when the input key goes \[lq]down\[rq] (i.e., when
|
|
|
|
the \[lq]on\[rq] status is received), the latter when the input key goes
|
|
|
|
\[lq]up\[rq] again (\[lq]off\[rq] status).
|
|
|
|
More precisely, at the end of the press sequence, all down keys marked
|
2018-11-16 21:16:00 +01:00
|
|
|
by \f[C]/D\f[R] will be released, and the last key not marked by
|
|
|
|
\f[C]/D\f[R], \f[C]/U\f[R], or \f[C]/H\f[R] will remain pressed.
|
2018-08-17 01:44:26 +02:00
|
|
|
The release sequence will begin by releasing the last held key.
|
|
|
|
If keys are to be pressed as part of the release sequence, then any keys
|
2018-11-16 21:16:00 +01:00
|
|
|
marked with \f[C]/D\f[R] will be repressed before continuing the
|
2018-08-17 01:44:26 +02:00
|
|
|
sequence.
|
2018-11-16 21:16:00 +01:00
|
|
|
Keycodes marked with \f[C]/H\f[R] remain held between the press and
|
2018-08-17 01:44:26 +02:00
|
|
|
release sequences.
|
2018-11-16 21:16:00 +01:00
|
|
|
For instance, let\[cq]s take a look at one of the more conspicuous
|
2018-08-20 21:50:44 +02:00
|
|
|
translations in the example above:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
G5 XK_Alt_L/D \[dq]v\[dq] XK_Alt_L/U \[dq]x\[dq] RELEASE \[dq]q\[dq]
|
|
|
|
\f[R]
|
2018-08-20 21:50:44 +02:00
|
|
|
.fi
|
2018-08-17 01:44:26 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
This translation has the following meaning: When the \f[C]G5\f[R] key is
|
|
|
|
pressed on the MIDI keyboard, the key sequence \f[C]Alt+v x\f[R] is
|
|
|
|
initiated, keeping the \f[C]x\f[R] key pressed (so it may start
|
2018-08-31 02:15:56 +02:00
|
|
|
auto\-repeating after a while).
|
2018-08-20 21:50:44 +02:00
|
|
|
The program then sits there waiting (possibly executing other
|
2018-11-16 21:16:00 +01:00
|
|
|
translations) until you release the \f[C]G5\f[R] key again, at which
|
|
|
|
point the \f[C]x\f[R] key is released and the \f[C]q\f[R] key is pressed
|
2018-08-20 21:50:44 +02:00
|
|
|
(and released).
|
2018-08-19 21:14:49 +02:00
|
|
|
.PP
|
2018-08-31 02:15:56 +02:00
|
|
|
One pitfall here is that character strings in double quotes are just a
|
|
|
|
shorthand for the corresponding X key codes, ignoring case.
|
2018-11-16 21:16:00 +01:00
|
|
|
Thus, e.g., \f[C]\[dq]abc\[dq]\f[R] actually denotes the keysym sequence
|
|
|
|
\f[C]XK_a XK_b XK_c\f[R], as does \f[C]\[dq]ABC\[dq]\f[R].
|
|
|
|
So in either case the \f[I]lowercase\f[R] string \f[C]abc\f[R] will be
|
2018-08-31 02:15:56 +02:00
|
|
|
output.
|
|
|
|
To output uppercase letters, it is always necessary to add one of the
|
|
|
|
shift modifiers to the output sequence.
|
2018-11-16 21:16:00 +01:00
|
|
|
E.g., \f[C]XK_Shift_L/D \[dq]abc\[dq]\f[R] will output \f[C]ABC\f[R] in
|
2018-08-31 02:15:56 +02:00
|
|
|
uppercase.
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
In \f[I]data mode\f[R] only a single sequence is output whenever the
|
2018-09-02 11:47:08 +02:00
|
|
|
message value changes.
|
2018-11-16 21:16:00 +01:00
|
|
|
So there\[cq]s no separate \[lq]release\[rq] sequence, and at the end of
|
|
|
|
the sequence, \f[I]all\f[R] down keys will be released.
|
|
|
|
Instead, data mode distinguishes between \f[I]increments\f[R] and
|
|
|
|
\f[I]decrements\f[R] of the input value and outputs the corresponding
|
2018-09-02 11:47:08 +02:00
|
|
|
sequence for each unit change.
|
2018-08-19 21:14:49 +02:00
|
|
|
For instance, the following translations move the cursor left or right
|
2018-11-16 21:16:00 +01:00
|
|
|
whenever the volume controller (\f[C]CC7\f[R]) decreases and increases,
|
2018-08-19 21:14:49 +02:00
|
|
|
respectively.
|
2018-08-17 01:44:26 +02:00
|
|
|
Also, the number of times one of these keys is output corresponds to the
|
2018-08-19 12:19:48 +02:00
|
|
|
actual change in the value.
|
2018-11-16 21:16:00 +01:00
|
|
|
Thus, if in the example \f[C]CC7\f[R] increases by 4, say, the program
|
|
|
|
will press (and release) \f[C]XK_Right\f[R] four times in close
|
2018-09-02 11:47:08 +02:00
|
|
|
succession, moving the cursor in the focused window four positions to
|
|
|
|
the right.
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC7\- XK_Left
|
|
|
|
CC7+ XK_Right
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-18 22:31:22 +02:00
|
|
|
Sign\-bit encoders are treated in an analogous fashion, but in this case
|
|
|
|
the increment or decrement is determined directly by the input message.
|
2018-08-31 02:15:56 +02:00
|
|
|
One example for this type of controller is the big jog wheel
|
2018-11-16 21:16:00 +01:00
|
|
|
(\f[C]CC60\f[R]) on some Mackie devices, which can be processed as
|
|
|
|
follows (using \f[C]<\f[R] and \f[C]>\f[R] in lieu of \f[C]\-\f[R] and
|
|
|
|
\f[C]+\f[R] as the increment flag of the \f[C]CC\f[R] message):
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC60< XK_Left
|
|
|
|
CC60> XK_Right
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-31 02:15:56 +02:00
|
|
|
The corresponding \[lq]bidirectional\[rq] translations, which are
|
2018-11-16 21:16:00 +01:00
|
|
|
indicated with the \f[C]=\f[R] and \f[C]\[ti]\f[R] flags, are mostly
|
|
|
|
used with MIDI output; the same goes for the special \f[C]SHIFT\f[R]
|
|
|
|
token.
|
|
|
|
Thus we\[cq]ll discuss these in later sections, see \f[I]MIDI
|
|
|
|
Events\f[R] and \f[I]Shift State\f[R] below.
|
2018-08-19 12:19:48 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
In data mode, input messages can also have a \f[I]step size\f[R]
|
2018-08-27 16:01:19 +02:00
|
|
|
associated with them, which has the effect of downscaling changes in the
|
2018-08-20 01:13:53 +02:00
|
|
|
parameter value.
|
2018-08-17 01:44:26 +02:00
|
|
|
The default step size is 1 (no scaling).
|
|
|
|
To change it, the desired step size is written in brackets immediately
|
2018-08-31 02:15:56 +02:00
|
|
|
after the message token and before the increment flag.
|
2018-11-16 21:16:00 +01:00
|
|
|
A step size \f[I]k\f[R] indicates that the translation is executed
|
|
|
|
whenever the input value has changed by \f[I]k\f[R] units.
|
2018-08-20 01:13:53 +02:00
|
|
|
For instance, to slow down the cursor movement in the example above by a
|
|
|
|
factor of 4:
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC7[4]\- XK_Left
|
|
|
|
CC7[4]+ XK_Right
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
2018-08-23 12:17:05 +02:00
|
|
|
.PP
|
2018-09-18 22:31:22 +02:00
|
|
|
The same goes for sign\-bit encoders:
|
2018-08-27 16:01:19 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC60[4]< XK_Left
|
|
|
|
CC60[4]> XK_Right
|
|
|
|
\f[R]
|
2018-08-27 16:01:19 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that since there\[cq]s no persistent absolute controller state in
|
|
|
|
this case, this simply scales down the actual increment value in the
|
|
|
|
message itself.
|
2018-09-13 19:37:43 +02:00
|
|
|
.SS MIDI Events
|
2018-08-17 01:44:26 +02:00
|
|
|
.PP
|
2018-08-19 21:14:49 +02:00
|
|
|
Most of the notation for MIDI messages on the left\-hand side of a
|
2018-09-16 20:53:46 +02:00
|
|
|
translation rule also carries over to the output side.
|
2018-11-16 21:16:00 +01:00
|
|
|
The only real difference is that the increment flags \f[C]+\-=<>\f[R]
|
|
|
|
aren\[cq]t permitted here, as they are only used to determine the input
|
|
|
|
mode (key or data) of the entire translation.
|
|
|
|
The \f[C]\[ti]\f[R] flag \f[I]is\f[R] allowed, however, to indicate
|
|
|
|
output in sign\-bit encoder format in data translations, see below.
|
|
|
|
Step sizes are permitted as well on the output side, in \f[I]both\f[R]
|
2018-08-27 16:01:19 +02:00
|
|
|
key and data translations.
|
|
|
|
Their meaning depends on the kind of translation, however.
|
|
|
|
In key translations, they denote the (nonzero) value to be used for the
|
|
|
|
\[lq]on\[rq] state in the press sequence; in data translations, they
|
|
|
|
indicate the amount of change for each unit input change (which has the
|
2018-11-16 21:16:00 +01:00
|
|
|
effect of \f[I]upscaling\f[R] the value change).
|
2018-08-17 01:44:26 +02:00
|
|
|
.PP
|
|
|
|
The output sequence can involve as many MIDI messages as you want, and
|
2018-08-19 12:19:48 +02:00
|
|
|
these can be combined freely with keyboard and mouse events in any
|
|
|
|
order.
|
2018-11-16 21:16:00 +01:00
|
|
|
However, as already discussed in Section \f[I]MIDI Output\f[R] above,
|
|
|
|
you also need to invoke the midizap program with the \f[C]\-o\f[R]
|
|
|
|
option to make MIDI output work.
|
2018-08-25 22:55:02 +02:00
|
|
|
Otherwise, MIDI messages in the output translations will just be
|
|
|
|
silently ignored.
|
2018-08-19 12:19:48 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
There is one special MIDI token \f[C]CH\f[R] which can only be used on
|
2018-08-20 01:13:53 +02:00
|
|
|
the output side.
|
2018-08-28 00:02:49 +02:00
|
|
|
It is always followed by a MIDI channel number in the range 1..16.
|
2018-11-16 21:16:00 +01:00
|
|
|
This token doesn\[cq]t actually generate any MIDI message, but merely
|
|
|
|
sets the default MIDI channel for subsequent MIDI messages in the same
|
|
|
|
output sequence, which is convenient if multiple messages are output to
|
|
|
|
the same MIDI channel.
|
|
|
|
For instance, the sequence \f[C]C5\-2 E5\-2 G5\-2\f[R], which outputs a
|
2018-08-20 01:13:53 +02:00
|
|
|
C major chord on MIDI channel 2, can also be abbreviated as
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]CH2 C5 E5 G5\f[R].
|
2018-08-20 01:13:53 +02:00
|
|
|
.PP
|
2018-09-23 13:34:48 +02:00
|
|
|
Key mode is a lot simpler for MIDI output than with key events; there is
|
2018-11-16 21:16:00 +01:00
|
|
|
no magic involving \[lq]held\[rq] keys here, and no \f[C]/D\f[R],
|
|
|
|
\f[C]/U\f[R] or \f[C]/H\f[R] flags (these are only valid with keyboard
|
2018-09-23 13:34:48 +02:00
|
|
|
output).
|
|
|
|
By default, the press and release sequences will have exactly the same
|
|
|
|
\[lq]on\[rq] and \[lq]off\[rq] MIDI messages, in the same order as they
|
|
|
|
appear in the given output sequence.
|
2018-11-16 21:16:00 +01:00
|
|
|
If there\[cq]s an explicit \f[C]RELEASE\f[R] section, however, then the
|
2018-09-23 13:34:48 +02:00
|
|
|
\[lq]off\[rq] messages in this sequence will be output for the release
|
|
|
|
sequence instead.
|
|
|
|
This allows you to output the \[lq]off\[rq] messages in a different
|
|
|
|
order, or output a completely different release sequence if you want.
|
2018-11-16 21:16:00 +01:00
|
|
|
(This case arises rarely, though; usually you\[cq]ll just specify the
|
|
|
|
press sequence and be done with it.) In either case, the messages will
|
|
|
|
be output exactly as written.
|
2018-09-23 13:34:48 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
For instance, the following rule outputs a \f[C]CC64\f[R] (hold pedal)
|
|
|
|
message with controller value 127 each time \f[C]C3\f[R] is pressed, and
|
|
|
|
another \f[C]CC64\f[R] message with value 0 when the note is released
|
2018-09-23 13:34:48 +02:00
|
|
|
again:
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
C3 CC64 # hold pedal on/off
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-19 12:19:48 +02:00
|
|
|
The value for the \[lq]on\[rq] state can also be denoted explicitly with
|
2018-08-20 21:50:44 +02:00
|
|
|
a step size:
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
C3 CC64[64] # hold pedal with an \[dq]on\[dq] value of 64
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-20 01:13:53 +02:00
|
|
|
For pitch bends, the step size can also be negative.
|
|
|
|
For instance, the following rules assign two keys to bend down and up by
|
2018-08-20 21:50:44 +02:00
|
|
|
the maximum amount possible:
|
2018-08-20 01:13:53 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
C2 PB[\-8192] # bend down
|
|
|
|
D2 PB[8191] # bend up
|
|
|
|
\f[R]
|
2018-08-20 01:13:53 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-31 02:15:56 +02:00
|
|
|
Rules similar to the ones above may be useful if your MIDI keyboard
|
2018-11-16 21:16:00 +01:00
|
|
|
doesn\[cq]t have a hold pedal or pitch bend wheel, as they let you set
|
|
|
|
aside some keys to emulate those functions.
|
2018-08-31 02:15:56 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Let\[cq]s now have a look at data mode.
|
|
|
|
There are two additional flags \f[C]=\f[R] and \f[C]\[ti]\f[R] for data
|
2018-09-13 19:37:43 +02:00
|
|
|
translations which are most useful with MIDI output, which is why we
|
|
|
|
deferred their discussion until now.
|
2018-08-31 02:15:56 +02:00
|
|
|
In pure MIDI translations not involving any key or mouse output, the
|
|
|
|
increment and decrement sequences are usually identical, in which case
|
2018-11-16 21:16:00 +01:00
|
|
|
the \f[C]=\f[R] suffix can be used to indicate that the output is to be
|
|
|
|
used for \f[I]both\f[R] increments and decrements.
|
|
|
|
For instance, to map the modulation wheel (\f[C]CC1\f[R]) to the volume
|
|
|
|
controller (\f[C]CC7\f[R]):
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1= CC7
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-31 02:15:56 +02:00
|
|
|
Which is more convenient to write, but is really just a shorthand for
|
|
|
|
the two separate translations:
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1+ CC7
|
|
|
|
CC1\- CC7
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
The same goes for \f[C]<\f[R], \f[C]>\f[R] and \f[C]\[ti]\f[R] with
|
|
|
|
sign\-bit encoders:
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC60\[ti] CC7
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-19 21:14:49 +02:00
|
|
|
Which is equivalent to:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC60< CC7
|
|
|
|
CC60> CC7
|
|
|
|
\f[R]
|
2018-08-19 21:14:49 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
The \f[C]\[ti]\f[R] flag can be used to denote encoders in output
|
|
|
|
messages, too.
|
2018-09-18 22:31:22 +02:00
|
|
|
E.g., to translate a standard (absolute) MIDI controller to a sign\-bit
|
|
|
|
encoder value, you might use a rule like:
|
2018-08-18 00:09:48 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC48= CC16\[ti]
|
|
|
|
\f[R]
|
2018-08-18 00:09:48 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Of course, this won\[cq]t magically turn a standard controller into a
|
|
|
|
\f[I]real\f[R] encoder; its range will still be limited.
|
2018-09-18 22:31:22 +02:00
|
|
|
One way to properly emulate the endless range of an encoder is to expend
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]two\f[R] absolute controllers, one for reducing and another one for
|
2018-09-18 22:31:22 +02:00
|
|
|
increasing the value.
|
2018-09-18 07:27:12 +02:00
|
|
|
For instance:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1\- CC60\[ti]
|
|
|
|
CC2+ CC60\[ti]
|
|
|
|
\f[R]
|
2018-09-18 07:27:12 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that the \[lq]down\[rq] controller (\f[C]CC1\f[R] in this example)
|
|
|
|
only reacts to negative, and the \[lq]up\[rq] controlller
|
|
|
|
(\f[C]CC2\f[R]) only to positive changes.
|
|
|
|
Therefore it\[cq]s possible to \[lq]rewind\[rq] each control when
|
|
|
|
getting to the end of its range, so that you can continue to change its
|
|
|
|
value as much as you want.
|
2018-09-18 22:31:22 +02:00
|
|
|
Admittedly, this solution is a bit quirky, but hey \[en] if you
|
2018-11-16 21:16:00 +01:00
|
|
|
absolutely need to emulate a real encoder on a device which doesn\[cq]t
|
|
|
|
have one, that\[cq]s one way to do it.
|
2018-09-18 07:27:12 +02:00
|
|
|
.PP
|
2018-08-31 02:15:56 +02:00
|
|
|
Step sizes work on the right\-hand side of data translations as well.
|
2018-08-20 01:13:53 +02:00
|
|
|
You might use these to scale up value changes, e.g., when translating
|
|
|
|
from control changes to pitch bends:
|
2018-08-17 01:44:26 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1= PB[128]
|
|
|
|
\f[R]
|
2018-08-17 01:44:26 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-20 21:50:44 +02:00
|
|
|
The step size can also be negative, which allows you to reverse the
|
2018-08-20 01:13:53 +02:00
|
|
|
direction of a controller if needed.
|
|
|
|
E.g., the following will output values going down from 127 to 0 as input
|
2018-08-20 21:50:44 +02:00
|
|
|
values go up from 0 to 127:
|
2018-08-20 01:13:53 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1= CC1[\-1]
|
|
|
|
\f[R]
|
2018-08-20 01:13:53 +02:00
|
|
|
.fi
|
2018-08-27 16:01:19 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that you can also place step sizes on \f[I]both\f[R] the left\-hand
|
2018-09-02 11:47:08 +02:00
|
|
|
and right\-hand side of a rule, in order to approximate a rational
|
|
|
|
scaling factor:
|
2018-08-27 16:01:19 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[3]= CC1[2]
|
|
|
|
\f[R]
|
2018-08-27 16:01:19 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
The above translation will only be triggered when the input value
|
|
|
|
changes by 3 units, and the change in the output value will then be
|
2018-09-02 11:47:08 +02:00
|
|
|
doubled again, so that the net effect is to scale the input value by
|
|
|
|
2/3.
|
|
|
|
(Note that for most ratios this will only give a rough approximation;
|
|
|
|
the method works best if the input and output step sizes are reasonably
|
|
|
|
small.)
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[B]NOTE:\f[R] All data translations we\[cq]ve seen so far handle
|
|
|
|
\f[I]incremental\f[R] value changes.
|
2018-09-02 11:47:08 +02:00
|
|
|
In order to be able to detect these changes and, in the case of MIDI
|
2018-09-02 13:06:55 +02:00
|
|
|
output, change the output values accordingly, midizap has to keep track
|
|
|
|
of all the current parameter values of all messages on all MIDI
|
|
|
|
channels, for both input and output.
|
2018-09-12 10:52:47 +02:00
|
|
|
This is easy enough, but midizap usually has no way of knowing the
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]actual\f[R] state of your controllers and MIDI applications, so
|
|
|
|
when the program starts up, it simply assumes all these values to be
|
|
|
|
zero.
|
|
|
|
This means that midizap\[cq]s \[lq]shadow\[rq] values of controllers,
|
|
|
|
pitch bends etc.\ may initially well be out of sync with your input
|
|
|
|
devices and applications, and you may have to wiggle a control in order
|
|
|
|
to \[lq]calibrate\[rq] it.
|
2018-09-18 07:27:12 +02:00
|
|
|
.PP
|
|
|
|
This becomes most apparent when using negative step sizes, as in the
|
2018-11-16 21:16:00 +01:00
|
|
|
translation \f[C]CC1= CC1[\-1]\f[R] from above.
|
2018-09-14 09:58:57 +02:00
|
|
|
In this case, you will first have to move the control all the way up and
|
2018-09-18 07:27:12 +02:00
|
|
|
then down again to get it working properly.
|
2018-09-18 22:31:22 +02:00
|
|
|
There are some ways to mitigate these issues, however.
|
2018-09-14 09:58:57 +02:00
|
|
|
In particular, midizap can utilize controller feedback from the
|
2018-11-16 21:16:00 +01:00
|
|
|
application, please check the \f[I]MIDI Feedback\f[R] section below for
|
2018-09-14 09:58:57 +02:00
|
|
|
details.
|
|
|
|
Also, encoders need no calibration as they represent incremental changes
|
2018-11-16 21:16:00 +01:00
|
|
|
anyway, and there\[cq]s an alternative form of data translation, to be
|
|
|
|
discussed in Section \f[I]Mod Translations\f[R], which always works with
|
2018-09-14 09:58:57 +02:00
|
|
|
absolute values and thus needs no calibration either.
|
2018-08-17 01:44:26 +02:00
|
|
|
.SS Shift State
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Like the \f[C]CH\f[R] token, the special \f[C]SHIFT\f[R] token
|
|
|
|
doesn\[cq]t generate any output by itself; it merely toggles an internal
|
|
|
|
shift state which can then be tested by other translations to generate
|
|
|
|
alternative output sequences.
|
|
|
|
The \f[C]\[ha]\f[R] prefix denotes a rule which is active only in
|
|
|
|
shifted state, while unprefixed rules are active in \f[I]both\f[R]
|
|
|
|
shifted and unshifted state.
|
|
|
|
Also, a prefixed rule \f[I]always\f[R] overrides an unprefixed one (no
|
2018-09-14 09:19:37 +02:00
|
|
|
matter in which order they appear in the configuration file), so if you
|
|
|
|
specify both, the former will be used in shifted, the latter in
|
|
|
|
unshifted state.
|
|
|
|
That is, unprefixed rules act as defaults which can be overridden by
|
|
|
|
prefixed ones.
|
|
|
|
.PP
|
2018-08-16 18:34:02 +02:00
|
|
|
Many DAW controllers have some designated shift keys which can be used
|
|
|
|
for this purpose, but the following will actually work with any
|
|
|
|
key\-style MIDI message.
|
2018-11-16 21:16:00 +01:00
|
|
|
E.g., to bind the shift key on an AKAI APCmini controller
|
|
|
|
(\f[C]D8\f[R]):
|
2018-08-16 18:34:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
D8 SHIFT
|
|
|
|
\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
This rule doesn\[cq]t have a prefix, so it is used to turn shift state
|
|
|
|
both on and off, giving a \[lq]Caps Lock\[rq]\-style of toggle key.
|
|
|
|
If you\[cq]d rather have an ordinary shift key which turns on shift
|
|
|
|
state when pressed and immediately turns it off when released again, you
|
|
|
|
can do that as follows:
|
2018-08-16 18:34:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
D8 SHIFT RELEASE SHIFT
|
|
|
|
\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that in either case \f[C]SHIFT\f[R] works as a \f[I]toggle\f[R];
|
|
|
|
when executed, it turns the shift status from off to on, and vice versa
|
|
|
|
from on to off.
|
2018-09-14 09:19:37 +02:00
|
|
|
.PP
|
2018-08-16 18:34:02 +02:00
|
|
|
Having set up the translation for the shift key itself, we can now
|
2018-09-14 09:19:37 +02:00
|
|
|
assign, depending on the shift state, different functions to buttons and
|
|
|
|
faders.
|
2018-11-16 21:16:00 +01:00
|
|
|
Here\[cq]s a typical example which maps a control change to either
|
2018-09-18 22:31:22 +02:00
|
|
|
Mackie\-style fader values encoded as pitch bends, or sign\-bit encoder
|
|
|
|
values:
|
2018-08-16 18:34:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC48= PB[128] # default: translate to pitch bend
|
|
|
|
\[ha]CC48= CC16\[ti] # shifted: translate to encoder
|
|
|
|
\f[R]
|
2018-08-16 18:34:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
It\[cq]s also possible to explicitly denote a rule which is active
|
|
|
|
\f[I]only\f[R] in unshifted state.
|
|
|
|
Unshifted state is specified with the \f[C]0\[ha]\f[R] (zero\-caret)
|
|
|
|
prefix, so you can write:
|
2018-09-14 09:19:37 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
0\[ha]CC56= PB[128]\-9 # unshifted: translate to pitch bend
|
|
|
|
\f[R]
|
2018-09-14 09:19:37 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
The syntax is a bit awkward, but the case arises rarely (usually,
|
|
|
|
you\[cq]ll just write an unprefixed rule instead).
|
2018-09-14 09:19:37 +02:00
|
|
|
.PP
|
2018-09-13 19:37:43 +02:00
|
|
|
midizap actually supports up to four different shift states, which are
|
2018-11-16 21:16:00 +01:00
|
|
|
denoted \f[C]SHIFT1\f[R] to \f[C]SHIFT4\f[R], with the corresponding
|
|
|
|
prefixes being \f[C]1\[ha]\f[R] to \f[C]4\[ha]\f[R].
|
2018-09-14 09:19:37 +02:00
|
|
|
Unprefixed rules are enabled by default in all of these.
|
2018-11-16 21:16:00 +01:00
|
|
|
The \f[C]SHIFT\f[R] token and \f[C]\[ha]\f[R] prefix we\[cq]ve seen
|
|
|
|
above are in fact just shortcuts for \f[C]SHIFT1\f[R] and
|
|
|
|
\f[C]1\[ha]\f[R], respectively.
|
2018-09-14 09:19:37 +02:00
|
|
|
So our first example above is equivalent to:
|
2018-09-12 20:57:45 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
D8 SHIFT1 RELEASE SHIFT1
|
|
|
|
CC48= PB[128]
|
|
|
|
1\[ha]CC48= CC16\[ti]
|
|
|
|
\f[R]
|
2018-09-12 20:57:45 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-14 09:19:37 +02:00
|
|
|
We might add another shift key and use it to assign yet another function
|
|
|
|
to the same input message:
|
2018-09-13 19:37:43 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
F7 SHIFT2 RELEASE SHIFT2
|
|
|
|
2\[ha]CC48\- XK_Left
|
|
|
|
2\[ha]CC48+ XK_Right
|
|
|
|
\f[R]
|
2018-09-13 19:37:43 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-14 09:58:57 +02:00
|
|
|
Another way to look at this is that translations are organized in
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]layers\f[R].
|
2018-09-14 09:58:57 +02:00
|
|
|
Layer 0 contains the unshifted translations, layer 1 to 4 the
|
|
|
|
translations prefixed with the corresponding shift level.
|
|
|
|
Unprefixed translations are available in all of these layers, unless
|
|
|
|
they are overriden by translations specifically assigned to one of the
|
|
|
|
layers.
|
|
|
|
To keep things simple, only one layer can be active at any one time; if
|
2018-09-16 20:53:46 +02:00
|
|
|
you press a shift key while another layer is still active, it will be
|
|
|
|
deactivated automatically before activating the new layer.
|
2018-09-14 09:58:57 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Also note that the status of internal shift keys is \f[I]only\f[R]
|
2018-09-14 09:58:57 +02:00
|
|
|
available to the midizap program; the host application never gets to see
|
|
|
|
them.
|
2018-11-16 21:16:00 +01:00
|
|
|
If your host software does its own handling of shift keys, it\[cq]s
|
|
|
|
usually more convenient to simply pass those keys on to the application.
|
|
|
|
However, \f[C]SHIFT\f[R] comes in handy if your controller doesn\[cq]t
|
|
|
|
have enough buttons and faders, since it makes it possible to multiply
|
|
|
|
the amount of controls available on the device.
|
2018-08-16 18:34:02 +02:00
|
|
|
For instance, you can emulate a Mackie controller with both encoders and
|
2018-09-14 09:58:57 +02:00
|
|
|
faders on a device which only has a single set of faders, simply by
|
|
|
|
assigning the shifted faders to the encoders, as shown in the first
|
|
|
|
example above.
|
2018-09-13 19:37:43 +02:00
|
|
|
.SH MIDI Feedback
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Some MIDI controllers need a more elaborate setup than what we\[cq]ve
|
|
|
|
seen so far, because they have motor faders, LEDs, etc., requiring
|
|
|
|
feedback from the application.
|
|
|
|
To accommodate these, you can use the \f[C]\-o2\f[R] option of midizap,
|
|
|
|
or the \f[C]JACK_PORTS 2\f[R] directive in the midizaprc file, to create
|
|
|
|
a second pair of MIDI input and output ports, named \f[C]midi_in2\f[R]
|
|
|
|
and \f[C]midi_out2\f[R].
|
2018-08-16 18:34:02 +02:00
|
|
|
Use of this option also activates a second MIDI default section in the
|
2018-11-16 21:16:00 +01:00
|
|
|
midizaprc file, labeled \f[C][MIDI2]\f[R], which is used exclusively for
|
2018-08-23 12:17:05 +02:00
|
|
|
translating MIDI input from the second input port and sending the
|
|
|
|
resulting MIDI output to the second output port.
|
2018-11-16 21:16:00 +01:00
|
|
|
Typically, the translations in the \f[C][MIDI2]\f[R] section will be the
|
|
|
|
inverse of those in the \f[C][MIDI]\f[R] section, or whatever it takes
|
|
|
|
to translate the MIDI feedback from the application back to MIDI data
|
|
|
|
which the controller understands.
|
|
|
|
.PP
|
|
|
|
You then wire up midizap\[cq]s \f[C]midi_in\f[R] and \f[C]midi_out\f[R]
|
|
|
|
ports to controller and application as before, but in addition you also
|
|
|
|
connect the application back to midizap\[cq]s \f[C]midi_in2\f[R] port,
|
|
|
|
and the \f[C]midi_out2\f[R] port to the controller.
|
2018-08-16 18:34:02 +02:00
|
|
|
This reverse path is what is needed to translate the feedback from the
|
|
|
|
application and send it back to the controller.
|
2018-11-16 21:16:00 +01:00
|
|
|
(The \f[C]\-s\f[R] option a.k.a.\ \f[C]SYSTEM_PASSTHROUGH\f[R] directive
|
2018-09-12 10:52:47 +02:00
|
|
|
also works on the feedback port, passing through all system messages
|
|
|
|
from the second input port to the second output port unchanged.)
|
|
|
|
.PP
|
2018-09-13 19:37:43 +02:00
|
|
|
The distribution includes a full\-blown example of this kind of setup
|
|
|
|
for your perusal, please check examples/APCmini.midizaprc in the
|
|
|
|
sources.
|
2018-11-16 21:16:00 +01:00
|
|
|
It shows how to emulate a Mackie controller with AKAI\[cq]s APCmini
|
|
|
|
device, so that it readily works with DAW software such as Ardour.
|
2018-09-13 19:37:43 +02:00
|
|
|
.SS Automatic Feedback
|
|
|
|
.PP
|
2018-09-16 20:53:46 +02:00
|
|
|
If done right, MIDI feedback will eliminate the problem of controls
|
|
|
|
being out of sync with the application.
|
2018-09-13 19:37:43 +02:00
|
|
|
midizap has some built\-in logic to help with this.
|
2018-09-16 20:53:46 +02:00
|
|
|
Specifically, the current state of controls received from the host
|
2018-11-16 21:16:00 +01:00
|
|
|
application via the \f[C]midi_in2\f[R] port will be recorded, so that
|
2018-09-16 20:53:46 +02:00
|
|
|
subsequent MIDI output for incremental data translations on the first
|
|
|
|
output port will use the proper values for determining the required
|
|
|
|
relative changes.
|
2018-09-13 19:37:43 +02:00
|
|
|
(The same goes for the reverse path, recording the values from
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]midi_in\f[R] so that data translations feeding back to the
|
2018-09-13 19:37:43 +02:00
|
|
|
controller will work correctly.)
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
We refer to this as \f[I]automatic feedback\f[R].
|
|
|
|
Some devices may provide you with sign\-bit encoders which don\[cq]t
|
|
|
|
need any kind of feedback for themselves.
|
|
|
|
In this case the automatic feedback will be all that\[cq]s needed to
|
|
|
|
keep controller and application in sync, and you don\[cq]t even have to
|
|
|
|
write any translation rules for the feedback; just enabling the second
|
|
|
|
input port and hooking it up to the application will be enough.
|
2018-09-13 19:37:43 +02:00
|
|
|
Other controllers may provide faders with motors or LEDs on them,
|
2018-09-12 10:52:47 +02:00
|
|
|
however, in which case additional translation rules for the feedback
|
|
|
|
will be needed.
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[B]NOTE:\f[R] Automatic feedback is enabled automatically whenever you
|
|
|
|
create a second pair of ports using \f[C]\-o2\f[R].
|
|
|
|
If you\[cq]re using the second pair for more esoteric purposes, you may
|
|
|
|
want to disable this feature, which can be done with the \f[C]\-n\f[R]
|
|
|
|
option or the \f[C]NO_FEEDBACK\f[R] directive in the configuration file.
|
|
|
|
Use this option \f[I]only\f[R] if feedback isn\[cq]t needed with your
|
2018-09-12 20:57:45 +02:00
|
|
|
application.
|
2018-09-13 19:37:43 +02:00
|
|
|
.SS Direct Feedback
|
|
|
|
.PP
|
2018-09-14 09:58:57 +02:00
|
|
|
Translations can also provide feedback themselves.
|
2018-09-13 19:37:43 +02:00
|
|
|
To these ends, any MIDI message on the right\-hand side of a translation
|
2018-11-16 21:16:00 +01:00
|
|
|
can be prefixed with the \f[C]!\f[R] character.
|
2018-09-13 19:37:43 +02:00
|
|
|
This outputs the message as usual, but flips the output ports, so that
|
2018-09-14 09:58:57 +02:00
|
|
|
the message will go to port 2 in a forward translation destined for port
|
|
|
|
1, and vice versa to port 1 in a feedback translation (in the
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C][MIDI2]\f[R] section) destined for port 2.
|
2018-09-13 19:37:43 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
We call this \f[I]direct feedback\f[R].
|
2018-09-13 19:37:43 +02:00
|
|
|
For instance, suppose that on our MIDI controller we have a fader taking
|
2018-11-16 21:16:00 +01:00
|
|
|
the form of a touchstrip \f[C]CC1\f[R] that has some LEDs for conveying
|
2018-09-13 19:37:43 +02:00
|
|
|
its current value.
|
2018-11-16 21:16:00 +01:00
|
|
|
We might like to translate that message to a \f[C]CC7\f[R] message for
|
2018-09-13 19:37:43 +02:00
|
|
|
the application, while also providing feedback to the controller.
|
|
|
|
The following translation will do this:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1= CC7 !CC1
|
|
|
|
\f[R]
|
2018-09-13 19:37:43 +02:00
|
|
|
.fi
|
2018-08-28 00:02:49 +02:00
|
|
|
.PP
|
2018-09-13 19:37:43 +02:00
|
|
|
Now, whenever you touch that fader, the corresponding value will be sent
|
2018-11-16 21:16:00 +01:00
|
|
|
as \f[C]CC7\f[R] to the application, while the same value is sent back
|
|
|
|
as \f[C]CC1\f[R] to the controller (which presumably will light the
|
2018-09-13 19:37:43 +02:00
|
|
|
appropriate LEDs on the fader).
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Another example are internal shift buttons (cf.\ \f[I]Shift State\f[R]
|
2018-09-13 19:37:43 +02:00
|
|
|
above).
|
2018-11-16 21:16:00 +01:00
|
|
|
The host application never gets to see these, so chances are that
|
|
|
|
we\[cq]ll have to provide suitable feedback ourselves in order to light
|
|
|
|
the buttons.
|
2018-09-13 19:37:43 +02:00
|
|
|
E.g., the following should usually turn on the LED of the button when
|
|
|
|
pressed, and turn it off again when released:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
D8 SHIFT !D8 RELEASE SHIFT !D8
|
|
|
|
\f[R]
|
2018-09-13 19:37:43 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
This will work for simple cases involving only a single shift key whose
|
|
|
|
state always matches the button state.
|
|
|
|
However, for more complicated setups possibly involving multiple shift
|
2018-11-16 21:16:00 +01:00
|
|
|
keys, it\[cq]s better to use the \f[C]\[ha]\f[R] prefix instead:
|
2018-09-13 19:37:43 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
D8 SHIFT \[ha]D8 RELEASE SHIFT \[ha]D8
|
|
|
|
\f[R]
|
2018-09-13 19:37:43 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-14 09:19:37 +02:00
|
|
|
This variation of direct feedback is tailored to shift keys, and it
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]only\f[R] works with key translations.
|
2018-09-13 19:37:43 +02:00
|
|
|
It also operates under the following two assumptions:
|
|
|
|
.IP \[bu] 2
|
2018-11-16 21:16:00 +01:00
|
|
|
Feedback messages come \f[I]after\f[R] the corresponding \f[C]SHIFT\f[R]
|
2018-09-13 19:37:43 +02:00
|
|
|
token in the translation, so that midizap knows which shift state the
|
|
|
|
message belongs to.
|
|
|
|
.IP \[bu] 2
|
|
|
|
The shift keys can be turned off by sending them a zero parameter value.
|
|
|
|
.PP
|
2018-09-18 07:27:12 +02:00
|
|
|
midizap has some built\-in machinery to deal with shift key feedback
|
2018-09-16 20:53:46 +02:00
|
|
|
which handles direct feedback for shift keys in an automatic fashion,
|
|
|
|
provided that these conditions are met.
|
2018-09-13 19:37:43 +02:00
|
|
|
In particular, midizap ensures that the feedback message reflects the
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]shift\f[R] (rather than the button) state, which is needed to make
|
2018-09-14 09:19:37 +02:00
|
|
|
\[lq]Caps Lock\[rq]\-style toggle keys like the following work
|
|
|
|
correctly:
|
2018-09-13 19:37:43 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
D8 SHIFT \[ha]D8
|
|
|
|
\f[R]
|
2018-09-13 19:37:43 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-14 09:19:37 +02:00
|
|
|
This turns the key on when pushed, and toggles it off again when pushed
|
|
|
|
a second time.
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that you can\[cq]t get this behavior with the basic direct feedback
|
|
|
|
facility, since there\[cq]s no way to keep track of the required status
|
2018-09-13 19:37:43 +02:00
|
|
|
information across different translations.
|
|
|
|
Moreover, midizap also maintains the current status of all shift keys
|
|
|
|
and automatically turns them off when switching from one shift status to
|
2018-09-16 20:53:46 +02:00
|
|
|
another, so that the keys will be lit properly even if you use multiple
|
2018-09-13 19:37:43 +02:00
|
|
|
shift keys in your configuration.
|
|
|
|
.PP
|
2018-09-20 01:24:52 +02:00
|
|
|
midizap still has a few more tricks up its sleeves, but they require the
|
|
|
|
use of a special kind of data translation.
|
2018-11-16 21:16:00 +01:00
|
|
|
These are a separate topic in their own right, so we\[cq]ll introduce
|
|
|
|
them in the next section.
|
2018-09-13 19:37:43 +02:00
|
|
|
.SH Mod Translations
|
2018-08-25 22:55:02 +02:00
|
|
|
.PP
|
|
|
|
Most of the time, MIDI feedback uses just the standard kinds of MIDI
|
|
|
|
messages readily supported by midizap, such as note messages which make
|
|
|
|
buttons light up in different colors, or control change messages which
|
|
|
|
set the positions of motor faders.
|
2018-08-31 02:15:56 +02:00
|
|
|
However, there are some encodings of feedback messages which combine
|
|
|
|
different bits of information in a single message, making them difficult
|
2018-11-16 21:16:00 +01:00
|
|
|
or even impossible to translate using the simple kinds of rules
|
|
|
|
we\[cq]ve seen so far.
|
2018-08-30 14:46:44 +02:00
|
|
|
midizap offers a special variation of data mode to help decoding such
|
|
|
|
messages.
|
2018-11-16 21:16:00 +01:00
|
|
|
We call them \f[I]mod translations\f[R] (a.k.a.\ \[lq]modulus\[rq] or
|
2018-09-12 10:52:47 +02:00
|
|
|
\[lq]modifier\[rq] translations), because they involve operations with
|
|
|
|
integer moduli which enable you to both calculate output from input
|
2018-11-16 21:16:00 +01:00
|
|
|
values in a direct fashion, \f[I]and\f[R] modify the output messages
|
2018-09-12 10:52:47 +02:00
|
|
|
themselves along the way.
|
2018-09-01 13:21:18 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
One important task, which we\[cq]ll use as a running example below, is
|
|
|
|
the decoding of meter (RMS level) data in the Mackie protocol.
|
2018-09-12 20:57:45 +02:00
|
|
|
There, each meter value is represented as a channel pressure message
|
|
|
|
whose value consists of a mixer channel index 0..7 in the \[lq]high
|
2018-09-01 13:21:18 +02:00
|
|
|
nibble\[rq] (bits 4..6) and the corresponding meter value in the
|
|
|
|
\[lq]low nibble\[rq] (bits 0..3).
|
2018-09-02 13:06:55 +02:00
|
|
|
We will show how to map these values to notes indicating buttons on the
|
|
|
|
AKAI APCmini (please check examples/APCmini.midizaprc in the sources for
|
|
|
|
details about this device).
|
2018-11-16 21:16:00 +01:00
|
|
|
Mod translations aren\[cq]t limited to this specific use case, however;
|
2018-09-02 13:06:55 +02:00
|
|
|
similar rules will apply to other kinds of \[lq]scrambled\[rq] MIDI
|
|
|
|
data.
|
2018-09-01 13:21:18 +02:00
|
|
|
.PP
|
|
|
|
In its simplest form, the translation looks as follows:
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CP[16] C0
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
In contrast to standard data translations, there\[cq]s no increment flag
|
|
|
|
here, so the translation does \f[I]not\f[R] indicate an incremental
|
2018-08-31 02:15:56 +02:00
|
|
|
change of the input value.
|
2018-11-16 21:16:00 +01:00
|
|
|
Instead, mod translations always work with \f[I]absolute\f[R] values,
|
|
|
|
and the step size on the left\-hand side is treated as a
|
|
|
|
\f[I]modulus\f[R] to decompose the input value into two separate
|
|
|
|
quantities, \f[I]quotient\f[R] and \f[I]remainder\f[R].
|
2018-08-25 22:55:02 +02:00
|
|
|
Only the latter becomes the value of the output message, while the
|
2018-11-16 21:16:00 +01:00
|
|
|
former is used as an \f[I]offset\f[R] to modify the output message.
|
|
|
|
(Note that \f[C]CP\f[R] and \f[C]PB\f[R] messages don\[cq]t have a
|
|
|
|
modifiable offset, so if you use these on the output side of a mod
|
|
|
|
translation, the offset part of the input value will be ignored.
|
|
|
|
\f[C]PC\f[R] messages, on the other hand, lack the parameter value, so
|
|
|
|
in this case the remainder value will be disregarded instead.)
|
|
|
|
.PP
|
|
|
|
In order to describe more precisely how this works, let\[cq]s assume an
|
|
|
|
input value \f[I]v\f[R] and a modulus \f[I]k\f[R].
|
|
|
|
We divide \f[I]v\f[R] by \f[I]k\f[R], yielding the quotient (offset)
|
|
|
|
\f[I]q\f[R] = \f[I]v\f[R] div \f[I]k\f[R] and the remainder (value)
|
|
|
|
\f[I]r\f[R] = \f[I]v\f[R] mod \f[I]k\f[R].
|
|
|
|
E.g., with \f[I]k\f[R] = 16 and \f[I]v\f[R] = 21, you\[cq]ll get
|
|
|
|
\f[I]q\f[R] = 1 and \f[I]r\f[R] = 5 (21 divided by 16 yields 1 with a
|
|
|
|
remainder of 5).
|
|
|
|
The calculated offset \f[I]q\f[R] is then applied to the note itself,
|
|
|
|
and the remainder \f[I]r\f[R] becomes the velocity of that note.
|
|
|
|
So in the example above the output would be the note \f[C]C#0\f[R]
|
|
|
|
(\f[C]C0\f[R] offset by 1) with a velocity of 5.
|
2018-08-28 00:02:49 +02:00
|
|
|
On the APCmini, this message will light up the second button in the
|
|
|
|
bottom row of the 8x8 grid in yellow.
|
|
|
|
.PP
|
2018-09-02 11:47:08 +02:00
|
|
|
This transformation is surprisingly versatile, and there are some
|
2018-09-14 09:58:57 +02:00
|
|
|
extensions of the MIDI syntax which make it even more flexible.
|
|
|
|
These extensions are only available in mod translations.
|
|
|
|
They are described by the following grammar rules (please also refer to
|
2018-11-16 21:16:00 +01:00
|
|
|
Section \f[I]MIDI Message Notation\f[R] for the rest of the grammar
|
|
|
|
rules for the MIDI syntax):
|
2018-09-01 13:21:18 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
token ::= msg [ mod ] [ steps ] [ \[dq]\-\[dq] number] [ flag ]
|
|
|
|
mod ::= \[dq][\[dq] [ number ] \[dq]]\[dq]
|
|
|
|
steps ::= \[dq][\[dq] number \[dq]]\[dq] | \[dq]{\[dq] list \[dq]}\[dq]
|
|
|
|
list ::= number { \[dq],\[dq] number | \[dq]:\[dq] number | \[dq]\-\[dq] number }
|
|
|
|
flag ::= \[dq]\[aq]\[dq] | \[dq]?\[dq] | \[dq]\[aq]?\[dq] | \[dq]?\[aq]\[dq]
|
|
|
|
\f[R]
|
2018-09-01 13:21:18 +02:00
|
|
|
.fi
|
2018-08-29 14:52:29 +02:00
|
|
|
.PP
|
2018-09-15 23:53:25 +02:00
|
|
|
There are a couple of new elements in the syntax: an empty modulus
|
2018-11-16 21:16:00 +01:00
|
|
|
bracket \f[C][]\f[R], the transposition flag \f[C]\[aq]\f[R], the change
|
|
|
|
flag \f[C]?\f[R], and lists of numbers enclosed in curly braces.
|
2018-09-14 09:58:57 +02:00
|
|
|
They have the following meaning:
|
2018-09-01 17:13:50 +02:00
|
|
|
.IP \[bu] 2
|
2018-11-16 21:16:00 +01:00
|
|
|
The \f[I]empty modulus\f[R] bracket, denoted \f[C][]\f[R] on the
|
2018-09-01 17:13:50 +02:00
|
|
|
left\-hand side of a mod translation, indicates a default modulus large
|
2018-11-16 21:16:00 +01:00
|
|
|
enough (16384 for \f[C]PB\f[R], 128 for other messages) so that the
|
|
|
|
offset \f[I]q\f[R] always becomes zero and the translation passes on the
|
2018-09-02 13:06:55 +02:00
|
|
|
entire input value as is.
|
2018-09-01 13:21:18 +02:00
|
|
|
.IP \[bu] 2
|
2018-11-16 21:16:00 +01:00
|
|
|
The \f[I]transposition\f[R] flag, denoted with the \f[C]\[aq]\f[R]
|
2018-09-15 23:53:25 +02:00
|
|
|
(apostrophe) suffix on an output message, reverses the roles of
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]q\f[R] and \f[I]r\f[R], so that the remainder becomes the offset
|
|
|
|
and the quotient the value of the output message.
|
2018-09-15 23:53:25 +02:00
|
|
|
.IP \[bu] 2
|
2018-11-16 21:16:00 +01:00
|
|
|
The \f[I]change\f[R] flag, denoted with the \f[C]?\f[R] suffix on an
|
2018-09-16 06:40:04 +02:00
|
|
|
output message, only outputs the message if there are any changes in
|
|
|
|
offset or value.
|
2018-09-01 13:21:18 +02:00
|
|
|
.IP \[bu] 2
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]Value lists\f[R], denoted as lists of numbers separated by commas
|
2018-09-01 13:21:18 +02:00
|
|
|
and enclosed in curly braces, provide a way to describe \f[I]discrete
|
2018-11-16 21:16:00 +01:00
|
|
|
mappings\f[R] of input to output values.
|
2018-09-14 09:58:57 +02:00
|
|
|
The input value is used as an index into the list to give the
|
|
|
|
corresponding output value, and the last value in the list will be used
|
|
|
|
for any index which runs past the end of the list.
|
2018-09-01 13:21:18 +02:00
|
|
|
There are also some convenient shortcuts which let you construct these
|
2018-11-16 21:16:00 +01:00
|
|
|
lists more easily: repetition \f[I]a\f[R]\f[C]:\f[R]\f[I]b\f[R]
|
|
|
|
(denoting \f[I]b\f[R] consecutive \f[I]a\f[R]\[cq]s) and enumeration
|
|
|
|
\f[I]a\f[R]\f[C]\-\f[R]\f[I]b\f[R] (denoting
|
|
|
|
\f[I]a\f[R]\f[C],\f[R]\f[I]a\f[R]\[t+-]1\f[C],\f[R]\&...\f[C],\f[R]\f[I]b\f[R],
|
2018-09-01 13:21:18 +02:00
|
|
|
which ramps either up or down depending on whether
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]a\f[R]<=\f[I]b\f[R] or \f[I]a\f[R]>\f[I]b\f[R], respectively).
|
2018-09-01 13:21:18 +02:00
|
|
|
.PP
|
2018-09-02 11:47:08 +02:00
|
|
|
These are often used in concert.
|
2018-09-15 23:53:25 +02:00
|
|
|
We will introduce value lists in a moment, and cover the other options
|
|
|
|
in due course.
|
2018-09-01 17:13:50 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[B]NOTE:\f[R] In the context of mod translations, pitch bend values
|
|
|
|
are interpreted as \f[I]unsigned\f[R] quantities in the range 0..16383
|
|
|
|
(with 8192 denoting the center value), which corresponds to the way they
|
|
|
|
are actually encoded in MIDI.
|
2018-09-14 09:58:57 +02:00
|
|
|
This makes the modular arithmetic work consistently across all types of
|
|
|
|
MIDI messages, and also facilitates conversions between the different
|
|
|
|
types of absolute parameter values.
|
2018-11-16 21:16:00 +01:00
|
|
|
Normally you shouldn\[cq]t have to worry about this, but the change in
|
2018-09-05 04:57:26 +02:00
|
|
|
representation needs to be taken into account when transforming pitch
|
|
|
|
bend values with value lists.
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Let\[cq]s return to our example.
|
2018-09-01 17:13:50 +02:00
|
|
|
As usual in data translations, you can also specify a step size on the
|
|
|
|
right\-hand side to upscale the output value (which is the remainder
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]r\f[R] here):
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CP[16] C0[2]
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-14 09:58:57 +02:00
|
|
|
More complicated transformations can be specified as value lists
|
2018-09-01 17:13:50 +02:00
|
|
|
instead.
|
2018-09-14 09:58:57 +02:00
|
|
|
E.g., the APCmini uses the velocities 0, 1, 3 and 5 to denote
|
|
|
|
\[lq]off\[rq] and the colors green, red and yellow, respectively, so we
|
|
|
|
can map the meter values to different colors as follows:
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CP[16] C0{0,1,1,1,1,1,1,1,1,5,5,5,3}
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-01 13:21:18 +02:00
|
|
|
Using the shorthand for repetitions, this can be written more succinctly
|
|
|
|
(which also helps readability):
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CP[16] C0{0,1:8,5:3,3}
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-01 13:21:18 +02:00
|
|
|
Thus 0 will be mapped to 0 (off), 1..8 to 1 (green), 9..11 to 5
|
|
|
|
(yellow), and 12 or more to 3 (red).
|
2018-09-14 09:58:57 +02:00
|
|
|
(These values appear to be in line with the MCP feedback spit out by
|
|
|
|
Ardour, and what little technical documentation about the Mackie
|
|
|
|
protocol is available on the web.
|
|
|
|
Your mileage may vary, though, so you may have to experiment with these
|
|
|
|
values to make this rule work with your DAW.)
|
2018-09-01 13:21:18 +02:00
|
|
|
.PP
|
|
|
|
The quotient here is the mixer channel index in the high\-nibble of the
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]CP\f[R] message, which will be used as an offset for the
|
|
|
|
\f[C]C0\f[R] note on the right, so the above rule shows the meters as a
|
|
|
|
single row of colored buttons at the bottom of the 8x8 grid on the
|
|
|
|
APCmini (first value on \f[C]C0\f[R], second value on \f[C]C#0\f[R],
|
|
|
|
etc.).
|
|
|
|
To get a different layout, you can also scale the \f[I]offset\f[R]
|
|
|
|
value, by adding a second step size to the left\-hand side:
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CP[16][8] C0{0,1:8,5:3,3}
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-18 07:27:12 +02:00
|
|
|
Even though the extra step size appears on the left\-hand side of a mod
|
|
|
|
translation, it is applied to all messages on the \f[I]right\-hand
|
2018-11-16 21:16:00 +01:00
|
|
|
side\f[R], scaling \f[I]up\f[R] the offsets of all output messages by
|
|
|
|
the same factor.
|
2018-09-18 07:27:12 +02:00
|
|
|
Thus, in the example above, the buttons are now in the first
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]column\f[R] of the grid (first value on \f[C]C0\f[R], second value
|
|
|
|
on \f[C]G#0\f[R], etc.).
|
|
|
|
Instead of a single step size, it\[cq]s also possible to specify a list
|
|
|
|
of discrete offset values, so that you can achieve any regular or
|
|
|
|
irregular output pattern that you want.
|
2018-09-01 13:21:18 +02:00
|
|
|
E.g., the following rule places every other meter value in the second
|
|
|
|
row:
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CP[16]{0,9,2,11,4,13,6,15} C0{0,1:8,5:3,3}
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-30 14:46:44 +02:00
|
|
|
You might also output several notes at once, in order to display a
|
2018-11-16 21:16:00 +01:00
|
|
|
horizontal or vertical meter \f[I]strip\f[R] instead of just a single
|
2018-09-01 17:13:50 +02:00
|
|
|
colored button for each value.
|
2018-08-28 00:02:49 +02:00
|
|
|
For instance:
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CP[16] C0{0,1} G#0{0:8,5} E1{0:11,3}
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-27 16:01:19 +02:00
|
|
|
Note that each of the output notes will be offset by the same amount, so
|
|
|
|
that the green, yellow and red buttons will always be lined up
|
2018-08-28 00:02:49 +02:00
|
|
|
vertically in this example.
|
2018-09-14 09:58:57 +02:00
|
|
|
(The APCmini.midizaprc example actually uses a very similar scheme
|
|
|
|
mapping the meter values to the five topmost button rows.)
|
2018-08-29 00:18:17 +02:00
|
|
|
.PP
|
|
|
|
Another example from the Mackie protocol is time feedback.
|
2018-08-30 14:46:44 +02:00
|
|
|
The following rule (also from the APCmini.midizaprc example) decodes the
|
2018-08-31 10:12:23 +02:00
|
|
|
least significant digit of the beat number in the time display
|
2018-11-16 21:16:00 +01:00
|
|
|
(\f[C]CC69\f[R]) to count off time on some of the scene launch buttons
|
|
|
|
of the APCmini.
|
2018-08-29 00:18:17 +02:00
|
|
|
Note that the digits are actually encoded in ASCII, hence the copious
|
|
|
|
amount of initial zeros in the value lists below with which we skip over
|
|
|
|
all the non\-digit characters at the beginning of the ASCII table.
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC69[] F7{0:49,1,0} E7{0:50,1,0} Eb7{0:51,1,0} D7{0:52,1,0}
|
|
|
|
\f[R]
|
2018-08-29 00:18:17 +02:00
|
|
|
.fi
|
2018-08-30 14:46:44 +02:00
|
|
|
.PP
|
2018-09-01 17:13:50 +02:00
|
|
|
Also note the use of an empty modulus bracket on the left\-hand side,
|
|
|
|
which means that we always have a zero offset here and thus the output
|
2018-11-16 21:16:00 +01:00
|
|
|
notes aren\[cq]t modified in this example.
|
2018-09-01 17:13:50 +02:00
|
|
|
.SS Basic Mod Translations
|
2018-08-30 14:46:44 +02:00
|
|
|
.PP
|
|
|
|
While mod translations are often employed for MIDI feedback, they can
|
2018-09-01 17:13:50 +02:00
|
|
|
also be used as an alternative to \[lq]ordinary\[rq] (incremental) data
|
|
|
|
translations in various contexts.
|
2018-11-16 21:16:00 +01:00
|
|
|
We discuss some of these use cases below and show how they\[cq]re
|
2018-08-27 16:01:19 +02:00
|
|
|
implemented.
|
|
|
|
.PP
|
2018-09-01 17:13:50 +02:00
|
|
|
For more basic uses we often want to simply pass on (and possibly
|
2018-11-16 21:16:00 +01:00
|
|
|
transform) the input value \f[I]without\f[R] using an offset, so we
|
2018-09-01 17:13:50 +02:00
|
|
|
employ a default modulus in most of the following examples to ensure
|
|
|
|
that the offset becomes zero and thus inconsequential.
|
2018-11-16 21:16:00 +01:00
|
|
|
We also call such translations \f[I]basic\f[R] mod translations.
|
2018-09-01 17:13:50 +02:00
|
|
|
They are useful, in particular, if we want to simply preserve the
|
|
|
|
parameter value in a data translation.
|
|
|
|
For instance:
|
2018-08-30 14:46:44 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[] C5
|
|
|
|
\f[R]
|
2018-08-30 14:46:44 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
This translates the \f[C]CC1\f[R] (modulation wheel) controller to a
|
|
|
|
\f[C]C5\f[R] (middle C) note message in such a way that the controller
|
2018-08-30 14:46:44 +02:00
|
|
|
value becomes the velocity of the note.
|
|
|
|
Note that this is different from both the key translation
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]CC1 C5\f[R] (which only preserves the \[lq]on\[rq]/\[lq]off\[rq]
|
2018-08-30 14:46:44 +02:00
|
|
|
status but looses the actual parameter value) and the incremental data
|
2018-11-16 21:16:00 +01:00
|
|
|
translation \f[C]CC1= C5\f[R] (which usually preserves the value, but
|
2018-09-14 09:58:57 +02:00
|
|
|
executes the translation in a step\-wise fashion).
|
|
|
|
A mod translation always maps messages in a single step, which
|
|
|
|
reproduces leaps in the input values on the output side (and, as a side
|
|
|
|
effect, also reduces the amount of data traffic compared to incremental
|
|
|
|
data translations).
|
|
|
|
While key and incremental data translations are tailored to key and
|
|
|
|
mouse output, for pure MIDI bindings like the one above a basic mod
|
|
|
|
translation is often preferable.
|
2018-08-31 10:12:23 +02:00
|
|
|
.PP
|
|
|
|
You also need to use a mod translation if your binding involves discrete
|
|
|
|
value lists, because these are not available in other kinds of
|
2018-08-31 02:15:56 +02:00
|
|
|
translations.
|
2018-11-16 21:16:00 +01:00
|
|
|
Value lists can represent \f[I]any\f[R] discrete mapping from input to
|
2018-08-31 10:12:23 +02:00
|
|
|
output values, and thus offer much more flexibility than simple step
|
2018-08-30 14:46:44 +02:00
|
|
|
sizes.
|
2018-11-16 21:16:00 +01:00
|
|
|
For instance, here\[cq]s how to map controller values to the first few
|
2018-08-27 16:01:19 +02:00
|
|
|
Fibonacci numbers:
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[] CC1{0,1,1,2,3,5,8,13,21,34,55,89}
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-31 10:12:23 +02:00
|
|
|
Value lists offer some conveniences to facilitate their use,
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]repetitions\f[R] (which we\[cq]ve already discussed above) and
|
|
|
|
\f[I]enumerations\f[R].
|
2018-08-31 10:12:23 +02:00
|
|
|
Enumerations are used to denote an ascending or descending range of
|
|
|
|
values.
|
2018-08-30 14:46:44 +02:00
|
|
|
E.g., to reverse the values of a controller you may write:
|
2018-08-27 04:23:32 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[] CC1{127\-0}
|
|
|
|
\f[R]
|
2018-08-27 04:23:32 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Contrast this with the \f[I]incremental\f[R] reversed controller rule
|
|
|
|
that we\[cq]ve seen earlier:
|
2018-09-18 07:27:12 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1= CC1[\-1]
|
|
|
|
\f[R]
|
2018-09-18 07:27:12 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
As mentioned, this rule requires that you first move the controller up
|
|
|
|
to its maximum position to make it work.
|
2018-11-16 21:16:00 +01:00
|
|
|
The mod translation above uses absolute values and thus doesn\[cq]t have
|
2018-09-22 21:21:10 +02:00
|
|
|
this defect.
|
2018-09-18 07:27:12 +02:00
|
|
|
.PP
|
2018-08-31 10:12:23 +02:00
|
|
|
The values in a list may be in any order, and you can throw in any
|
|
|
|
combination of singleton values, enumerations and repetitions.
|
2018-09-01 17:13:50 +02:00
|
|
|
For instance:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[] CC1{0:2\-5,7:5\-0}
|
|
|
|
\f[R]
|
2018-09-01 17:13:50 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-02 11:47:08 +02:00
|
|
|
The value list in this example starts with two zeros, then ramps up to 5
|
|
|
|
followed by five 7s, before finally fading back to 0.
|
|
|
|
It goes without saying that this is much easier to read and also much
|
|
|
|
less error\-prone to write than
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]{0,0,1,2,3,4,5,7,7,7,7,7,6,5,4,3,2,1,0}\f[R].
|
2018-08-30 14:46:44 +02:00
|
|
|
.PP
|
2018-09-02 11:47:08 +02:00
|
|
|
Values in lists may also be negative.
|
|
|
|
In general, if mapping any input value using a value list results in an
|
|
|
|
output value that is out of range for the type of MIDI message at hand,
|
|
|
|
the message will be silently ignored.
|
|
|
|
We can use this, e.g., to suppress note\-off messages in the output:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
C0[] C0{\-1,1\-127}
|
|
|
|
\f[R]
|
2018-09-02 11:47:08 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
This rule will translate a zero velocity to \-1, which isn\[cq]t in the
|
2018-09-02 11:47:08 +02:00
|
|
|
valid range, so the output message will be dropped.
|
|
|
|
For all other velocities, the input message will be output unchanged,
|
2018-11-16 21:16:00 +01:00
|
|
|
because the \f[C]1\-127\f[R] enumeration maps the positive velocities to
|
2018-09-02 11:47:08 +02:00
|
|
|
themselves.
|
2018-11-16 21:16:00 +01:00
|
|
|
If you\[cq]d rather output a key\-style fixed velocity for the note\-ons
|
2018-09-02 11:47:08 +02:00
|
|
|
instead, you can do that as follows:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
C0[] C0{\-1,127}
|
|
|
|
\f[R]
|
2018-09-02 11:47:08 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-22 21:21:10 +02:00
|
|
|
This kind of translation may look a bit odd, but can be useful at times
|
|
|
|
if the application interprets note inputs, e.g., as radio or toggle
|
|
|
|
buttons, and may get confused by note\-off messages.
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that it\[cq]s impossible to do this kind of mapping with key or
|
|
|
|
incremental data translations, because these don\[cq]t allow you to
|
|
|
|
suppress the note\-off messages.
|
2018-09-02 11:47:08 +02:00
|
|
|
.PP
|
2018-09-16 06:40:04 +02:00
|
|
|
Last but not least, you can also use a modulus of 1 to cancel the
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]remainder\f[R] instead, if you want to use the input value solely
|
|
|
|
as an offset.
|
|
|
|
For instance, here\[cq]s how you can map controller values to note
|
|
|
|
\f[I]numbers\f[R] (rather than velocities):
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[1] C0
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-30 14:46:44 +02:00
|
|
|
This outputs the note with the same number as the controller value,
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]C0\f[R] for value 0, \f[C]C#0\f[R] for value 1, \f[C]D0\f[R] for
|
|
|
|
value 2, etc.
|
2018-09-02 11:47:08 +02:00
|
|
|
In fact, this is just a basic mod translation in disguise, because
|
2018-11-16 21:16:00 +01:00
|
|
|
employing the \f[C]\[aq]\f[R] flag on the output message to transpose
|
2018-09-16 06:40:04 +02:00
|
|
|
quotient and remainder, we can also write it as:
|
2018-08-27 04:23:32 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[] C0\[aq]
|
|
|
|
\f[R]
|
2018-08-27 04:23:32 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-14 09:58:57 +02:00
|
|
|
Note that the quotient, which becomes the velocity of the output note,
|
|
|
|
will always be zero here, so the above translation turns all notes off.
|
2018-09-01 17:13:50 +02:00
|
|
|
To get a nonzero velocity, you specify it in a value list:
|
2018-08-30 14:46:44 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC2[] C0{127}\[aq]
|
|
|
|
\f[R]
|
2018-08-30 14:46:44 +02:00
|
|
|
.fi
|
2018-09-01 17:13:50 +02:00
|
|
|
.SS Extracting Sub\-Values
|
|
|
|
.PP
|
2018-08-29 00:18:17 +02:00
|
|
|
Another important idiom is the following, which extracts the low nibble
|
|
|
|
from a controller value.
|
2018-08-30 14:46:44 +02:00
|
|
|
To these ends, we use a modulus of 16 and force the offset value to
|
|
|
|
zero:
|
2018-08-25 22:55:02 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[16]{0} CC1
|
|
|
|
\f[R]
|
2018-08-29 00:18:17 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Extracting the \f[I]high\f[R] nibble is just as easy (this is another
|
2018-08-30 14:46:44 +02:00
|
|
|
case where the transposition flag comes in handy):
|
2018-08-29 00:18:17 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[16]{0} CC2\[aq]
|
|
|
|
\f[R]
|
2018-08-25 22:55:02 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that this works because the output mapping \f[C]{0}\f[R] (which
|
|
|
|
forces the offset to 0) is in fact applied \f[I]after\f[R] the
|
2018-09-01 17:13:50 +02:00
|
|
|
transposition.
|
2018-11-16 21:16:00 +01:00
|
|
|
Thus the quotient becomes the value of the \f[C]CC2\f[R] message, while
|
2018-09-13 19:37:43 +02:00
|
|
|
the remainder is canceled out and becomes a zero offset.
|
2018-11-16 21:16:00 +01:00
|
|
|
You can also output \f[I]both\f[R] the low and high nibbles at the same
|
2018-09-01 17:13:50 +02:00
|
|
|
time that way:
|
2018-08-31 10:12:23 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[16]{0} CC1 CC2\[aq]
|
|
|
|
\f[R]
|
2018-08-31 10:12:23 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-02 11:47:08 +02:00
|
|
|
Using similar rules, you can extract almost any part of an input value,
|
2018-11-16 21:16:00 +01:00
|
|
|
down to every single bit if needed (see the \f[I]Macro Translations\f[R]
|
2018-09-15 23:53:25 +02:00
|
|
|
section below for another example).
|
|
|
|
.SS Detecting Changes
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Let\[cq]s have another look at the high\-nibble extraction rule from
|
|
|
|
above:
|
2018-09-15 23:53:25 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[16]{0} CC2\[aq]
|
|
|
|
\f[R]
|
2018-09-15 23:53:25 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
Note that if the input value changes gradually then many output values
|
|
|
|
will be identical.
|
|
|
|
E.g., if the input values are 0, 10, 19, 32, 64 then the first four high
|
|
|
|
nibbles are all zero, so the output will be 0, 0, 0, 0, 1, with the zero
|
|
|
|
value repeated four times.
|
2018-11-16 21:16:00 +01:00
|
|
|
If this is not desired, you can add the \f[C]?\f[R] flag to indicate
|
|
|
|
that the message should be output only if the value has changed:
|
2018-09-15 23:53:25 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[16]{0} CC2\[aq]?
|
|
|
|
\f[R]
|
2018-09-15 23:53:25 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
Now, repeated values are suppressed, so with the same inputs the output
|
|
|
|
will be just 0, 1.
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that we used the \f[C]?\f[R] flag in combination with transposition
|
2018-09-15 23:53:25 +02:00
|
|
|
and the offset forced to zero here, but of course it will work for any
|
|
|
|
kind of change (offset or value, transposed or not).
|
|
|
|
Also note that change detection always considers the
|
|
|
|
\[lq]post\-transform\[rq] values as they would be output, i.e., changes
|
2018-11-16 21:16:00 +01:00
|
|
|
are detected \f[I]after\f[R] transposition and all mappings of input and
|
2018-09-15 23:53:25 +02:00
|
|
|
output values have been performed.
|
|
|
|
.PP
|
|
|
|
Change detection is often useful when input values are projected, as in
|
|
|
|
the above example, but also in many other situations in which you simply
|
|
|
|
want to prevent repeated values.
|
2018-11-16 21:16:00 +01:00
|
|
|
For instance, suppose that we\[cq]d like to turn the modulation wheel
|
|
|
|
(\f[C]CC1\f[R]) into a kind of on/off switch.
|
2018-09-15 23:53:25 +02:00
|
|
|
Using a basic mod translation with a value list and change detection,
|
|
|
|
this can be done quite easily:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC1[] CC1{0,127}?
|
|
|
|
\f[R]
|
2018-09-15 23:53:25 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-16 06:40:04 +02:00
|
|
|
This emits a single 127 value as soon as the input value becomes
|
|
|
|
nonzero, and a single 0 value when it drops to zero again.
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that without the \f[C]?\f[R] flag, the 127 value might be repeated
|
2018-09-16 06:40:04 +02:00
|
|
|
any number of times while you keep turning the modulation wheel, which
|
2018-11-16 21:16:00 +01:00
|
|
|
isn\[cq]t the behavior we want here.
|
2018-08-30 14:46:44 +02:00
|
|
|
.SS Macro Translations
|
2018-08-29 00:18:17 +02:00
|
|
|
.PP
|
2018-09-02 11:47:08 +02:00
|
|
|
There are some situations in which it is hard or even impossible to
|
|
|
|
construct a translation in a single step, but it may become much easier
|
|
|
|
if we can recursively invoke other translations.
|
2018-08-29 00:18:17 +02:00
|
|
|
midizap allows you to do this by \[lq]calling\[rq] the mod translation
|
|
|
|
for a MIDI message on the right\-hand side of a translation.
|
2018-11-16 21:16:00 +01:00
|
|
|
This is done by prefixing the message to be expanded with the
|
|
|
|
\f[C]$\f[R] character:
|
2018-08-29 00:18:17 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC0[] $CC1
|
|
|
|
\f[R]
|
2018-08-29 00:18:17 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that you can \f[I]only\f[R] call mod translations this way, so the
|
|
|
|
message to be expanded (\f[C]CC1\f[R] in this example) must be bound in
|
|
|
|
a mod translation somewhere; otherwise you\[cq]ll get a warning about
|
|
|
|
the message being undefined and no output will be generated.
|
|
|
|
On the other hand, the translation \f[I]containing\f[R] the call may
|
|
|
|
also be a key or incremental data translation instead, so we might just
|
|
|
|
as well have written, e.g.:
|
2018-09-03 01:54:50 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC0= $CC1
|
|
|
|
\f[R]
|
2018-09-03 01:54:50 +02:00
|
|
|
.fi
|
2018-08-30 14:46:44 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Before we proceed, let\[cq]s introduce a few terms which will make it
|
|
|
|
easier to talk about these things.
|
2018-08-30 14:46:44 +02:00
|
|
|
We refer to a mod translation being called in this manner as a
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[I]macro translation\f[R], and we also call the left\-hand side of the
|
|
|
|
translation a \f[I]macro\f[R], and the invocation of a macro using the
|
|
|
|
dollar symbol a \f[I]macro call\f[R].
|
2018-08-30 14:46:44 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
To continue our example, let\[cq]s define the \f[C]CC1\f[R] macro so
|
|
|
|
that it outputs just a single note message:
|
2018-08-29 00:18:17 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC0[] $CC1 #1
|
|
|
|
CC1[] C5 #2
|
|
|
|
\f[R]
|
2018-08-29 00:18:17 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-08-30 14:46:44 +02:00
|
|
|
On a conceptual level, the macro expansion process works pretty much
|
2018-08-31 02:15:56 +02:00
|
|
|
like the production rules of a grammar, with the \[lq]dollar\[rq] tokens
|
2018-08-31 10:12:23 +02:00
|
|
|
playing the role of the nonterminals.
|
2018-11-16 21:16:00 +01:00
|
|
|
Thus, with the definitions above a \f[C]CC0\f[R] message will be
|
2018-08-30 14:46:44 +02:00
|
|
|
processed as follows:
|
2018-08-29 00:18:17 +02:00
|
|
|
.IP \[bu] 2
|
2018-08-30 14:46:44 +02:00
|
|
|
Rule #1 is applied, constructing the output sequence with the
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]CC1\f[R] message as usual.
|
2018-08-29 00:18:17 +02:00
|
|
|
.IP \[bu] 2
|
2018-11-16 21:16:00 +01:00
|
|
|
Instead of outputting the resulting \f[C]CC1\f[R] message directly, the
|
2018-08-31 10:12:23 +02:00
|
|
|
program now looks for a mod translation of that message which can be
|
|
|
|
applied recursively.
|
2018-08-29 00:18:17 +02:00
|
|
|
.IP \[bu] 2
|
2018-11-16 21:16:00 +01:00
|
|
|
Rule #2 is applied, yielding a \f[C]C5\f[R] message which is substituted
|
|
|
|
for the \f[C]$CC1\f[R] token in rule #1.
|
2018-08-29 00:18:17 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Unsurprisingly, the end result is a \f[C]C5\f[R] message with the same
|
|
|
|
velocity as the value of the \f[C]CC1\f[R] message, which in turn comes
|
|
|
|
from the original \f[C]CC0\f[R] message being translated.
|
2018-08-29 00:18:17 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Of course, we could also just have written \f[C]CC0[] C5\f[R] here and
|
2018-09-01 17:13:50 +02:00
|
|
|
be done with it.
|
2018-11-16 21:16:00 +01:00
|
|
|
So let\[cq]s try something slightly more complicated which really
|
|
|
|
\f[I]needs\f[R] recursive translations to work.
|
|
|
|
For instance, suppose that we\[cq]d like to output \f[I]two\f[R]
|
|
|
|
messages instead: the note message \f[C]C5\f[R] as before, followed by a
|
|
|
|
\f[C]CC1\f[R] message with just the low nibble of the controller value.
|
2018-08-29 00:18:17 +02:00
|
|
|
Now each of these translations is easy to define:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC0[] C5
|
|
|
|
CC0[16]{0} CC1
|
|
|
|
\f[R]
|
2018-08-29 00:18:17 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
But we can\[cq]t just put these two rules into the same section, because
|
|
|
|
we\[cq]re not allowed to bind \f[C]CC0\f[R] in two different
|
|
|
|
translations at once (if you try this, the parser will complain and just
|
|
|
|
ignore the second rule).
|
|
|
|
And the single rule \f[C]CC0[16]{0} C5 CC1\f[R] won\[cq]t work either,
|
|
|
|
because it only passes the low nibble to the \f[C]C5\f[R] message.
|
2018-09-02 11:47:08 +02:00
|
|
|
However, using a macro call we can massage those rules into an eligible
|
|
|
|
form:
|
2018-08-29 00:18:17 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC0[] C5 $CC1
|
|
|
|
CC1[16]{0} CC1
|
|
|
|
\f[R]
|
2018-08-29 00:18:17 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-09-02 11:47:08 +02:00
|
|
|
This does exactly what we set out to do, and the transformation of the
|
|
|
|
original rules we applied here is actually quite straightforward.
|
2018-08-29 00:18:17 +02:00
|
|
|
In the same vein, we can combine as many different mod translations as
|
|
|
|
we like, even if they involve different moduli and offset
|
|
|
|
transformations.
|
|
|
|
.PP
|
2018-08-31 10:12:23 +02:00
|
|
|
If you know C, you will have realized by now that macro translations
|
2018-09-16 20:53:46 +02:00
|
|
|
work pretty much like macros in the C programming language.
|
2018-08-29 00:18:17 +02:00
|
|
|
The same caveats apply here, too.
|
2018-11-16 21:16:00 +01:00
|
|
|
Specifically, you usually do \f[I]not\f[R] want to have a macro invoke
|
2018-09-15 23:53:25 +02:00
|
|
|
itself (either directly or indirectly), because that will almost
|
|
|
|
certainly lead to infinite recursion.
|
2018-08-31 10:12:23 +02:00
|
|
|
E.g.:
|
2018-08-29 00:18:17 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC0[128] $CC1
|
|
|
|
CC1[128] $CC0 # don\[aq]t do this!
|
|
|
|
\f[R]
|
2018-08-29 00:18:17 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
midizap \f[I]will\f[R] catch such mishaps after a few iterations, but
|
|
|
|
it\[cq]s better to avoid them in the first place.
|
2018-09-16 06:40:04 +02:00
|
|
|
We mention in passing that in theory, recursive macro calls in
|
|
|
|
conjunction with value lists and change detection make the configuration
|
|
|
|
language Turing\-complete.
|
2018-11-16 21:16:00 +01:00
|
|
|
However, there\[cq]s a quite stringent limit on the number of recursive
|
2018-09-16 06:40:04 +02:00
|
|
|
calls, and there are no variables and no iteration constructs, so these
|
2018-11-16 21:16:00 +01:00
|
|
|
facilities aren\[cq]t really suitable for general\-purpose programming.
|
2018-08-29 00:18:17 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
But there\[cq]s still a lot of fun to be had with macros despite their
|
2018-09-15 23:53:25 +02:00
|
|
|
limitations.
|
2018-11-16 21:16:00 +01:00
|
|
|
Here\[cq]s another instructive example which spits out the individual
|
|
|
|
bits of a controller value, using the approach that we discussed earlier
|
|
|
|
in the context of nibble extraction.
|
|
|
|
Input comes from \f[C]CC7\f[R] in the example, and bit #\f[I]i\f[R] of
|
|
|
|
the controller value becomes \f[C]CC\f[R]\f[I]i\f[R] in the output,
|
|
|
|
where \f[I]i\f[R] runs from 0 to 6.
|
2018-09-01 13:21:18 +02:00
|
|
|
Note that each of these rules uses a successively smaller power of 2 as
|
|
|
|
modulus and passes on the remainder to the next rule, while
|
2018-09-01 17:13:50 +02:00
|
|
|
transposition is used to extract and output the topmost bit in the
|
|
|
|
quotient.
|
2018-10-15 06:23:23 +02:00
|
|
|
(You may want to run this example with debugging enabled to see what
|
|
|
|
exactly is going on there.)
|
2018-08-29 00:18:17 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC7[64]{0} $CC6 CC6\[aq]
|
|
|
|
CC6[32]{0} $CC5 CC5\[aq]
|
|
|
|
CC5[16]{0} $CC4 CC4\[aq]
|
|
|
|
CC4[8]{0} $CC3 CC3\[aq]
|
|
|
|
CC3[4]{0} $CC2 CC2\[aq]
|
|
|
|
CC2[2]{0} CC0 CC1\[aq]
|
|
|
|
\f[R]
|
2018-08-29 00:18:17 +02:00
|
|
|
.fi
|
2018-09-15 23:53:25 +02:00
|
|
|
.PP
|
|
|
|
In principle, any message which can occur on the left\-hand side of a
|
2018-11-16 21:16:00 +01:00
|
|
|
mod translation (i.e., everything but \f[C]PC\f[R]) can also be used as
|
|
|
|
a macro.
|
|
|
|
Unfortunately, in general you can\[cq]t be sure which messages might
|
|
|
|
show up in \f[I]real\f[R] MIDI input.
|
2018-09-15 23:53:25 +02:00
|
|
|
For instance, in the example above the macro translations for
|
2018-11-16 21:16:00 +01:00
|
|
|
\f[C]CC2\f[R] to \f[C]CC6\f[R] might also be triggered by real MIDI
|
|
|
|
input instead of macro calls.
|
2018-09-15 23:53:25 +02:00
|
|
|
While this may be useful at times, e.g., for testing purposes, it is
|
|
|
|
most likely going to confuse unsuspecting end users.
|
|
|
|
As a remedy, midizap also provides a special kind of \f[I]macro
|
2018-11-16 21:16:00 +01:00
|
|
|
event\f[R], denoted \f[C]M0\f[R] to \f[C]M127\f[R].
|
|
|
|
These \[lq]synthetic\[rq] messages work exactly like \f[C]CC\f[R]
|
2018-09-16 06:40:04 +02:00
|
|
|
messages, but they are guaranteed to never occur as real input, and they
|
2018-11-16 21:16:00 +01:00
|
|
|
can \f[I]only\f[R] be used in macro calls and on the left\-hand side of
|
2018-09-16 06:40:04 +02:00
|
|
|
mod translations.
|
2018-09-15 23:53:25 +02:00
|
|
|
We can rewrite the previous example using macro events as follows:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
CC7[64]{0} $M6 CC6\[aq]
|
|
|
|
M6[32]{0} $M5 CC5\[aq]
|
|
|
|
M5[16]{0} $M4 CC4\[aq]
|
|
|
|
M4[8]{0} $M3 CC3\[aq]
|
|
|
|
M3[4]{0} $M2 CC2\[aq]
|
|
|
|
M2[2]{0} CC0 CC1\[aq]
|
|
|
|
\f[R]
|
2018-09-15 23:53:25 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Let\[cq]s conclude with another, slightly more practical example for the
|
|
|
|
use of macros, which turns the pitch wheel of a MIDI keyboard into a
|
|
|
|
simple kind of \[lq]shuttle control\[rq].
|
|
|
|
To illustrate how this works, let\[cq]s emit an \f[C]XK_Left\f[R] key
|
|
|
|
event when the pitch wheel is pushed down, and an \f[C]XK_Right\f[R]
|
|
|
|
event when it\[cq]s pushed up.
|
2018-09-15 23:53:25 +02:00
|
|
|
This can be done as follows:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
PB[] $M0{0:8192,1,2}?
|
|
|
|
M0[] $M1{1,\-1} $M2{\-1:2,1,\-1}
|
|
|
|
M1[] XK_Left
|
|
|
|
M2[] XK_Right
|
|
|
|
\f[R]
|
2018-09-15 23:53:25 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Note that the \f[C]M0\f[R] macro will be invoked with a value of 0, 1
|
|
|
|
and 2 if the pitch wheel is down, centered, and up, respectively.
|
|
|
|
Also, we use the change flag here, so the \f[C]M0\f[R] macro is only
|
2018-09-18 00:06:55 +02:00
|
|
|
invoked when this value actually changes.
|
2018-11-16 21:16:00 +01:00
|
|
|
The value lists in the definition of \f[C]M0\f[R] are then used to
|
|
|
|
filter these values and call the appropriate macro which handles the key
|
|
|
|
output: \f[C]M1\f[R] for value 0, \f[C]M2\f[R] for value 2.
|
2018-09-20 01:50:52 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Flipping the pitch wheel just to move the cursor left and right
|
|
|
|
isn\[cq]t much fun after a while, but it\[cq]s easy to adjust the
|
|
|
|
\f[C]M1\f[R] and \f[C]M2\f[R] macros for more sensible purposes.
|
2018-09-16 06:40:04 +02:00
|
|
|
E.g., we might output the keyboard shortcuts for \[lq]Rewind\[rq] and
|
2018-09-18 07:27:12 +02:00
|
|
|
\[lq]Fast Forward\[rq] for a video editor like Kdenlive or Shotcut:
|
2018-09-15 23:53:25 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
M1[] \[dq]j\[dq]
|
|
|
|
M2[] \[dq]l\[dq]
|
|
|
|
\f[R]
|
2018-09-18 07:27:12 +02:00
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
We could also substitute the corresponding MIDI messages of the Mackie
|
|
|
|
protocol to control a DAW program like Ardour:
|
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
M1[] G7[127] # Rewind
|
|
|
|
M2[] G#7[127] # Fast Forward
|
|
|
|
\f[R]
|
2018-09-15 23:53:25 +02:00
|
|
|
.fi
|
2018-09-18 00:06:55 +02:00
|
|
|
.SH Configuration Language Grammar
|
|
|
|
.PP
|
|
|
|
The following EBNF grammar summarizes the syntax of the configuration
|
|
|
|
language.
|
|
|
|
The character set is 7 bit ASCII (arbitrary UTF\-8 characters are
|
|
|
|
permitted in comments, however).
|
2018-09-18 07:27:12 +02:00
|
|
|
The language is line\-oriented; each directive, section header, and
|
|
|
|
translation must be on a separate line.
|
2018-09-18 00:06:55 +02:00
|
|
|
Empty lines and lines containing nothing but whitespace are generally
|
2018-11-16 21:16:00 +01:00
|
|
|
ignored, as are comments, which are introduced with \f[C]#\f[R] at the
|
2018-09-20 01:50:52 +02:00
|
|
|
beginning of a line or after whitespace, and continue until the end of
|
|
|
|
the line.
|
2018-09-22 21:21:10 +02:00
|
|
|
(The section name and regex in header lines is always taken verbatim,
|
2018-11-16 21:16:00 +01:00
|
|
|
though, so whitespace and \f[C]#\f[R] have no special significance
|
2018-09-22 21:21:10 +02:00
|
|
|
there.)
|
2018-09-18 00:06:55 +02:00
|
|
|
.PP
|
2018-09-23 13:34:48 +02:00
|
|
|
Regular expressions must follow the usual syntax for extended regular
|
2018-09-18 11:53:43 +02:00
|
|
|
expressions, see regex(7) for details.
|
2018-09-18 07:27:12 +02:00
|
|
|
In a directive or translation line, tokens are delimited by whitespace.
|
2018-09-18 00:06:55 +02:00
|
|
|
Strings are delimited by double quotes and may contain any printable
|
|
|
|
ASCII character except newline and double quotes.
|
2018-09-23 13:34:48 +02:00
|
|
|
Numbers are always integers written in decimal notation.
|
2018-09-18 00:06:55 +02:00
|
|
|
.IP
|
|
|
|
.nf
|
|
|
|
\f[C]
|
2018-11-16 21:16:00 +01:00
|
|
|
config ::= { directive | header | translation }
|
|
|
|
header ::= \[dq][\[dq] name \[dq]]\[dq] [ \[dq]CLASS\[dq] | \[dq]TITLE\[dq] ] regex
|
|
|
|
translation ::= midi\-token { key\-token | midi\-token }
|
2018-09-18 00:06:55 +02:00
|
|
|
|
2018-11-16 21:16:00 +01:00
|
|
|
directive ::= \[dq]DEBUG_REGEX\[dq] | \[dq]DEBUG_STROKES\[dq] | \[dq]DEBUG_KEYS\[dq] |
|
|
|
|
\[dq]DEBUG_MIDI\[dq] | \[dq]MIDI_OCTAVE\[dq] number |
|
|
|
|
\[dq]JACK_NAME\[dq] string | \[dq]JACK_PORTS\[dq] number |
|
|
|
|
\[dq]JACK_IN\[dq] [number] regex | \[dq]JACK_OUT\[dq] [number] regex |
|
|
|
|
\[dq]PASSTHROUGH\[dq] [ number ] |
|
|
|
|
\[dq]SYSTEM_PASSTHROUGH\[dq] [ number ]
|
2018-09-18 00:06:55 +02:00
|
|
|
|
2018-11-16 21:16:00 +01:00
|
|
|
midi\-token ::= msg [ mod ] [ steps ] [ \[dq]\-\[dq] number] [ flag ]
|
|
|
|
msg ::= ( note | other | \[dq]M\[dq] ) [ number ]
|
|
|
|
note ::= ( \[dq]A\[dq] | ... | \[dq]G\[dq] ) [ \[dq]#\[dq] | \[dq]b\[dq] ]
|
|
|
|
other ::= \[dq]CH\[dq] | \[dq]PB\[dq] | \[dq]PC\[dq] | \[dq]CC\[dq] | \[dq]CP\[dq] | \[dq]KP:\[dq] note
|
|
|
|
mod ::= \[dq][\[dq] [ number ] \[dq]]\[dq]
|
|
|
|
steps ::= \[dq][\[dq] number \[dq]]\[dq] | \[dq]{\[dq] list \[dq]}\[dq]
|
|
|
|
list ::= number { \[dq],\[dq] number | \[dq]:\[dq] number | \[dq]\-\[dq] number }
|
|
|
|
flag ::= \[dq]\-\[dq] | \[dq]+\[dq] | \[dq]=\[dq] | \[dq]<\[dq] | \[dq]>\[dq] | \[dq]\[ti]\[dq] |
|
|
|
|
\[dq]\[aq]\[dq] | \[dq]?\[dq] | \[dq]\[aq]?\[dq] | \[dq]?\[aq]\[dq]
|
2018-09-18 00:06:55 +02:00
|
|
|
|
2018-11-16 21:16:00 +01:00
|
|
|
key\-token ::= \[dq]RELEASE\[dq] | \[dq]SHIFT\[dq] [ number ] |
|
|
|
|
keycode [ \[dq]/\[dq] keyflag ] | string
|
|
|
|
keycode ::= \[dq]XK_Button_1\[dq] | \[dq]XK_Button_2\[dq] | \[dq]XK_Button_3\[dq] |
|
|
|
|
\[dq]XK_Scroll_Up\[dq] | \[dq]XK_Scroll_Down\[dq] |
|
|
|
|
\[dq]XK_...\[dq] (see /usr/include/X11/keysymdef.h)
|
|
|
|
keyflag ::= \[dq]U\[dq] | \[dq]D\[dq] | \[dq]H\[dq]
|
|
|
|
string ::= \[aq]\[dq]\[aq] { character } \[aq]\[dq]\[aq]
|
|
|
|
\f[R]
|
2018-09-18 00:06:55 +02:00
|
|
|
.fi
|
2018-08-17 01:44:26 +02:00
|
|
|
.SH Bugs
|
|
|
|
.PP
|
|
|
|
There probably are some.
|
|
|
|
Please submit bug reports and pull requests at the midizap git
|
|
|
|
repository (https://github.com/agraef/midizap).
|
2018-08-20 21:50:44 +02:00
|
|
|
Contributions are also welcome.
|
2018-11-16 21:16:00 +01:00
|
|
|
In particular, we\[cq]re looking for interesting configurations to be
|
2018-08-20 21:50:44 +02:00
|
|
|
included in the distribution.
|
2018-08-17 01:44:26 +02:00
|
|
|
.PP
|
2018-08-30 14:46:44 +02:00
|
|
|
The names of some of the debugging options are rather idiosyncratic.
|
2018-11-16 21:16:00 +01:00
|
|
|
midizap inherited them from Eric Messick\[cq]s ShuttlePRO program, and
|
|
|
|
we decided to keep them for backward compatibility.
|
2018-08-20 21:50:44 +02:00
|
|
|
.PP
|
2018-08-18 00:09:48 +02:00
|
|
|
midizap tries to keep things simple, which implies that it has its
|
|
|
|
limitations.
|
2018-09-22 21:21:10 +02:00
|
|
|
In particular, it lacks support for translating system messages and
|
|
|
|
other advanced ways of manipulating MIDI data, and its macro programming
|
|
|
|
capabilities are also rather basic.
|
|
|
|
There are other, more powerful utilities which offer these things, but
|
|
|
|
they are also more complicated and usually require programming skills.
|
2018-09-01 17:13:50 +02:00
|
|
|
Fortunately, midizap often does the job reasonably well for simple
|
2018-08-30 14:46:44 +02:00
|
|
|
mapping tasks (and even some rather complicated ones, such as the
|
2018-09-01 13:21:18 +02:00
|
|
|
APCmini Mackie emulation included in the distribution).
|
2018-09-22 21:21:10 +02:00
|
|
|
But if things start getting too fiddly then you should really consider
|
|
|
|
using a more comprehensive tool such as Pd (http://puredata.info/)
|
|
|
|
instead.
|
2018-09-13 19:37:43 +02:00
|
|
|
.PP
|
|
|
|
midizap has only been tested on Linux so far, and its keyboard and mouse
|
2018-11-16 21:16:00 +01:00
|
|
|
support is tailored to X11, i.e., it\[cq]s pretty much tied to Unix/X11
|
2018-09-13 19:37:43 +02:00
|
|
|
systems right now.
|
2018-11-16 21:16:00 +01:00
|
|
|
Native Mac or Windows support certainly seems possible, but it\[cq]s not
|
|
|
|
going to happen until someone steps in who\[cq]s in the know about
|
|
|
|
suitable Mac and Windows replacements for the X11 XTest extension.
|
2018-08-18 00:09:48 +02:00
|
|
|
.SH See Also
|
|
|
|
.PP
|
2018-08-23 12:17:05 +02:00
|
|
|
midizap is based on a fork (https://github.com/agraef/ShuttlePRO) of
|
2018-11-16 21:16:00 +01:00
|
|
|
Eric Messick\[cq]s ShuttlePRO
|
2018-08-23 12:17:05 +02:00
|
|
|
program (https://github.com/nanosyzygy/ShuttlePRO), which provides
|
2018-08-28 00:02:49 +02:00
|
|
|
similar functionality for the Contour Design Shuttle devices.
|
2018-08-20 07:09:52 +02:00
|
|
|
.PP
|
2018-11-16 21:16:00 +01:00
|
|
|
Spencer Jackson\[cq]s osc2midi
|
|
|
|
utility (https://github.com/ssj71/OSC2MIDI) makes for a great companion
|
|
|
|
to midizap if you also need to convert between MIDI and Open Sound
|
|
|
|
Control (http://opensoundcontrol.org/).
|
2018-08-20 21:50:44 +02:00
|
|
|
.PP
|
2018-08-20 07:09:52 +02:00
|
|
|
The Bome MIDI Translator (https://www.bome.com/products/miditranslator)
|
2018-08-20 21:50:44 +02:00
|
|
|
seems to be a popular MIDI and keystroke mapping tool for Mac and
|
|
|
|
Windows.
|
2018-11-16 21:16:00 +01:00
|
|
|
It is proprietary software and isn\[cq]t available for Linux, but it
|
|
|
|
should be worth a look if you need a midizap alternative which runs on
|
|
|
|
these systems.
|
2018-09-01 17:13:50 +02:00
|
|
|
.SH Authors, License and Credits
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
2018-09-04 07:53:18 +02:00
|
|
|
midizap is free and open source software licensed under the GPLv3,
|
|
|
|
please see the LICENSE file in the distribution for details.
|
2018-08-16 18:34:02 +02:00
|
|
|
.PP
|
|
|
|
Copyright 2013 Eric Messick (FixedImagePhoto.com/Contact)
|
|
|
|
.PD 0
|
|
|
|
.P
|
|
|
|
.PD
|
|
|
|
Copyright 2018 Albert Graef (<aggraef@gmail.com>)
|
|
|
|
.PP
|
2018-11-10 23:46:20 +01:00
|
|
|
midizap is a heavily modified version of the ShuttlePRO program which
|
|
|
|
was written in 2013 by Eric Messick, based on earlier code by Trammell
|
|
|
|
Hudson and Arendt David.
|
2018-08-23 12:17:05 +02:00
|
|
|
All the key and mouse translation features of the original program still
|
|
|
|
work as before, but it goes without saying that the configuration
|
|
|
|
language and the translation code have undergone some substantial
|
|
|
|
changes to accommodate the MIDI input and output facilities.
|
2018-11-16 21:16:00 +01:00
|
|
|
The Jack MIDI backend is based on code from Spencer Jackson\[cq]s
|
|
|
|
osc2midi utility, and on the simple_session_client.c example available
|
|
|
|
in the Jack git repository.
|