959 lines
39 KiB
Groff
959 lines
39 KiB
Groff
.\" Automatically generated by Pandoc 2.2.2.1
|
|
.\"
|
|
.TH "midizap" "1" "" "" ""
|
|
.hy
|
|
.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]Secondary MIDI Ports\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
|
|
The midizap program translates Jack MIDI input into X keystrokes, mouse
|
|
button presses, scroll wheel events, or, 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.
|
|
Otherwise 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 for use with any kind of application taking
|
|
keyboard, mouse or MIDI input.
|
|
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 favorite multimedia applications, like digital audio
|
|
workstation (DAW) programs, as well as audio and video editors.
|
|
The MIDI output option is useful if the target application supports
|
|
MIDI, but can't work directly with your controller 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 for DAW programs.
|
|
Another common use case is video editing software, which rarely offers
|
|
built\-in MIDI controller support.
|
|
midizap allows you to map the faders, encoders and buttons of your MIDI
|
|
controller to corresponding keyboard commands of your video software for
|
|
cutting, marking, playback, scrolling and zooming.
|
|
.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 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.
|
|
You can edit this file as you see fit, in order to customize existing or
|
|
add your own application configurations, adjust the bindings for the
|
|
MIDI controllers that you have, etc.
|
|
(If you create any 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
|
|
\f[B]NOTE:\f[] 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, but of course it is also possible to invoke it
|
|
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.
|
|
.PP
|
|
(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.
|
|
Otherwise, editing the configuration to make the translations work with
|
|
your controller should be a piece of cake.
|
|
.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
|
|
Please see Section \f[I]Translation Syntax\f[] below for a more detailed
|
|
explanation of the syntax used in the configuration file.
|
|
Besides MIDI notes and control change (\f[C]CC\f[]) messages, the
|
|
midizap program also recognizes program change (\f[C]PC\f[]) and pitch
|
|
bend (\f[C]PB\f[]) messages, which should cover most common use cases.
|
|
Other messages (in particular, aftertouch and system messages) are not
|
|
supported right now, but may be added in the future.
|
|
.SH Translation Syntax
|
|
.PP
|
|
\f[C]#\f[] after whitespace (or at the beginning of a line) indicates
|
|
that the rest of the line is a comment.
|
|
.PP
|
|
The midizap configuration file is a sequence of sections defining
|
|
translation classes.
|
|
Each section looks like this (\f[C]<X..Y>\f[] indicates ranges of
|
|
permitted values, \f[C][...]\f[] optional parts, and \f[C]output\f[]
|
|
denotes the output sequence):
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[name]\ regex
|
|
CC<0..127>\ output\ \ \ \ \ \ \ \ \ \ \ #\ control\ change
|
|
PC<0..127>\ output\ \ \ \ \ \ \ \ \ \ \ #\ program\ change
|
|
PB\ output\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ pitch\ bend
|
|
<A..G>[#b]<\-11..11>\ output\ \ #\ note
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
When focus is on a window whose class or title matches the regular
|
|
expression \f[C]regex\f[], the following translation class is 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
|
|
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.
|
|
The following lines indicate what output should be produced for the
|
|
given MIDI messages.
|
|
.PP
|
|
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 different 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.
|
|
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
|
|
messages in translations later, but it's good to have the following
|
|
grammar in EBNF notation handy for reference:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
tok\ \ ::=\ (\ note\ |\ msg\ )\ [\ number\ ]\ [\ "["\ number\ "]"\ ]
|
|
\ \ \ \ \ \ \ \ \ [\ "\-"\ number]\ [\ incr\ ]
|
|
note\ ::=\ (\ "a"\ |\ ...\ |\ "g"\ )\ [\ "#"\ |\ "b"\ ]
|
|
msg\ \ ::=\ "ch"\ |\ "pb"\ |\ "pc"\ |\ "cc"
|
|
incr\ ::=\ "\-"\ |\ "+"\ |\ "="\ |\ "<"\ |\ ">"\ |\ "~"
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
Case is insignificant.
|
|
Numbers are always integers in decimal.
|
|
The meaning of the first number depends on the context (octave number
|
|
for notes, 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 flag at the end of a token indicates an
|
|
\[lq]incremental\[rq] controller or pitch bend value which responds to
|
|
numeric (up/down) changes rather than key presses, cf.
|
|
\f[I]On/Off vs.\ Incremental Changes\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, if you prefer a different numbering scheme then you can easily
|
|
change this by specifying 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
|
|
This is useful, in particular, if you use some external MIDI monitoring
|
|
software to figure out which notes to put into your midizaprc file.
|
|
To these ends, just check how the program prints middle C, and adjust
|
|
the \f[C]MIDI_OCTAVE\f[] offset in your midizaprc file accordingly.
|
|
(Note that midizap's built\-in MIDI monitoring facility always prints
|
|
out MIDI notes using the \f[C]MIDI_OCTAVE\f[] offset that is in effect.
|
|
Thus in this case the printed note tokens will always be in exactly the
|
|
form that is to be used in the midizaprc file, no matter what the
|
|
\f[C]MIDI_OCTAVE\f[] offset happens to be.)
|
|
.SS On/Off vs.\ Incremental Changes
|
|
.PP
|
|
By default, all MIDI messages on the left\-hand side of a rule are
|
|
interpreted in the same way as keys on a computer keyboard, i.e., they
|
|
can be \[lq]on\[rq] (\[lq]pressed\[rq]) or \[lq]off\[rq]
|
|
(\[lq]released\[rq]).
|
|
For notes, a nonzero velocity means \[lq]pressed\[rq], zero
|
|
\[lq]released\[rq].
|
|
Similarly, for control changes any nonzero value indicates
|
|
\[lq]pressed\[rq].
|
|
Same goes for pitch bends, but in this case 0 denotes the center value
|
|
(considering pitch bend values as signed quantities in the range
|
|
\-8192..8191).
|
|
Again, any nonzero (positive or negative) value means \[lq]pressed\[rq],
|
|
and 0 (the center value) \[lq]released\[rq].
|
|
Finally, while program changes don't actually come in
|
|
\[lq]on\[rq]/\[lq]off\[rq] pairs, they are treated in the same key\-like
|
|
fashion, assuming that they are \[lq]pressed\[rq] and then
|
|
\[lq]released\[rq] immediately afterwards.
|
|
.PP
|
|
\f[C]CC\f[] (control change) and \f[C]PB\f[] (pitch bend) input messages
|
|
can also be marked with a trailing \f[C]+\f[] or \f[C]\-\f[] in the
|
|
left\-hand side of a translation.
|
|
This changes their meaning, so that they are used to report incremental
|
|
(up and down) changes of the controller or pitch bend value instead of
|
|
key presses.
|
|
.SS Key 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 (symbolic constants prefixed with
|
|
\f[C]XK_\f[] from the /usr/include/X11/keysymdef.h file) with optional
|
|
up/down indicators, or strings of printable characters enclosed in
|
|
double quotes.
|
|
Also, there are some special keycodes 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.
|
|
Sequences may have separate press and release sequences, separated by
|
|
the special word \f[C]RELEASE\f[].
|
|
.PP
|
|
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
|
|
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.
|
|
.PP
|
|
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[].
|
|
.PP
|
|
By default, MIDI messages translate to separate press and release
|
|
sequences.
|
|
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.
|
|
.PP
|
|
When marking \f[C]CC\f[] (control change) and \f[C]PB\f[] (pitch bend)
|
|
input messages with a trailing \f[C]+\f[] or \f[C]\-\f[] in the
|
|
left\-hand side of a translation, they are interpreted as
|
|
\f[I]incremental changes\f[] instead.
|
|
Instead of providing separate press and release sequences, the output of
|
|
such translations is executed whenever the controller increases or
|
|
decreases, respectively.
|
|
At the end of such sequences, all down keys will be released.
|
|
For instance, the following translations output the letter \f[C]"a"\f[]
|
|
whenever the volume controller (\f[C]CC7\f[]) is increased, and the
|
|
letter \f[C]"b"\f[] if it is decreased.
|
|
Also, the number of times one of these keys is output corresponds to the
|
|
actual change in the controller value.
|
|
(Thus, if in the example \f[C]CC7\f[] increases by 32, say, 32
|
|
\f[C]"a"\f[]s will be output.)
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
CC7+\ "a"
|
|
CC7+\ "b"
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
\f[C]CC\f[] also has an alternative incremental mode which handles
|
|
\f[I]relative control changes\f[] encoded in \[lq]sign bit\[rq] format.
|
|
Here, a value < 64 denotes an increase, and a value > 64 a decrease
|
|
(thus the 7th bit is the sign of the value change).
|
|
The lower 6 bits then denote the amount of change (e.g., 2 increments
|
|
the control by 2, whereas 66 decrements by 2).
|
|
This format is often used with endless rotary encoders, such as the jog
|
|
wheel on the Mackie MCU.
|
|
It is denoted by using \f[C]<\f[] and \f[C]>\f[] in lieu of \f[C]\-\f[]
|
|
and \f[C]+\f[] as the suffix of the CC message.
|
|
Example:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
CC60<\ XK_Left
|
|
CC60>\ XK_Right
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
Furthermore, incremental \f[C]CC\f[] and \f[C]PB\f[] messages can have a
|
|
\f[I]step size\f[] associated with them, which enables you to scale
|
|
controller and pitch bend changes.
|
|
The default step size is 1 (no scaling).
|
|
To change it, the desired step size is written in brackets immediately
|
|
after the message token, but before the increment suffix.
|
|
Thus, e.g., \f[C]CC1[2]+\f[] denotes a sequence to be executed once
|
|
whenever the controller increases by an amount of 2.
|
|
As another (more useful) example, \f[C]PB[1170]\f[] will give you 7
|
|
steps up and down, which is useful to emulate a shuttle wheel, such as
|
|
those on the Contour Design devices, with the pitch bend wheel available
|
|
on many MIDI keyboards.
|
|
For instance, we might map this to the \f[C]"j"\f[] and \f[C]"k"\f[]
|
|
keys used to control the playback speed in various video editors as
|
|
follows:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
PB[1170]\-\ "j"
|
|
PB[1170]+\ "l"
|
|
\f[]
|
|
.fi
|
|
.SS MIDI Translations
|
|
.PP
|
|
Most of the notations for MIDI messages on the left\-hand side of a
|
|
translation rule also carry over to the output side, in order to
|
|
translate MIDI input to MIDI output.
|
|
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 this
|
|
work.
|
|
(Otherwise, MIDI messages in the output translations will just be
|
|
silently ignored.)
|
|
.PP
|
|
The output sequence can involve as many MIDI messages as you want, and
|
|
these can be combined freely with keypress events in any order.
|
|
There's no limitation on the type or number of MIDI messages that you
|
|
can put into a translation rule.
|
|
.PP
|
|
Note that on output, the \f[C]+\-<>\f[] suffixes aren't supported,
|
|
because the \f[I]input\f[] message determines whether it is a key press
|
|
or value change type of event, and which direction it goes in the latter
|
|
case.
|
|
.PP
|
|
For key press events, such as a note or non\-incremental control change
|
|
message, 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:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
C5\ CC80
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
It is also possible to specify a step size in this case, which
|
|
explicitly sets the value for the \[lq]on\[rq] state.
|
|
For instance, the following variation of the rule above produces a
|
|
\f[C]CC80\f[] message with value 64 (rather than the default
|
|
\[lq]on\[rq] value of 127) whenever the MIDI note \f[C]C5\f[] is
|
|
pressed:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
C5\ CC80[64]
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
On the left\-hand side of a translation, there are two additional
|
|
suffixes \f[C]=\f[] and \f[C]~\f[] for incremental \f[C]CC\f[] and
|
|
\f[C]PB\f[] messages which are most useful with pure MIDI translations,
|
|
which is why we deferred their discussion until now.
|
|
If the \[lq]up\[rq] and \[lq]down\[rq] sequences for these messages are
|
|
the same, the \f[C]=\f[] suffix can be used to indicate that the same
|
|
sequence should be output for both 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
|
|
relative encoders.
|
|
Also, on the output side the \f[C]~\f[] suffix can be used to indicate
|
|
an incremental \f[C]CC\f[] message in sign\-bit encoding.
|
|
Thus, to translate a standard MIDI controller to an endless encoder
|
|
value, you might use a rule like:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
CC1=\ CC60~
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
Specifying step sizes with incremental \f[C]CC\f[] and \f[C]PB\f[]
|
|
messages works as well, but scales the values \f[I]up\f[] rather than
|
|
down on the output side.
|
|
This is most commonly used when scaling up controller values to pitch
|
|
bends, which cover 128 times the range of a controller:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
CC1=\ PB[128]
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
Another possible use is to scale controller values \f[I]both\f[] down
|
|
and up with a combination of step sizes on the left\- and right\-hand
|
|
sides, to achieve (an approximation of) a rational scaling factor (2/3
|
|
in this example):
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
CC1[3]=\ CC1[2]
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
There are two other special tokens on the output side, \f[C]CH\f[] which
|
|
selects the default MIDI channel for output, and \f[C]SHIFT\f[] which is
|
|
used for processing shift state.
|
|
We'll discuss the latter in its own section below.
|
|
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[].
|
|
.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 different functions, e.g., to buttons
|
|
and faders which depend on the shift state.
|
|
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[129]\-1\ #\ translate\ controller\ to\ pitch\ bend\ when\ unshifted
|
|
^CC48=\ CC16~\ \ \ \ \ #\ translate\ controller\ to\ encoder\ when\ shifted
|
|
\f[]
|
|
.fi
|
|
.PP
|
|
\f[B]NOTE:\f[] To keep things simple, only one shift status is available
|
|
in the present implementation.
|
|
Also, when using a shift key in the manner described above, then 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 DAW software does), then it's usually more convenient
|
|
to simply pass those keys on to the application and have it take care of
|
|
them.
|
|
.PP
|
|
However, midizap's internal shift status feature may come 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 (almost)
|
|
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 the \[lq]Save\[rq] (or \[lq]Save and Quit\[rq]) option
|
|
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]) option in the same dialog.
|
|
.SH Secondary MIDI Ports
|
|
.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_input2\f[]
|
|
and \f[C]midi_output2\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 from the second input port and sending the resulting
|
|
MIDI data 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_input\f[] and \f[C]midi_output\f[]
|
|
ports to controller and application as before, but in addition you also
|
|
connect the application back to midizap's \f[C]midi_input2\f[] port, and
|
|
the \f[C]midi_output2\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 and Reaper.
|
|
.PP
|
|
You can also use examples/APCmini.midizaprc as a blueprint for your own
|
|
Mackie emulations.
|
|
If your controller has enough buttons and faders to serve as a mixing
|
|
device, you just need to figure out the MIDI messages which the device
|
|
generates, and which MIDI messages can be sent back to the device for
|
|
controller feedback (if the device supports it).
|
|
This information can hopefully be gleaned from your controller's manual
|
|
or found on the web somewhere, or you can figure it out on your own by
|
|
running midizap with its MIDI monitoring option (\f[C]\-dm\f[]).
|
|
.SH Bugs
|
|
.PP
|
|
There probably are some.
|
|
Please submit bug reports and pull requests at the midizap git
|
|
repository (https://github.com/agraef/midizap).
|
|
.PP
|
|
Here are some issues that I'm aware of and which might be addressed in
|
|
the future (or not):
|
|
.IP \[bu] 2
|
|
The names of the various debugging options aren't really very mnemonic
|
|
in some cases.
|
|
They are the way they are for compatibility with Eric Messick's
|
|
ShuttlePRO program on which midizap is based (see below).
|
|
.IP \[bu] 2
|
|
There's only one internal shift state.
|
|
That's unlikely to change, because in cases where multiple shift keys
|
|
are needed, the host application most likely already does them, so this
|
|
doesn't really seem to be worth the effort.
|
|
.IP \[bu] 2
|
|
Aftertouch and system exclusive/realtime messages are not supported
|
|
right now.
|
|
I didn't find any uses for them yet, but at least the system messages
|
|
might be good to have.
|
|
.IP \[bu] 2
|
|
It might be nice to have more options for scaling controller and pitch
|
|
bend values, and maybe ways to combine such values, or use them to
|
|
specify conditions on a rule (such as restricting the valid range of a
|
|
controller).
|
|
.SH Notes
|
|
.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 use Jack MIDI instead of the Contour Design Shuttle
|
|
devices that the original program was written for.
|
|
.PP
|
|
ShuttlePRO (https://github.com/nanosyzygy/ShuttlePRO) was originally
|
|
written in 2013 by Eric Messick, based on earlier code by Trammell
|
|
Hudson (<hudson@osresearch.net>) and Arendt David (<admin@prnet.org>).
|
|
The present version of the program is based on Albert Graef's
|
|
fork (https://github.com/agraef/ShuttlePRO) of the program.
|
|
All the translation features of Eric's version are still there (in
|
|
particular, key and mouse translations work exactly the same), but of
|
|
course the code has undergone quite some significant changes to
|
|
accommodate the MIDI input and output facilities.
|
|
The Jack MIDI driver code is based on code from Spencer Jackson's
|
|
osc2midi (https://github.com/ssj71/OSC2MIDI) utility, and on the
|
|
simple_session_client.c example available in the Jack git
|
|
repository (https://github.com/jackaudio/example-clients).
|