1328 lines
53 KiB
Groff
1328 lines
53 KiB
Groff
.\" Automatically generated by Pandoc 2.2.3.2
|
||
.\"
|
||
.TH "midizap" "1" "" "" ""
|
||
.hy
|
||
.SH Name
|
||
.PP
|
||
midizap \[en] control your multimedia applications with MIDI
|
||
.SH Synopsis
|
||
.PP
|
||
midizap [\-h] [\-k] [\-o[2]] [\-j \f[I]name\f[]] [\-r \f[I]rcfile\f[]]
|
||
[\-d[rskmj]]
|
||
.SH Options
|
||
.TP
|
||
.B \-h
|
||
Print a short help message.
|
||
.RS
|
||
.RE
|
||
.TP
|
||
.B \-k
|
||
Keep track of key (on/off) status of MIDI notes and control switches.
|
||
This isn't generally recommended, but may occasionally be useful to deal
|
||
with quirky controllers sending note\- or control\-ons without
|
||
corresponding off messages.
|
||
.RS
|
||
.RE
|
||
.TP
|
||
.B \-o[2]
|
||
Enable MIDI output.
|
||
Add \[lq]2\[rq] for a second pair of MIDI ports to be used, e.g., for
|
||
controller feedback.
|
||
See Sections \f[I]MIDI Output\f[] and \f[I]MIDI Feedback\f[].
|
||
.RS
|
||
.RE
|
||
.TP
|
||
.B \-j \f[I]name\f[]
|
||
Set the Jack client name.
|
||
Default: \[lq]midizap\[rq].
|
||
See Section \f[I]Jack\-Related Options\f[].
|
||
.RS
|
||
.RE
|
||
.TP
|
||
.B \-r \f[I]rcfile\f[]
|
||
Set the configuration file name.
|
||
Default: taken from the MIDIZAP_CONFIG_FILE environment variable if it
|
||
exists, or ~/.midizaprc if it exists, /etc/midizaprc otherwise.
|
||
See Section \f[I]Configuration File\f[].
|
||
.RS
|
||
.RE
|
||
.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 =
|
||
midi (MIDI monitor, print all recognizable MIDI input), j = jack
|
||
(additional Jack debugging output).
|
||
Just \f[C]\-d\f[] enables all debugging options.
|
||
See Section \f[I]Basic Usage\f[].
|
||
.RS
|
||
.RE
|
||
.SH Description
|
||
.PP
|
||
midizap lets you control your favorite multimedia applications using
|
||
MIDI (https://www.midi.org/).
|
||
To these ends, it translates Jack MIDI input into X keystrokes, mouse
|
||
button presses, scroll wheel events, and, as an option, MIDI output.
|
||
It does this by matching the \f[C]WM_CLASS\f[] and \f[C]WM_NAME\f[]
|
||
properties of the window that has the keyboard focus against the regular
|
||
expressions for each application section in its configuration
|
||
(midizaprc) file.
|
||
If a regex matches, the corresponding set of translations is used.
|
||
If a matching section cannot be found, or if it doesn't define a
|
||
suitable translation, the program falls back to a set of translations in
|
||
a default section at the end of the file, if available.
|
||
.PP
|
||
The midizaprc file is just an ordinary text file which you can edit to
|
||
configure the program.
|
||
An example.midizaprc file containing sample configurations for some
|
||
applications is included in the sources.
|
||
Also, in the examples directory you can find some more examples of
|
||
configuration files for various purposes.
|
||
.PP
|
||
midizap provides you with a way to hook up just about any MIDI
|
||
controller to your applications.
|
||
MIDI controllers are readily supported by all major operating systems,
|
||
and are often cheaper and more versatile than special\-purpose input
|
||
devices, so they're always an option to consider, especially if you
|
||
already have one lying around that you'd like to put to good use again.
|
||
Even if your target application already supports MIDI, midizap's MIDI
|
||
output option will be useful if your controller can't work directly with
|
||
the application because of protocol incompatibilities.
|
||
In particular, you can use midizap to turn pretty much any MIDI
|
||
controller with enough faders and buttons into a Mackie\-compatible
|
||
mixing device ready to be used with most DAW (digital audio workstation)
|
||
programs.
|
||
Another common use case is video editing software, which rarely offers
|
||
built\-in MIDI support.
|
||
midizap allows you to map the faders, encoders and buttons of your MIDI
|
||
controller to keyboard commands of your video editor for cutting,
|
||
marking, playback, scrolling, zooming, etc.
|
||
.PP
|
||
In other words, as long as the target application can be controlled with
|
||
simple keyboard shortcuts and/or MIDI commands, chances are that midizap
|
||
can make it work (at least to some extent) with your controller.
|
||
.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
|
||
everything that's needed by running this command:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
sudo\ apt\ install\ build\-essential\ libx11\-dev\ libxtst\-dev\ libjack\-dev
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Then just run \f[C]make\f[] and \f[C]sudo\ make\ install\f[].
|
||
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
|
||
be changed with the \f[C]prefix\f[] variable in the Makefile.
|
||
Also, package maintainers can use the \f[C]DESTDIR\f[] variable as usual
|
||
to install into a staging directory for packaging purposes.
|
||
.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]
|
||
cp\ /etc/midizaprc\ ~/.midizaprc
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
The ~/.midizaprc file, if it exists, takes priority over /etc/midizaprc,
|
||
so it becomes your personal default midizap configuration.
|
||
The midizaprc file included in the distribution is really just an
|
||
example; you're expected to edit this file to adjust the bindings for
|
||
the MIDI controllers and the applications that you use.
|
||
(If you create new configurations which might be useful for others,
|
||
please consider submitting them so that they can be included in future
|
||
releases.)
|
||
.PP
|
||
It is also possible to specify the configuration file to be used, by
|
||
invoking midizap with the \f[C]\-r\f[] option on the command line, e.g.:
|
||
\f[C]midizap\ \-r\ myconfig.midizaprc\f[].
|
||
This is often used with more specialized configurations dealing with
|
||
specific applications or MIDI controllers.
|
||
.PP
|
||
The program automatically reloads the midizaprc file whenever it notices
|
||
that the file has been changed.
|
||
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
|
||
it from the terminal.
|
||
However, it is also possible to launch it from your Jack session manager
|
||
(see \f[I]Jack\-Related Options\f[] below) or from your desktop
|
||
environment's startup files once you've set up everything to your
|
||
liking.
|
||
.PP
|
||
Try \f[C]midizap\ \-h\f[] for a brief summary of the available options
|
||
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.
|
||
While it's possible to do all of that from the command line as well, we
|
||
recommend using a Jack front\-end and patchbay program like
|
||
QjackCtl (https://qjackctl.sourceforge.io/) to manage Jack and to set up
|
||
the MIDI connections.
|
||
In QjackCtl's setup, make sure that you have selected \f[C]seq\f[] as
|
||
the MIDI driver.
|
||
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.
|
||
(Here and in the following, we're assuming that you're using Jack1.
|
||
Jack2 works in a very similar way, but may require some more fiddling;
|
||
in particular, you may have to use
|
||
a2jmidid (http://repo.or.cz/a2jmidid.git) as a separate ALSA\-Jack MIDI
|
||
bridge in order to have the ALSA MIDI devices show properly as Jack MIDI
|
||
devices.)
|
||
.PP
|
||
Having that set up, start Jack, make sure that your MIDI controller is
|
||
connected, and try running \f[C]midizap\f[] from the command line
|
||
(without any arguments).
|
||
In QjackCtl, open the Connections dialog and activate the second tab
|
||
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
|
||
\f[C]midizap\f[] with one MIDI input port named \f[C]midi_in\f[].
|
||
That's the one you need to connect to your MIDI controller, whose output
|
||
port should be visible under the \f[C]alsa_midi\f[] client on the left
|
||
side of the dialog.
|
||
.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]
|
||
|
||
\ C5\ \ \ \ XK_Button_1
|
||
\ D5\ \ \ \ XK_Button_2
|
||
\ E5\ \ \ \ XK_Button_3
|
||
|
||
\ F5\ \ \ \ XK_Left
|
||
\ G5\ \ \ \ XK_Up
|
||
\ A5\ \ \ \ XK_Down
|
||
\ B5\ \ \ \ XK_Right
|
||
|
||
\ CC1+\ \ XK_Scroll_Up
|
||
\ CC1\-\ \ XK_Scroll_Down
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
We refer to Section \f[I]Translation Syntax\f[] below for a discussion
|
||
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
|
||
\f[C]C5\f[] thru \f[C]B5\f[]) to some mouse buttons and cursor commands.
|
||
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.
|
||
Also, moving the modulation wheel (\f[C]CC1\f[]) on your keyboard should
|
||
scroll the window contents up and down.
|
||
.PP
|
||
One useful feature is that you can invoke the program with various
|
||
debugging options to get more verbose output as the program recognizes
|
||
events from the device and translates them to corresponding mouse
|
||
actions or key presses.
|
||
E.g., try running \f[C]midizap\ \-drk\f[] to have the program print the
|
||
recognized configuration sections and translations as they are executed.
|
||
Now press some of the keys and move the modulation wheel.
|
||
You should see something like:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$\ midizap\ \-drk
|
||
Loading\ configuration:\ /home/user/.midizaprc
|
||
translation:\ Default\ for\ emacs\@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[]
|
||
.fi
|
||
.PP
|
||
It goes without saying that these debugging options will be very helpful
|
||
when you start developing your own bindings.
|
||
The \f[C]\-d\f[] option can be combined with various option characters
|
||
to choose exactly which kinds of debugging output you want; \f[C]r\f[]
|
||
(\[lq]regex\[rq]) prints the matched translation section (if any) along
|
||
with the window name and class of the focused window; \f[C]s\f[]
|
||
(\[lq]strokes\[rq]) prints the parsed contents of the configuration file
|
||
in a human\-readable form whenever the file is loaded; \f[C]k\f[]
|
||
(\[lq]keys\[rq]) shows the recognized translations as the program
|
||
executes them, in the same format as \f[C]s\f[]; \f[C]m\f[]
|
||
(\[lq]MIDI\[rq]) prints \f[I]any\f[] MIDI input, so that you can figure
|
||
out which MIDI tokens to use for configuring the translations for your
|
||
controller; and \f[C]j\f[] adds some debugging output from the Jack
|
||
driver.
|
||
You can also just use \f[C]\-d\f[] to enable all debugging output.
|
||
(Most of these options are also available as directives in the midizaprc
|
||
file; please check the distributed example.midizaprc for details.)
|
||
.PP
|
||
Have a look at the distributed midizaprc file for more examples.
|
||
Most of the other translations in the file assume a Mackie\-like device
|
||
with standard playback controls and a jog wheel.
|
||
Any standard DAW controller which can be switched into Mackie mode
|
||
should work with these out of the box.
|
||
There are also some more generic examples, like the one above, which
|
||
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.
|
||
.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.
|
||
MIDI output is enabled by running the program as \f[C]midizap\ \-o\f[].
|
||
This equips the Jack client with an additional MIDI output port named
|
||
\f[C]midi_out\f[] (visible on the left side of QjackCtl's Connection
|
||
window).
|
||
.PP
|
||
The example.midizaprc file comes with a sample configuration in the
|
||
special \f[C][MIDI]\f[] default section for illustration purposes.
|
||
This section is only active if the program is run with the \f[C]\-o\f[]
|
||
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
|
||
You can try it and test that it works by running \f[C]midizap\ \-o\f[],
|
||
firing up a MIDI synthesizer such as
|
||
FluidSynth (http://www.fluidsynth.org/) or its graphical front\-end
|
||
Qsynth (https://qsynth.sourceforge.io/), and employing QjackCtl to
|
||
connect its input it to midizap's output port.
|
||
In the sample configuration, the notes \f[C]C4\f[] thru \f[C]F4\f[] in
|
||
the small octave have been set up so that you can operate a little
|
||
drumkit, and a binding for the volume controller (\f[C]CC7\f[]) has been
|
||
added as well.
|
||
The relevant portion from the configuration entry looks as follows:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
[MIDI]
|
||
|
||
\ C4\ \ \ \ C3\-10
|
||
\ D4\ \ \ \ C#3\-10
|
||
\ E4\ \ \ \ D3\-10
|
||
\ F4\ \ \ \ D#3\-10
|
||
|
||
\ CC7=\ \ CC7\-10
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Note the \f[C]\-10\f[] suffix on the output messages in the above
|
||
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.
|
||
.PP
|
||
E.g., the input note \f[C]C4\f[] is mapped to \f[C]C3\-10\f[], 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[]) at the end of the
|
||
entry sends volume changes to the same drum channel (\f[C]CC7\-10\f[]),
|
||
so that you can use the volume control on your keyboard to dial in the
|
||
volume on the drum channel that you want.
|
||
The program keeps track of the values of both input and output
|
||
controllers on all MIDI channels internally, so with the translations
|
||
above all that happens automagically.
|
||
.PP
|
||
Besides MIDI notes and control change (\f[C]CC\f[]) messages, the
|
||
midizap program also recognizes key and channel pressure (\f[C]KP\f[],
|
||
\f[C]CP\f[]), program change (\f[C]PC\f[]), and pitch bend (\f[C]PB\f[])
|
||
messages, which should cover most common use cases; see below for
|
||
details.
|
||
.SH Translation Syntax
|
||
.PP
|
||
The midizap configuration file consists of sections defining translation
|
||
classes.
|
||
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:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
[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[]
|
||
.fi
|
||
.PP
|
||
The \f[C]#\f[] 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.
|
||
Empty lines and lines containing nothing but whitespace are also
|
||
ignored.
|
||
.PP
|
||
Each \f[C][name]\ regex\f[] line introduces the list of MIDI message
|
||
translations for the named translation class.
|
||
The name is only used for debugging output, and needn't be unique.
|
||
When focus is on a window whose class or title matches the regular
|
||
expression \f[C]regex\f[], the corresponding translations are in effect.
|
||
An empty regex for the last class will always match, allowing default
|
||
translations.
|
||
Any output sequences not bound in a matched section will be loaded from
|
||
the default section if they are bound there.
|
||
.PP
|
||
The translations define what output should be produced for the given
|
||
MIDI input.
|
||
Each translation must be on a line by itself.
|
||
The left\-hand side (first token) of each translation denotes the MIDI
|
||
message to be translated.
|
||
MIDI messages are on channel 1 by default; a suffix of the form
|
||
\f[C]\-<1..16>\f[] can be used to specify a MIDI channel.
|
||
E.g., \f[C]C3\-10\f[] denotes note \f[C]C3\f[] on MIDI channel 10.
|
||
.PP
|
||
Note messages are specified using the customary notation (note name
|
||
\f[C]A..G\f[], optionally followed by an accidental, \f[C]#\f[] or
|
||
\f[C]b\f[], followed by the MIDI octave number).
|
||
The same notation is used for key pressure (\f[C]KP\f[]) messages.
|
||
Note that all MIDI octaves start at the note C, so \f[C]B0\f[] comes
|
||
before \f[C]C1\f[].
|
||
By default, \f[C]C5\f[] denotes middle C.
|
||
Enharmonic spellings are equivalent, so, e.g., \f[C]D#\f[] and
|
||
\f[C]Eb\f[] denote exactly the same MIDI note.
|
||
.PP
|
||
We will go into most of the other syntactic bits and pieces of MIDI
|
||
message designations later, but it's good to have the following grammar
|
||
in EBNF notation handy for reference.
|
||
(To keep things simple, the grammar is somewhat abridged, but it covers
|
||
all the frequently used notation.
|
||
There is some additional syntax for some special forms of translations
|
||
which will be introduced later.)
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
token\ ::=\ msg\ [\ "["\ number\ "]"\ ]\ [\ "\-"\ number\ ]\ [\ incr\ ]
|
||
msg\ \ \ ::=\ (\ note\ |\ other\ )\ [\ number\ ]
|
||
note\ \ ::=\ (\ "A"\ |\ ...\ |\ "G"\ )\ [\ "#"\ |\ "b"\ ]
|
||
other\ ::=\ "CH"\ |\ "PB"\ |\ "PC"\ |\ "CC"\ |\ "CP"\ |\ "KP:"\ note
|
||
incr\ \ ::=\ "\-"\ |\ "+"\ |\ "="\ |\ "<"\ |\ ">"\ |\ "~"
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Case is ignored here, so \f[C]CC\f[], \f[C]cc\f[] or even \f[C]Cc\f[]
|
||
are considered to be exactly the same token by the parser, although by
|
||
convention we usually write them in uppercase.
|
||
Numbers are always integers in decimal.
|
||
The meaning of the first number depends on the context (octave number
|
||
for notes and key pressure, controller or program number in the range
|
||
0..127 for other messages).
|
||
This can optionally be followed by a number in brackets, denoting a
|
||
nonzero step size.
|
||
Also optionally, the suffix with the 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 right\-hand side with \f[C]CH\f[]).
|
||
The optional incr (increment) flag at the end of a token indicates a
|
||
\[lq]data\[rq] translation which responds to incremental (up/down) value
|
||
changes rather than key presses, cf.
|
||
\f[I]Key and Data Input\f[] below.
|
||
.SS Octave Numbering
|
||
.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.
|
||
E.g., there's the ASA (Acoustical Society of America) standard where
|
||
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.
|
||
There's not really a single \[lq]best\[rq] standard here, but the latter
|
||
tends to appeal to mathematically inclined and computer\-savvy people,
|
||
and is also what is used by default in the midizaprc file.
|
||
.PP
|
||
However, you may want to change this, e.g., if you're working with
|
||
documentation or MIDI monitoring software which uses a different
|
||
numbering scheme.
|
||
To do this, just specify the desired offset for the lowest MIDI octave
|
||
with the special \f[C]MIDI_OCTAVE\f[] directive in the configuration
|
||
file.
|
||
For instance:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
MIDI_OCTAVE\ \-1\ #\ ASA\ pitches\ (middle\ C\ is\ C4)
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Note that this transposes \f[I]all\f[] existing notes in translations
|
||
following the directive, so if you add this option to an existing
|
||
configuration, you probably have to edit the note messages in it
|
||
accordingly.
|
||
.SS Key and Data Input
|
||
.PP
|
||
Input messages can be processed in two different ways, \[lq]key
|
||
mode\[rq] and \[lq]data mode\[rq].
|
||
Depending on the mode, the extra data payload of the message, which we
|
||
refer to as the \f[I]parameter value\f[] (or just \f[I]value\f[] for
|
||
short), is interpreted in different ways.
|
||
The parameter value corresponds to the type of MIDI message.
|
||
Program changes have no value at all.
|
||
For notes, as well as key and channel pressure messages, it is the
|
||
velocity value; for control changes, the controller value; and for pitch
|
||
bend messages, the pitch bend value.
|
||
Note that the latter is actually a 14 bit value which is considered as a
|
||
signed quantity in the range \-8192..8191, where 0 denotes the center
|
||
value.
|
||
In all other cases, the parameter value is an unsigned 7 bit quantity in
|
||
the range 0..127.
|
||
(MIDI aficionados will notice that what we call the parameter value
|
||
here, is actually the second data byte, or, in case of pitch bends, the
|
||
combined first and second data byte of the MIDI message.)
|
||
.PP
|
||
\f[I]Key mode\f[] is the default mode and is available for all message
|
||
types.
|
||
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
|
||
For pitch bends, any positive \f[I]or\f[] negative value means
|
||
\[lq]pressed\[rq], while 0 (the center value) means \[lq]released\[rq].
|
||
.IP \[bu] 2
|
||
Since program changes have no parameter value associated with them, they
|
||
don't really have an \[lq]on\[rq] or \[lq]off\[rq] status.
|
||
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
|
||
\f[I]Data mode\f[] is available for all messages whose parameter value
|
||
may continuously change over time, i.e., key and channel pressure,
|
||
control changes, and pitch bends.
|
||
In this mode, the actual \f[I]amount\f[] of change in the value of the
|
||
message (increment or decrement, a.k.a.
|
||
\[lq]up\[rq] or \[lq]down\[rq]) is processed rather than the on/off
|
||
state.
|
||
Data mode is indicated with a special suffix on the message token which
|
||
indicates the direction of the change which the rule should apply to:
|
||
increment (\f[C]+\f[]), decrement (\f[C]\-\f[]), or both (\f[C]=\f[]).
|
||
.PP
|
||
Data mode usually tracks changes in the \f[I]absolute\f[] value of a
|
||
control.
|
||
However, for \f[C]CC\f[] messages there's also an alternative mode for
|
||
so\-called \f[I]incremental\f[] controllers, or \f[I]encoders\f[] for
|
||
short, which can found on some DAW controllers.
|
||
(These usually take the form of jog wheels or rotary encoders which can
|
||
be turned endlessly in either direction.
|
||
In contrast, absolute\-valued controllers are usually faders or knobs
|
||
which are confined to a range between minimum and maximum values.)
|
||
.PP
|
||
Encoders emit a special \f[I]sign bit\f[] value indicating a
|
||
\f[I]relative\f[] change, where a value < 64 usually 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, these kinds of controls are indicated by using
|
||
the suffixes \f[C]<\f[], \f[C]>\f[] and \f[C]~\f[] in lieu of
|
||
\f[C]\-\f[], \f[C]+\f[] and \f[C]=\f[], respectively.
|
||
These suffixes are only permitted with \f[C]CC\f[] messages.
|
||
.PP
|
||
Translations must be determined uniquely in each translation class.
|
||
That is, there must at most be one translation for each MIDI token in
|
||
each translation section.
|
||
Note, however, that the MIDI channel is part of the token, so tokens
|
||
with different MIDI channels count as different messages here.
|
||
The same goes for the mode of a message (key or data), so messages can
|
||
have both key and data translations associated with them (which is
|
||
rarely used in practice, though).
|
||
.SS Keyboard and Mouse Translations
|
||
.PP
|
||
The right\-hand side of a translation (i.e., everything following the
|
||
first token) is a sequence of one or more tokens, separated by
|
||
whitespace, indicating either MIDI messages or X11 keyboard and mouse
|
||
events to be output.
|
||
.PP
|
||
Let's look at keyboard and mouse output first.
|
||
It consists of X key codes with optional up/down indicators, or strings
|
||
of printable characters enclosed in double quotes.
|
||
The syntax of these items, as well as the special \f[C]RELEASE\f[] and
|
||
\f[C]SHIFT\f[] tokens which will be discussed later, are described by
|
||
the following grammar:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
token\ \ \ ::=\ "RELEASE"\ |\ "SHIFT"\ |\ keycode\ [\ "/"\ flag\ ]\ |\ string
|
||
keycode\ ::=\ "XK_Button_1"\ |\ "XK_Button_2"\ |\ "XK_Button_3"\ |
|
||
\ \ \ \ \ \ \ \ \ \ \ \ "XK_Scroll_Up"\ |\ "XK_Scroll_Down"\ |
|
||
\ \ \ \ \ \ \ \ \ \ \ \ "XK_..."\ (X\ keysyms,\ see\ /usr/include/X11/keysymdef.h)
|
||
flag\ \ \ \ ::=\ "U"\ |\ "D"\ |\ "H"
|
||
string\ \ ::=\ \[aq]"\[aq]\ {\ character\ }\ \[aq]"\[aq]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Here, case \f[I]is\f[] significant (except in character strings, see the
|
||
remarks below), so the special \f[C]RELEASE\f[] and \f[C]SHIFT\f[]
|
||
tokens must be in all caps, and the \f[C]XK\f[] symbols need to be
|
||
written in mixed case exactly as they appear in the
|
||
/usr/include/X11/keysymdef.h file.
|
||
Besides the key codes from the keysymdef.h file, there are also some
|
||
special additional key codes to denote mouse button
|
||
(\f[C]XK_Button_1\f[], \f[C]XK_Button_2\f[], \f[C]XK_Button_3\f[]) and
|
||
scroll wheel (\f[C]XK_Scroll_Up\f[], \f[C]XK_Scroll_Down\f[]) events.
|
||
.PP
|
||
Any keycode can be followed by an optional \f[C]/D\f[], \f[C]/U\f[], or
|
||
\f[C]/H\f[] 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[], and
|
||
precede the keycodes they are intended to modify.
|
||
If a sequence requires different sets of modifiers for different
|
||
keycodes, \f[C]/U\f[] can be used to release a modifier that was
|
||
previously pressed with \f[C]/D\f[].
|
||
Sequences may also have separate press and release sequences, separated
|
||
by the special word \f[C]RELEASE\f[].
|
||
Examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
C5\ "qwer"
|
||
D5\ XK_Right
|
||
E5\ XK_Alt_L/D\ XK_Right
|
||
F5\ "V"\ XK_Left\ XK_Page_Up\ "v"
|
||
G5\ XK_Alt_L/D\ "v"\ XK_Alt_L/U\ "x"\ RELEASE\ "q"
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
One pitfall for beginners is that character strings in double quotes are
|
||
just a shorthand for the corresponding X key codes, ignoring case.
|
||
Thus, e.g., \f[C]"abc"\f[] actually denotes the keysym sequence
|
||
\f[C]XK_a\ XK_b\ XK_c\f[], as does \f[C]"ABC"\f[].
|
||
So in either case the \f[I]lowercase\f[] string \f[C]abc\f[] will be
|
||
output.
|
||
To output uppercase letters, it is always necessary to add one of the
|
||
shift modifiers to the output sequence.
|
||
E.g., \f[C]XK_Shift_L/D\ "abc"\f[] will output \f[C]ABC\f[] in
|
||
uppercase.
|
||
.PP
|
||
Translations are handled differently depending on the input mode (cf.
|
||
\f[I]Key and Data Input\f[] above).
|
||
In \f[I]key mode\f[], there are separate press and release sequences.
|
||
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
|
||
by \f[C]/D\f[] will be released, and the last key not marked by
|
||
\f[C]/D\f[], \f[C]/U\f[], or \f[C]/H\f[] will remain pressed.
|
||
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
|
||
marked with \f[C]/D\f[] will be repressed before continuing the
|
||
sequence.
|
||
Keycodes marked with \f[C]/H\f[] remain held between the press and
|
||
release sequences.
|
||
For instance, let's take a look at one of the more conspicuous
|
||
translations in the example above:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
G5\ XK_Alt_L/D\ "v"\ XK_Alt_L/U\ "x"\ RELEASE\ "q"
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
When the \f[C]G5\f[] key is pressed on the MIDI keyboard, the key
|
||
sequence \f[C]Alt+v\ x\f[] is initiated, keeping the \f[C]x\f[] key
|
||
pressed (so it may start auto\-repeating after a while).
|
||
The program then sits there waiting (possibly executing other
|
||
translations) until you release the \f[C]G5\f[] key again, at which
|
||
point the \f[C]x\f[] key is released and the \f[C]q\f[] key is pressed
|
||
(and released).
|
||
.PP
|
||
In contrast, in \f[I]data mode\f[] only a single sequence is output
|
||
whenever the message value increases or decreases.
|
||
At the end of the sequence, all down keys will be released.
|
||
For instance, the following translations move the cursor left or right
|
||
whenever the volume controller (\f[C]CC7\f[]) decreases and increases,
|
||
respectively.
|
||
Also, the number of times one of these keys is output corresponds to the
|
||
actual change in the value.
|
||
Thus, if in the example \f[C]CC7\f[] increases by 4, say, the program
|
||
will press (and release) \f[C]XK_Right\f[] four times, moving the cursor
|
||
4 positions to the right.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC7\-\ XK_Left
|
||
CC7+\ XK_Right
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Incremental \f[C]CC\f[] messages are treated in an analogous fashion,
|
||
but in this case the increment or decrement is determined directly by
|
||
the input message.
|
||
One example for this type of controller is the jog wheel on the Mackie
|
||
MCU, which can be processed as follows (using \f[C]<\f[] and \f[C]>\f[]
|
||
in lieu of \f[C]\-\f[] and \f[C]+\f[] as the suffix of the \f[C]CC\f[]
|
||
message):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC60<\ XK_Left
|
||
CC60>\ XK_Right
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
(The corresponding \[lq]bidirectional\[rq] translations, which are
|
||
indicated with the \f[C]=\f[] and \f[C]~\f[] suffixes, are rarely used
|
||
with keyboard and mouse translations.
|
||
Same goes for the special \f[C]SHIFT\f[] token.
|
||
Thus we'll discuss these in later sections, see \f[I]MIDI
|
||
Translations\f[] and \f[I]Shift State\f[] below.)
|
||
.PP
|
||
In data mode, input messages can also have a \f[I]step size\f[]
|
||
associated with them, which enables you to scale down changes in the
|
||
parameter value.
|
||
The default step size is 1 (no scaling).
|
||
To change it, the desired step size is written in brackets immediately
|
||
after the message token to be translated, but before the increment
|
||
suffix.
|
||
A step size \f[I]k\f[] indicates that the translation is executed
|
||
whenever the input value has changed by \f[I]k\f[] units.
|
||
For instance, to slow down the cursor movement in the example above by a
|
||
factor of 4:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC7[4]\-\ XK_Left
|
||
CC7[4]+\ XK_Right
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Note that there is no step size with input messages in (standard) key
|
||
mode.
|
||
The message is either just \[lq]on\[rq] or \[lq]off\[rq], with any
|
||
nonzero value denoting off.
|
||
There is a special variation of key mode which has a step size
|
||
associated with it, but it functions differently.
|
||
As these translations are somewhat esoteric and mostly used with MIDI
|
||
feedback generated by the host application, we'll have a look at them
|
||
later, see the \f[I]MIDI Feedback\f[] section near the end of the
|
||
manual.
|
||
.SS MIDI Translations
|
||
.PP
|
||
Most of the notation for MIDI messages on the left\-hand side of a
|
||
translation rule also carry over to the output side.
|
||
The only real difference is that the increment suffixes \f[C]+\-=<>\f[]
|
||
aren't permitted here, as they are only used to determine the input mode
|
||
(key or data) of the entire translation.
|
||
(The \f[C]~\f[] suffix \f[I]is\f[] allowed, however, to indicate output
|
||
in incremental bit\-sign format in data translations, see below.)
|
||
.PP
|
||
The output sequence can involve as many MIDI messages as you want, and
|
||
these can be combined freely with keyboard and mouse events in any
|
||
order.
|
||
However, as already discussed in Section \f[I]MIDI Output\f[] above, you
|
||
need to invoke the midizap program with the \f[C]\-o\f[] option to make
|
||
MIDI output work.
|
||
Otherwise, MIDI messages in the output translations will just be
|
||
silently ignored.
|
||
.PP
|
||
There is one special MIDI token \f[C]CH\f[] which can only be used on
|
||
the output side.
|
||
The \f[C]CH\f[] token, which is followed by a MIDI channel number in the
|
||
range 1..16, doesn't actually generate any MIDI message, but merely sets
|
||
the default MIDI channel for subsequent MIDI messages in the same output
|
||
sequence.
|
||
This 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[], which outputs a
|
||
C major chord on MIDI channel 2, can also be abbreviated as
|
||
\f[C]CH2\ C5\ E5\ G5\f[].
|
||
.PP
|
||
For key\-mode inputs, the corresponding \[lq]on\[rq] or \[lq]off\[rq]
|
||
event is generated for all MIDI messages in the output sequence, where
|
||
the \[lq]on\[rq] value defaults to the maximum value (127 for controller
|
||
values, 8191 for pitch bends).
|
||
Thus, e.g., the following rule outputs a \f[C]CC80\f[] message with
|
||
controller value 127 each time middle C (\f[C]C5\f[]) is pressed (and
|
||
another \f[C]CC80\f[] message with value 0 when the note is released
|
||
again):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
C5\ CC80
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
The value for the \[lq]on\[rq] state can also be denoted explicitly with
|
||
a step size:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
C5\ CC80[64]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
For pitch bends, the step size can also be negative.
|
||
For instance, the following rules assign two keys to bend down and up by
|
||
the maximum amount possible:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
C2\ PB[\-8192]\ #\ bend\ down
|
||
D2\ PB[8191]\ \ #\ bend\ up
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
There are two additional suffixes \f[C]=\f[] and \f[C]~\f[] for data
|
||
translations which are most useful with pure MIDI translations, which is
|
||
why we deferred their discussion until now.
|
||
If the increment and decrement sequences for a given translation are the
|
||
same, the \f[C]=\f[] suffix can be used to indicate that this sequence
|
||
should be output for \f[I]both\f[] increments and decrements.
|
||
For instance, to map the modulation wheel (\f[C]CC1\f[]) to the volume
|
||
controller (\f[C]CC7\f[]):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC1=\ CC7
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Which is exactly the same as the two translations:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC1+\ CC7
|
||
CC1\-\ CC7
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
The same goes for \f[C]<\f[], \f[C]>\f[] and \f[C]~\f[] with sign\-bit
|
||
encoders:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC60~\ CC7
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Which is equivalent to:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC60<\ CC7
|
||
CC60>\ CC7
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
The \f[C]~\f[] suffix can be used to denote incremental controllers in
|
||
output messages, too.
|
||
E.g., to translate a standard (absolute) MIDI controller to an
|
||
incremental encoder value, you might use a rule like:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC48=\ CC16~
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Step sizes also work on the right\-hand side of data translations.
|
||
You might use these to scale up value changes, e.g., when translating
|
||
from control changes to pitch bends:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC1=\ PB[128]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
The step size can also be negative, which allows you to reverse the
|
||
direction of a controller if needed.
|
||
E.g., the following will output values going down from 127 to 0 as input
|
||
values go up from 0 to 127:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC1=\ CC1[\-1]
|
||
\f[]
|
||
.fi
|
||
.SS Shift State
|
||
.PP
|
||
The special \f[C]SHIFT\f[] token toggles an internal shift state, which
|
||
can be used to generate alternative output for certain MIDI messages.
|
||
Please note that, like the \f[C]CH\f[] token, the \f[C]SHIFT\f[] token
|
||
doesn't generate any output by itself; it merely toggles the internal
|
||
shift bit which can then be queried in other translations to distinguish
|
||
between shifted and unshifted bindings for the same input message.
|
||
.PP
|
||
To these ends, there are two additional prefixes which indicate the
|
||
shift status in which a translation is active.
|
||
Unprefixed translations are active only in unshifted state.
|
||
The \f[C]^\f[] prefix denotes a translation which is active only in
|
||
shifted state, while the \f[C]?\f[] prefix indicates a translation which
|
||
is active in \f[I]both\f[] shifted and unshifted state.
|
||
.PP
|
||
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.
|
||
E.g., to bind the shift key (\f[C]A#5\f[]) on a Mackie controller:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
?A#5\ SHIFT
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Note the \f[C]?\f[] prefix indicating that this translation is active in
|
||
both unshifted and shifted state, so it is used to turn shift state both
|
||
on and off, giving a \[lq]Caps Lock\[rq]\-style of toggle key.
|
||
If you'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:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
?A#5\ SHIFT\ RELEASE\ SHIFT
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Having set up the translation for the shift key itself, we can now
|
||
indicate that a translation should be valid only in shifted state with
|
||
the \f[C]^\f[] prefix.
|
||
This makes it possible to assign, depending on the shift state,
|
||
different functions to buttons and faders.
|
||
Here's a typical example which maps a control change to either
|
||
Mackie\-style fader values encoded as pitch bends, or incremental
|
||
encoder values:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
\ CC48=\ PB[128]\ \ #\ translate\ to\ pitch\ bend\ when\ unshifted
|
||
^CC48=\ CC16~\ \ \ \ #\ translate\ to\ encoder\ when\ shifted
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
To keep things simple, only one shift status is available in the present
|
||
implementation.
|
||
Also note that when using a shift key in the manner described above, its
|
||
status is \f[I]only\f[] available internally to the midizap program; the
|
||
host application never gets to see it.
|
||
If your host software does its own handling of shift keys (as most
|
||
Mackie\-compatible DAWs do), it's usually more convenient to simply pass
|
||
those keys on to the application.
|
||
However, \f[C]SHIFT\f[] comes in handy if your controller simply doesn't
|
||
have enough buttons and faders to control all the essential features of
|
||
your target application.
|
||
In this case the internal shift feature makes it possible to double the
|
||
amount of controls available on the device.
|
||
For instance, you can emulate a Mackie controller with both encoders and
|
||
faders on a device which only has a single set of faders, by assigning
|
||
the shifted faders to the encoders, as shown above.
|
||
.SH Jack\-Related Options
|
||
.PP
|
||
There are some additional directives (and corresponding command line
|
||
options) to set midizap's Jack client name and the number of input and
|
||
output ports it uses.
|
||
(If both the command line options and directives in the midizaprc file
|
||
are used, the former take priority, so that it's always possible to
|
||
override the options in the midizaprc file from the command line.)
|
||
.PP
|
||
Firstly, there's the \f[C]\-j\f[] option and the \f[C]JACK_NAME\f[]
|
||
directive which change the Jack client name from the default
|
||
(\f[C]midizap\f[]) to whatever you want it to be.
|
||
To use this option, simply invoke midizap as
|
||
\f[C]midizap\ \-j\ client\-name\f[], or put the following directive into
|
||
your midizaprc file:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
JACK_NAME\ "client\-name"
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
This option is useful, in particular, if you're running multiple
|
||
instances of midizap with different configurations for different
|
||
controllers and/or target applications, and you want to have the
|
||
corresponding Jack clients named appropriately, so that they can be
|
||
identified more easily when wiring them up.
|
||
If you're using a persistent MIDI patchbay, such as the one available in
|
||
QjackCtl, you can then have the right connections automatically set up
|
||
for you whenever you launch midizap with that specific configuration.
|
||
.PP
|
||
Secondly, we've already seen the \f[C]\-o\f[] 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[] directive in the
|
||
midizaprc file, as follows:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
JACK_PORTS\ 1
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
You may want to place this directive directly into a configuration file
|
||
if the configuration is primarily aimed at doing MIDI translations, so
|
||
you'd like to have the MIDI output enabled by default.
|
||
Typically, such configurations will include just a default
|
||
\f[C][MIDI]\f[] section and little else.
|
||
As explained below, it's also possible to have \f[I]two\f[] pairs of
|
||
input and output ports, in order to deal with controller feedback from
|
||
the application.
|
||
This is achieved by either invoking midizap with the \f[C]\-o2\f[]
|
||
option, or by employing the \f[C]JACK_PORTS\ 2\f[] directive in the
|
||
configuration file.
|
||
.PP
|
||
Last but not least, midizap also supports Jack session management, which
|
||
makes it possible to record the options the program was invoked with,
|
||
along with all the MIDI connections.
|
||
This feature can be used with any Jack session management software.
|
||
Specifically, QjackCtl has its own built\-in Jack session manager which
|
||
is available in its Session dialog.
|
||
To use this, launch midizap and any other Jack applications you want to
|
||
have in the session, use QjackCtl to set up all the connections as
|
||
needed, and then hit the \[lq]Save\[rq] (or \[lq]Save and Quit\[rq])
|
||
button in the Session dialog to have the session recorded.
|
||
Now, at any later time you can relaunch the same session with the
|
||
\[lq]Load\[rq] (or \[lq]Recent\[rq]) button in the same dialog.
|
||
.SH MIDI Feedback
|
||
.PP
|
||
Some MIDI controllers need a more elaborate setup than what we'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[] option of midizap,
|
||
or the \f[C]JACK_PORTS\ 2\f[] directive in the midizaprc file, to create
|
||
a second pair of MIDI input and output ports, named \f[C]midi_in2\f[]
|
||
and \f[C]midi_out2\f[].
|
||
Use of this option also activates a second MIDI default section in the
|
||
midizaprc file, labeled \f[C][MIDI2]\f[], which is used exclusively for
|
||
translating MIDI input from the second input port and sending the
|
||
resulting MIDI output to the second output port.
|
||
Typically, the translations in the \f[C][MIDI2]\f[] section will be the
|
||
inverse of those in the \f[C][MIDI]\f[] 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's \f[C]midi_in\f[] and \f[C]midi_out\f[] ports
|
||
to controller and application as before, but in addition you also
|
||
connect the application back to midizap's \f[C]midi_in2\f[] port, and
|
||
the \f[C]midi_out2\f[] port to the controller.
|
||
This reverse path is what is needed to translate the feedback from the
|
||
application and send it back to the controller.
|
||
A full\-blown example for this kind of setup can be found in
|
||
examples/APCmini.midizaprc in the sources, which shows how to emulate a
|
||
Mackie controller with AKAI's APCmini device, so that it readily works
|
||
with DAW software such as Ardour.
|
||
.SS Specialized Key Translations for MIDI Feedback
|
||
.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.
|
||
However, there are some encodings of MIDI messages employed in feedback,
|
||
such as time and meter displays, which combine different bits of
|
||
information in a single message, making them difficult or even
|
||
impossible to translate using the simple kinds of rules we've seen so
|
||
far.
|
||
.PP
|
||
midizap offers a special variation of key mode to help decoding at least
|
||
some of these special messages.
|
||
For reasons which will become obvious in a moment, we also call these
|
||
\f[I]mod key translations\f[], or just \f[I]mod translations\f[] for
|
||
short.
|
||
The extended MIDI syntax being used here is described by the following
|
||
grammar rules (please refer to the beginning of Section \f[I]Translation
|
||
Syntax\f[] for the parts of the syntax not explicitly defined here):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
token\ ::=\ msg\ [\ steps\ ]\ [\ "\-"\ number]
|
||
steps\ ::=\ "["\ list\ "]"\ |\ "["\ number\ "]"\ "["\ list\ "]"
|
||
list\ \ ::=\ number\ {\ ","\ number\ |\ ":"\ number\ }
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
To explain the meaning of these translations, we take the mapping of
|
||
channel pressure to notes as a running example here.
|
||
But the same works with any kind of message having a parameter value
|
||
(i.e., anything but \f[C]PC\f[]).
|
||
In its most basic form, the translation looks as follows:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CP[16]\ C0
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
This looks like a key translation with a step size, but is treated
|
||
differently.
|
||
Firstly, there are no separate press and release sequences like in other
|
||
key translations, only a single output sequence.
|
||
Thus, like in data mode, all down keys will be released immediately
|
||
(there aren't any in this example, but in general, all kinds of output
|
||
events are allowed, like in other translations).
|
||
Secondly, there's no \[lq]on\[rq]/\[lq]off\[rq] status here to determine
|
||
the output values either.
|
||
Rather, the output messages are constructed directly from the input
|
||
value by some arithmetic calculations.
|
||
To these ends, the step size actually denotes a \f[I]modulus\f[] which
|
||
is used to decompose the input value into two separate quantities,
|
||
\f[I]quotient\f[] and \f[I]remainder\f[].
|
||
Only the latter becomes the value of the output message, while the
|
||
former is used as an \f[I]offset\f[] to modify the output message.
|
||
.PP
|
||
More precisely, the input value \f[I]v\f[], say, is divided by the given
|
||
step size \f[I]k\f[], yielding the offset \f[I]p\f[] = \f[I]v/k\f[]
|
||
(rounded down to the nearest integer), and the remainder \f[I]q\f[] of
|
||
that division.
|
||
E.g., with \f[I]k\f[] = 16 and \f[I]v\f[] = 21, you'll get \f[I]p\f[] =
|
||
1 and \f[I]q\f[] = 5 (21 divided by 16 yields 1 with remainder 5,
|
||
because 16×1 + 5 = 21).
|
||
The offset \f[I]p\f[] is then applied to the note itself, and the
|
||
remainder \f[I]q\f[] becomes the velocity of that note.
|
||
So in the example the output would be the note \f[C]C#0\f[] (\f[C]C0\f[]
|
||
offset by 1) with a velocity of 5.
|
||
.PP
|
||
The above might seem a bit esoteric, but this is in fact exactly how you
|
||
decode meter information in the Mackie control protocol, which consists
|
||
of a mixer channel index 0..7 in the high nibble (bits 4..6) and the
|
||
corresponding meter value in the low nibble (bits 0..3) of a key
|
||
pressure message, which is why we use 16 as the modulus here.
|
||
There are also some variations of the syntax which make this kind of
|
||
translation more flexible.
|
||
In particular, on the right\-hand side of the rule you can specify a
|
||
step size if the remainder value needs to be scaled:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CP[16]\ C0[2]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Or you can specify a list of discrete velocity values instead.
|
||
E.g., the APCmini uses the velocities 1, 3 and 5 to denote the colors
|
||
green, red and yellow, respectively, and a zero velocity denotes
|
||
\[lq]off\[rq], so you can encode the meter value in different colors,
|
||
like so:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CP[16]\ C0[0,1,1,1,1,5,5,5,3]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
There are a lot of repeated values there.
|
||
For convenience, it's also possible to abbreviate these with the colon,
|
||
which also improves readability:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CP[16]\ C0[0,1:4,5:3,3]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
This denotes exactly the same list.
|
||
Also note that when using discrete value lists, the remainder of the
|
||
input value will be used as an index into the list, and the last value
|
||
in the list will be used for any index which runs past the end of the
|
||
list.
|
||
Thus in the above example, if for some reason you'd receive a meter
|
||
value of 10, say, the output will still be 3, since it's the last value
|
||
in the list.
|
||
.PP
|
||
You can also scale the \f[I]offset\f[] value, by adding a second step
|
||
size to the left\-hand side:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CP[16][8]\ C0[0,1:4,5:3,3]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Now, a channel pressure value of 24 (denoting a meter value of 8 on the
|
||
second mixer channel) will output the note \f[C]A0\f[] (\f[C]C0\f[]
|
||
offset by 8) with velocity 3, which on the APCmini will light up the
|
||
first LED in the second row in red.
|
||
Instead of a single step size, it's also possible to specify a list of
|
||
discrete offset values, so that you can achieve any regular or irregular
|
||
output pattern that you like:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CP[16][1,8,17,24]\ C0[0,1:4,5:3,3]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
You might also output several notes at once, to show a horizontal or
|
||
vertical strip of LEDs for each mixer channel.
|
||
For instance, suppose that we'd like to use an LED in the bottom row of
|
||
the APCmini for the green, and the LEDs in the two rows above it for the
|
||
yellow and red values, respectively, you can do that as follows:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CP[16]\ C0[0,1]\ G#0[0:5,5]\ E1[0:8,3]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Note that in this case each of the output notes will be offset by the
|
||
same amount, so that an input value of 24 will cause the second LED in
|
||
the bottom row to light up in green, and the two LEDs above it in yellow
|
||
and red, respectively.
|
||
Please also have a look at the APCmini.midizaprc example which has a
|
||
collection of similar rules to implement the meter display.
|
||
.PP
|
||
It goes without saying that this is not a universal solution, but it
|
||
handles at least one important real\-world use case, and should work
|
||
with almost any other kind of \[lq]scrambled\[rq] MIDI feedback which
|
||
packs two separate values together.
|
||
The case of Mackie meter feedback certainly seemed important enough, and
|
||
was easy to support without complicating the syntax too much.
|
||
Although we try to keep midizap lean and mean, we might add some more
|
||
special\-case key translations like these in the future.
|
||
.SS Other Uses of Mod Translations
|
||
.PP
|
||
The mod key translations explained above work with all other kinds of
|
||
output events, too, so that you can also output X11 key and mouse events
|
||
and \f[C]PC\f[] messages along with the transformed MIDI data if needed;
|
||
these won't be modified, however.
|
||
Also note that if you use \f[C]CP\f[] and \f[C]PB\f[] messages on the
|
||
output side, which don't have a modifiable offset, the offset part of
|
||
the input value will be ignored for these messages; only the remainder
|
||
part will be used, becoming the output value of the message.
|
||
.PP
|
||
Of course, mod translations can also be used for other purposes, not
|
||
just MIDI feedback.
|
||
The input message may be anything which has a parameter value, i.e., any
|
||
MIDI message but \f[C]PC\f[].
|
||
You can also choose the modulus large enough (8192 for \f[C]PB\f[], 128
|
||
for other messages) so that the offset is always zero, if you just want
|
||
to employ the discrete value lists for your translations.
|
||
These offer a great deal of flexibility, more than can be achieved with
|
||
simple step sizes.
|
||
In fact, they can be used to realize just about any mapping between
|
||
input and output values.
|
||
For instance, suppose that we'd like to map controller values to the the
|
||
first few Fibonacci numbers:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC1[128]\ CC1[0,1,1,2,3,5,8,13,21,34,55,89]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
You can also use a modulus of 1 if you'd like to map, say, controller
|
||
values to note \f[I]numbers\f[] (rather than velocities):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC1[1]\ C0
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
This will output the note with the same number as the controller value,
|
||
\f[C]C0\f[] for value 0, \f[C]C#0\f[] for value 1, etc.
|
||
Note that the remainder value, which becomes the velocity of the output
|
||
note in this case, will always be zero here, so if you want a nonzero
|
||
velocity, you will have to specify a value list for that:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
CC1[1]\ C0[127:1]
|
||
\f[]
|
||
.fi
|
||
.PP
|
||
Note that we added a repeat count in the list on the right\-hand side,
|
||
so that the parser recognizes it as a value list rather than a simple
|
||
step size (which wouldn't help much since the remainder value to be
|
||
scaled is always zero here).
|
||
.SH Bugs
|
||
.PP
|
||
There probably are some.
|
||
Please submit bug reports and pull requests at the midizap git
|
||
repository (https://github.com/agraef/midizap).
|
||
Contributions are also welcome.
|
||
In particular, we're looking for interesting configurations to be
|
||
included in the distribution.
|
||
.PP
|
||
The names of some of the debugging options are rather peculiar.
|
||
midizap inherited them from Eric Messick's ShuttlePRO program on which
|
||
midizap is based, so they'll probably last until someone comes up with
|
||
something better.
|
||
.PP
|
||
There's no Mac or Windows support (yet).
|
||
midizap has only been tested on Linux so far, and its keyboard and mouse
|
||
support is tailored to X11, i.e., it's pretty much tied to Unix/X11
|
||
systems right now.
|
||
.PP
|
||
midizap tries to keep things simple, which implies that it has its
|
||
limitations.
|
||
In particular, system messages are not supported right now, and midizap
|
||
lacks some more interesting ways of mapping, filtering and recombining
|
||
MIDI data.
|
||
There are other, more powerful utilities which do these things, but they
|
||
are also more complicated and usually require at least some programming
|
||
skills.
|
||
midizap often does the job reasonably well for simple mapping tasks, but
|
||
if things start getting fiddly then you should consider using a more
|
||
comprehensive tool like Pd (http://puredata.info/) instead.
|
||
.SH See Also
|
||
.PP
|
||
midizap is based on a fork (https://github.com/agraef/ShuttlePRO) of
|
||
Eric Messick's ShuttlePRO
|
||
program (https://github.com/nanosyzygy/ShuttlePRO), which provides
|
||
pretty much the same functionality for the Contour Design Shuttle
|
||
devices.
|
||
.PP
|
||
Spencer Jackson's osc2midi (https://github.com/ssj71/OSC2MIDI) utility
|
||
makes for a great companion to midizap if you also need to convert
|
||
between MIDI and Open Sound Control (http://opensoundcontrol.org/).
|
||
.PP
|
||
The Bome MIDI Translator (https://www.bome.com/products/miditranslator)
|
||
seems to be a popular MIDI and keystroke mapping tool for Mac and
|
||
Windows.
|
||
It is proprietary software and isn't available for Linux, but it should
|
||
be worth a look if you need a midizap alternative which runs on these
|
||
systems.
|
||
.SH Authors
|
||
.PP
|
||
midizap is free and open source software licensed under the GPLv3,
|
||
please check the accompanying LICENSE file for details.
|
||
.PP
|
||
Copyright 2013 Eric Messick (FixedImagePhoto.com/Contact)
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Copyright 2018 Albert Graef (<aggraef@gmail.com>)
|
||
.PP
|
||
This is a version of Eric Messick's ShuttlePRO program which has been
|
||
redesigned to work with Jack MIDI instead of the Contour Design Shuttle
|
||
devices.
|
||
ShuttlePRO was written in 2013 by Eric Messick, based on earlier code by
|
||
Trammell Hudson and Arendt David.
|
||
The MIDI support was added by Albert Graef.
|
||
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.
|
||
The Jack MIDI backend is based on code from Spencer Jackson's osc2midi
|
||
utility, and on the simple_session_client.c example available in the
|
||
Jack git repository.
|