xphat: a MIDI slider box for Linux/X

Paul Barton-Davis <pbd@op.net> (Late Summer/Fall 1998)

a small screenshot of xphat


What is xphat ?

First of all, xphat is a piece of free and open source software. I wrote it because I wanted a tool like this. I'm giving it away because I believe in the idea that most software should be free. I'm giving you the source code because you may want to modify the program, perhaps to improve it, or perhaps you might like to learn something from how I wrote it (or tell me how to to do it better). I want xphat to benefit from this kind of software development process. However, there are some restrictions on what you can do with xphat, since I'm releasing it under the GNU Public License. In particular, you can't distribute it, or any modified version of it that you produce, without giving other people the option of getting the complete corresponding source code.

Secondly, xphat is a program that provides the functionality associated with MIDI slider/fader boxes such as the Peavey PC-1600 and the Phat Boy. Its a device for controlling other MIDI devices that respond to MIDI messages in useful ways. Such devices could include external MIDI synthesizers, soundcard-based synthesizers that can be controlled via MIDI, MIDI effects processors, MIDI software tools, software sequencers such as Rebirth or Softwerk; basically, any MIDI device.

xphat grew out of my frustration with conventional computer-based device simulations, which rely on the mouse for action and/or use conventional event processing. These approaches typically restrict you to modifying only one thing at a time. It seemed to me that a computer keyboard, although not the ideal control device for every purpose, had on the order of 100 keys that could be used as controls for a device like xphat. I think that xphat is novel in its use of the computer keyboard as a controlling device allowing simultaneous manipulation of several objects at once.

Getting xphat

You will need:

Once you've collected all the pieces, then:

  1. cd /the/right/place/for/source/code/on/your/system
  2. tar -zxvf wherever/you/put/the/tar/file/xphat.tar.gz
  3. cd xphat
  4. edit the Makefile to reflect the location of the XForms library.
  5. make
You can then run xphat by typing ./xphat.

What does it do ?

xphat displays 1 or more windows each of which contains 16 sliders. These sliders can be controlled with the mouse, or, more usefully, with the keyboard. Each slider can be bound to a keyboard key. The response of each slider to a keypress is by default logarithmic (the slider moves quicker the longer you press "it"), but each slider can be given a custom response curve using a simple graphical curve drawing tool. The space bar gives a convenient method of reversing the direction of slider movement.

Each slider can emit any MIDI message (except Active Sense). Most of the modes for each slider feature a well-defined MIDI message type (such as Note On, Controller N, Pitch Bend, etc.) which contain one parameter which can be varied by moving the slider. One exception to this is "Sysex" mode, which allows a slider to be programmed with an arbitary sequence of bytes, including parameters that can be altered.

Command Line Options

The following command line options are available:

-m device-name:tag or --midi device-name:tag
defines one or more device files (such as /dev/midi00) to use as a MIDI port. Up to 32 of these options may be used. The ports will be opened in the order given, and numbered accordingly, starting with zero. If no --midi options are given, xphat will attempt to open the first two ports found (using the directory order of /dev to find device files matching "midi*"). Each device file successfully opened will be referred to using the symbol name `tag' given with the option. This allows you to "label" MIDI ports with mnemonic names to help when selecting ports for various reasons. If no --midi options are given, the device file names will be used as the tag.
-o N or --oport N
defines the default input MIDI port, using the numbering scheme described above. If not given, the first port found (numbered zero) will be used as the default output port.
-i N or --iport N
defines the default input MIDI port, using the numbering scheme described above. If not given, the second port found (numbered one) will be used as the default input port. If no second port exists, then the first port will be used instead.
-t or --thru
automatically turns on "thru" mode if the default input and output ports are differen. Turning thru mode on/off can be done by clicking on a button; this just starts up xphat with it turned on, instead of off, which is the default. Note that if the default input and output port are the same, the --thru option will do nothing, and no button for thru mode will be displayed.
-d what or --debug what
turns on debug options for `what'
-s sysex_file_name or --sysex sysex_file_name
specifies the name of the System Exclusive file. See Sysex Configuration below for details on the format of this file. If not given, the filename defaults to "xphat.sysex".

Message Parameters

Arbitrary Sysex Messages (either custom or defined in the sysex configuration file can contain a number of special references that provide for dynamic adjustment of the message sent by that slider. Each reference is inserted into the message as a single character, and must be one of the following:

this will result in the current slider value being inserted at that point in the message whenever it is sent.
this will result in the most recent note-on velocity for the slider's MIDI channel being inserted at that point in the message whenever it is sent. If no note-on velocity has been seen for that channel, a value of 127 will be used instead.

Sysex Configuration

xphat uses a simple text file to provide the information necessary to predefine useful System Exclusive messages for a variety of MIDI devices. The file can be specified on the command line with the -s or --sysex options. If unspecified, xphat looks for a file called "xphat.sysex" in the current directory.

This file has a very simple format:

An example will help:

# Sysex Info File for xphat

Oberheim Matrix 6
	 keyboard mode =	f0 10 06 06 30 P f7

	 dco1 freq =    	f0 10 06 06 00 P f7
	 dco1 saw shape =	f0 10 06 06 05 P f7
	 dco1 pulse width = 	f0 10 06 06 03 P f7
	 dco1 mod/vibrato =	f0 10 06 06 07 P f7
	 dco1 waveform =	f0 10 06 06 06 P f7

The System Exclusive message is specified in a series of two-character sequences, each of which is a hexadecimal value. They may also contain the parameter references "P" or "V" (see Parameters above for details on how these work.

The User Interface

The Sliders

Each window that xphat displays contains 16 slider interfaces. Each slider interface looks like this:

picture of a slider interface
The Button

The Port Selector

The Port selector pops up a menu of available MIDI ports to assign as this sliders output MIDI port.

The Channel Selector

The Channel selector has two modes: clicking on it with the right button will advance through the available MIDI channels; clicking with the left will pop up a list of channel choices.

The Button

The Button can function in many different ways. Its mode can be set by editing the slider. Possible modes are:

When the button is in this mode, it has its own pair of MIDI messages, one sent when the button is pushed, and one when it is released. One or both these messages may be left unset, which will do the obvious: pressing or releasing the button will do nothing. The message has to be entered as raw MIDI bytes, and may include the usual parameters.
Send On Press
In this mode, when the button is not pushed, the slider will not emit any messages at all. When the button is pushed, the relevant message given the slider's current state will be sent, and while it remains pushed, modifying the slider will continue to cause the slider to actively operate. Releasing the button stops the slider from actively operating. This mode can be useful if you want to adjust the slider to a particular value, but not send the messages containing the intermediate values. Just set the button mode, adjust the slider, then press the button (and possibly release it).
In this mode, pressing the button causes the slider to automatically "slide" from its current value to its maximum value, following its own response curve. It can be used, for example, to trigger pre-programmed changes in a MIDI control parameter (say, volume) that vary over some period of time.
Recorded MIDI
This mode does not currently work, and may be removed.
This scene does not currently work, but will do in a future version.

The Slider

The slider is just that - a slider. It may be moved by pressing the key bound to that slider (displayed in the Key Window), or using the mouse. If the slider is part of a group, moving any slider in the group (with the mouse or with the keyboard) will move all other sliders in the group. The slider will also move if it has been set to use MIDI input for update, and relevant MIDI messages are received on its input port.

The Value Window

The Value window displays the value of the current slider. This is the value that will be inserted into the message sent by this slider. It can also be directly edited by first clicking on it, typing in a new value, and then pressing the TAB or Return keys.

The Mode Button

The Mode button, when pressed, pops up a list of available modes for this slider, and displays a description of the mode once selected. See Slider Modes for details on each mode.

The Key Selector

The Key selector allows to specify the key that will control this slider. Click on the key selector, press the key you want to use, and then press TAB or Return. NOTE: at present, only alpha-numeric keys can be used for binding to a slider. A future version may alter this.

The Group Selector

The Group selector allows you to assign the slider to a group, and optionally, for certain slider modes, a particular MIDI note value within that group. Sliders in a group can be all be simultaneously controlled by adjusting any of the group's member sliders.

Click on the group selector, then edit its contents. If you just want to specify the group, use a simple integer. To specify a group and a note number, separate them with a period (e.g. 3.64 means "group 3, MIDI note number 64). You can also use 0 for the group, which means "no group". Once you've entered the desired value, press TAB or RETURN. This and any other sliders with the same group ID are then all considered to be part of a group.

Notice that the Group selector allows great control when used with the On Velocity or Off Velocity modes. If the slider is assigned to a MIDI note number, the slider will only edit the velocity values of the specified note. This can be used as a powerful means of fading parts of a track, especially drumkits, where typically a given MIDI note corresponds to a particular drum sound. By collecting several MIDI notes together into the same group, you can fade in/out entire sections of a drumkit (or other pattern-based musical form).

Per-Window controls

The Preset button

The Preset button pops up an interface for saving, naming, renaming and loading presets. See Preset Handling.

The Thru Mode button

The Thru Mode button turns on/off MIDI thru mode. When turned on (pressed), each MIDI port used by xphat is connected to the next port (where next is defined by the order they were opened in, and where the last port is connected to the first, to form a closed circle). Thru mode is shared by all windows created by xphat (i.e. it is a global property of the program).

The More Sliders button

The More Sliders button creates a new window of 16 sliders and their controls. This new window is completely independent of all others xphat creates, and has its own keybindings, preset storage, and so on. The only setting it shares with other windows is the "Thru mode".

The Quit button

The Quit button closes the window it is on, and, if this is the last window that xphat has created, exits from xphat.

Editing a slider's "hidden" settings

There's no documentation for this yet. But ... try pressing the control key and one of the keys bound to a slider (mnemonic: "control slider K"), and see what pops up. It should be fairly obvious. Don't try editing the response curve yet, its still broken. Also, the SysEx mode selector doesn't do anything useful.

Slider Modes

Each slider can be set to any one of many different modes. These currently include:
The slider does nothing.
Note On
The slider sends a MIDI note on message every time it is altered, and the note number will be the value of the slider.
Note Off
The slider sends a MIDI note off message every time it is altered, and the note number will be the value of the slider.
Program Change
The slider sends a MIDI Program Change message every time it is altered, and the program number will be the value of the slider.
The slider sends a MIDI Polyphonic Pressure message every time it is altered, and the pressure value will be the value of the slider.
The slider sends a MIDI Channel Pressure message every time it is altered, and the pressure value will be the value of the slider.
Pitch Bend
The slider sends a MIDI Pitch Bend message every time it is altered, and the pitch bend value will be the value of the slider.
The slider sends a user-provided MIDI message every time it is altered. If the message contained any parameters, they will be set according to the current value of the slider and other relevant conditions.
The slider will send a MIDI Controller message every time it is altered. The controller ID is set when this mode is selected. The value of the controller value will be the value of the slider.
On Velocity
The slider will edit MIDI Note On messages received on its input port, setting the velocity value to the value of the slider. If the slider has its note number set, only Note On messages for that note will be edited. This mode only has an effect if thru mode is in effect to relay the messages from the inport port to its output port.
Off Velocity
The slider will edit MIDI Note Off messages received on its input port, setting the velocity value to the value of the slider. If the slider has its note number set, only Note Off messages for that note will be edited. This mode only has an effect if thru mode is in effect to relay the messages from the inport port to its output port.


One big problem you may notice is that if you try to operate two sliders at the same time using the keyboard, it doesn't always work. I've spent a lot of time investigating this issue, and it turns out to be very deeply rooted in the hardware of the PC keyboard. There is an electrical contact matrix under the keyboard, which is used to identify which keys are depressed. In certain keyboard designs, the matrix doesn't always allow the correct identification of simultaneous "key held down" conditions for arbitary combinations of keys. For example, on my keyboard, once 't' is held down, no keyboard interrupt for 'r', 'y', or 'u' will be generated until 't' is let up and those keys pressed again. xphat is not the only program to encounter this: you can see the same behaviour with the X event testing program xev(1), and a Linux console keyboard utility (whose name I forget). The best approach to this is to rebind the slider to a key in a different section of the keyboard, although this is a trial-and-error approach, since you can't predict which keys suffer from this problem.