Purpose
To turn signals coming from a Wiimote into MIDI events.
In more concrete terms: to play real MIDI instruments with the Guitar Hero drumkit. Or to control stage effects (lighting and so on) with your Wiimote buttons. Or to control software sound effects with a hacked Wiimote. Or simply to use your Wiimote as a remote control for your media player.
Features
- Handles all the standard buttons on a Wiimote, plus those on the “nunchuck” (including the directional stick), the Guitar Hero World Tour drum contoller (including the actual drum pads, the stick and the extra buttons), the Guitar Hero guitar controller (colored frets, “touch” frets, strum bar, buttons, stick and the whammy bar). The ”classic controller” is only partially supported (sticks and a few buttons); I don't have one at hand to test.
- Each event can be mapped to a specific MIDI signal (note or program-change or any arbitrary MIDI message).
- …or to a LED status change.
- …or to LED animations!
- …ot to set the default channel for future events.
- …or to several such actions (MIDI signals, LED stuff, channel change).
- …or even cycle across a list of events, so a button/pad can act as a toggle.
- Buttons generate two separately-mappable events for press and release.
- Drum pads are sensitive to the force of the hit, which is mapped to a MIDI velocity. Also, the MIDI event can differ based on the strength of the hit, which allows things like open/closed hi-hat sounds on the same pad.
- Directional sticks can be used as an “analog” control (with values across the given range of the stick); they are also mapped to four virtual buttons that generate press/release events if that's enough.
- Simple
.ini-style configuration file. - Multiple configurations can be defined in the configuration file, and one chosen at runtime.
- The configuration includes what MIDI device to send the events too.
- A sample Hydrogen “song file” is provided, since it can be tricky to set up a kit appropriately in Hydrogen.
- A sample Wiimidi kit is also included in the configuration file, which should work with the order of the instruments in the default GMkit provided by Hydrogen.
- A sample script is also included, demonstrating how to run arbitrary commands on receiving MIDI events. The commands shown in the sample script control the Rhythmbox music player, which you can therefore control with your Wiimote or something attached to it.
- Free Software: licensed under the GNU General Public License, version 2 or later.
Get it
The current version of Wiimidi is arbitrarily numbered 0.8, and can be downloaded at wiimidi-0.8.tar.gz.
Wiimidi is developed with Bazaar, and the public branch is at
http://alioth.debian.org/~lolando/bzr/wiimidi/trunk/ (may also work
in https). So, to grab a copy:
bzr checkout http://alioth.debian.org/~lolando/bzr/wiimidi/trunk/
You'll need a few Python modules, namely configobj, pypm
(PortMidi) and of course python-cwiid for accessing the Wiimote
data. They're all packaged in major Linux distributions. Wiimidi
itself could easily be made available in Debian if there's enough
demand (the Bazaar branch actually already contains the packaging).
Run it
wiimidi --verbose --config=./wiimidi.conf --kit=general_midi
The --config option allows specifying a config file (on top of the
default locations); --kit allows choosing which of the
configurations in the config file to use. After launching the script,
press the 1+2 buttons simultaneously on the Wiimote to establish the
Bluetooth peering. Oh, yes, you'll need a Bluetooth adapter if it's
not built-in, of course.
Configure it
Edit the wiimidi.conf file to fit your needs. (Or copy it to
/etc/wiimidi/wiimidi.conf or to your
~/.config/wiimidi/wiimidi.conf.) It's sort of self-documented, and I
tried to pick meaningful names for the sections and the variables, as
well as providing usable default values, but your use case may be
different. The configuration syntax is described below.
Kits
Each section describes a “kit”, or set of settings. The DEFAULT
section is special, and its values are inherited by other kits. It
also has a default_kit setting, which is used if no kit is
explicitly specified on the command line.
Kit settings
midi_out describes the MIDI port to which events should be sent. It
can be a purely software port (Midi Through Port-0 for instance, or
Hydrogen Midi-In) or a hardware adapter (my Roland USB adapter
describes itself as UM-1G MIDI 1).
on_startup is a list of actions to be executed on startup. You can
send initialization messages to MIDI, or provide some visual feedback
using the LEDs on the Wiimote.
Mappings
map_* values describe the mappings from Wiimote events to actions.
The simplest mappings concern the buttons and the cross-pad:
map_wiimote_button_1, map_wiimote_button_left and so on. You can
also trigger events when the button is released, with mappings such as
map_wiimote_button_1_release.
When the Wiimote is plugged into an additional controller that
provides buttons, these can be mapped too; for instance, the nunchuck
provides map_nunchuck_button_c (and the _release variant).
When the additional controller provides a directional stick, four new
virtual buttons appear for up/down/right/left; hence possible mappings
such as map_guitar_stick_left (and of course
map_nunchuck_stick_right_release for the release action). The exact
value of each axis (mapped to the 0-127 range used in MIDI) can also
be used for MIDI “control change” events (see cc below) with
map_nunchuck_stick_y. The classic controller provides two such
sticks, leading to map_classiccontroller_leftstick_up and so on.
The classic controller has a cross-pad and a handful of buttons, used
the usual way. The standard classic controller also provides two
“analog” triggers, l and r, which can be mapped to a control
change using the map_classiccontroller_trigger_l mapping (and ditto
for _r of course). This comes in addition to the _button_l/r
mappings, so you can use the triggers both as a continuous source of
events or as a button. Note that the “classic controller pro“ only
provides buttons where these triggers are in the standard one, so the
_trigger_l/r mappings will not be particularly useful since they'll
only send one of two distinct values.
The drum pads (map_drum_pad_red, map_drum_pad_kick, and so on) are
sensitive to velocity (on a range from 1 to 7), and can have a
different mapping based on whether the hit is stronger than a
threshold. To have the red pad send a “cross-stick” action instead of
the standard snare drum action on soft hits, set
drum_split_threshold_red to a value such as 2, and set the
map_drum_pad_red_soft value to the cross-stick action.
The guitar controller provides five fret buttons (from
map_guitar_fret_green to map_guitar_fret_orange). The Guitar Hero
World Tour guitar controller also provides five buttons for the
sensitive part of the guitar neck, which are accessible with
map_guitar_touchfret_1 to map_guitar_touchfret_5; note that these
touch-frets they're not quite independent: at most two touch-frets can
be active at a time, and that requires them to be contiguous. If you
finger several touch-frets in a split way, only the highest one is
taken into account (or possibly the highest two, if they're
consecutive).
The guitar controller also provides a whammy bar, which can be mapped
to a control change action with map_guitar_whammy_bar.
Note that the various controls provided by the guitar generate independent MIDI events; there's no mechanism to only trigger the event when you strum, for instance. This is partly because I have no clue about guitars (I'm a drummer myself), partly because that would probably mean a combinatory explosion in the required mappings, and partly because I feel it goes beyond what Wiimidi should do: Wiimidi is meant as a gateway from the Wii world to the MIDI world. The actual smarts of what to do can (and should) be implemented further down the MIDI pipe, possibly with tools such as Mididings or others.
Actions
The syntax for actions is command/parameter or
command/parameter/parameter if several parameters are possible.
Commands can be grouped in several categories. First, MIDI events:
note-on: mandatory parameter is the number of the note; an optional second parameter can override the default channel to send the note on.note-off: ditto.noteis a shortcut, and sends the note-on and the note-off events in a row.- Another shortcut: if the action is only a number, then
note/is assumed. pc: program change. The program number is expected as first argument; an optional second argument can specify an explicit channel.cc: control change. The control number is expected as first argument; an optional second argument can specify an explicit channel. The value of the controller is taken from the input trigger when relevant.raw: send raw MIDI events. Useful for SysEx events, or those events that don't have a dedicated command here. No validation is made on the bytes, so be careful what you send.- Not exactly a MIDI event, but
set-channelsets the default channel for further actions.
Then, LED control:
led-on: switch a Wiimote LED (number expected as parameter) on.led-off: guess.led-toggle: guess.led-animate: start a LED animation (see below). Parameter is the name of the animation.
Compound actions:
- Several actions can be described in one mapping, using
+as separator. The actions are executed in a row, with no arbitrary delay. For instance,pc/2 + led-on/2 + led-off/1could be used to send a program change and adjust the LEDs accordingly. cycle: run the next action in the cycle named in the parameter, see below.
Cycles (macros)
A cycle_foo directive describes a cycle named foo. It's described
as a sequence of actions (possibly compound actions) separated with
;. The number of semicolon-separated components is the length of
the cycle. Each time the cycle is called (with an action such as
cycle/foo, the actions in the corresponding step are called, and the
step is pushed forward by one, unless the end of the cycle has been
reached and we loop back to the beginning.
A two-step cycle can be used as a toggle/flip-flop: a possible use
would be cycle_playpause = pc/10 + led-on/2 ; pc/11 + led-off/2
(note compound steps). The first time the cycle is called, a
program-change/10 event is sent, and the second LED is switched on.
The next time, program-change/11 and the LED is switched off.
A one-step cycle can be used as a macro: for readability, you may want
to define a cycle_ledsoff = led-off/1 + led-off/2 + led-off/3 +
led-off/4.
LED animations
A ledanimation_foo directive describes a LED animation that can be
triggered to give visual feedback on some actions. The syntax is a
simple semicolon-separated list of the set of LEDs that should be on
at a particular step. Flashing all LEDs twice would be
ledanimation_flashtwice = 1234;0;1234;0 (the zeroes are optional and
only mentioned for readability). A sweep would be defined as
ledanimation_sweep = 1;12;123;1234;234;34;4;0, and would be invoked
by an action with led-animate/sweep.
Note that LED animations are asynchronous, and further actions do not wait for the animation to complete. As a consequence, if two animations overlap in time because the second one was started before the first one was finished, then you'll see interesting flashing things.
Tell me about it
Patches welcome, of course! Also, I'll be interested to hear about your applications. I use it alternately to add extra pads to my electronic drumkit and to control my music player when practicing. I've already been told about a Wiimote-powered foot controller. If you do a Wiimote-controlled robot dinosaur (with lasers), please tell me!
Improve it
Possible improvements to Wiimidi include:
- Some kind of GUI to help with customisation/configuration.
- Handling of the accelerometers in the Wiimote and nunchuck, probably mapped to Control Change messages (to act as an expression pedal, or a pitch-bend wheel).
- More comprehensive handling of attached devices, such as the “Taiko no Tatsujin” taiko drum controller, or the “balance board” for more convenient expression pedals. This may take some time, because I don't have the necessary hardware at hand (hint, hint).