Wednesday, February 28, 2007

HID

The Human Interface Device standard for USB devices is great. The obvious appeal of using them as controllers: there are a huge number of cheaply available keyboard, mice, trackpads, joysticks, jog wheels, etc, all of which can be understood without individual drivers. However using them as controllers is not straightforward because most audio software does not accept joystick input, and mice and keyboards just duplicate the normal mouse and keyboard.

In Linux, I wrote a GDAM input plugin for reading USB HID events. USB events show up on /dev/input/event* (if you have your kernel configured correctly, but these days it seems to be the default) The event interface is also great: you get 3 bytes, the first is event type (button vs axis vs relative etc) second is index (256 of each type max per device) 3rd is value. Implementing the OSX version involved many lines of dynamically allocating objects based on how big they were in the current version of OS.... linux was dead simple.

Recently revisiting some HID controllers, they were less convenient than MIDI. In particular, if I unplug the device /dev/input/eventN disappears and I get read errors. If I replug I have to reopen device. So I made a HID -> MIDI driver for linux. It hotplugs, and any USB HID device plugged in becomes a virtual ALSA MIDI port. So far I'm translating key and button presses, and absolute values (faders, analog joysticks) into MIDI notes and CC's. I haven't decided the best way to translate relative (mouse, touchpad) events into MIDI, there is no clear match. I refuse to convert to absolute by driving a virtual CC because that would be limiting. I may send note on with different velocities, or set CC value for each relative event but those are non-standard uses.

Now, using qjackctl's patchbay to automatically restore MIDI routing, I can replug my HID controllers at will without doing a thing in software. Instead of working through a plugin specific to my software, the MIDI can be used with any software or even sent over a MIDI cable to drive hardware.

I made a quick GDAM binding file to make the MIDI notes correspond to qwerty layout. My laptop keyboard may or may not be implemented via USB, but it does show up in /dev/input/event* so I can run my driver on it. Now all my typing is rendered rhythmically and melodically. I've enjoyed some of the riffs that emerged while I code, newlines and braces resolve nicely.

No comments: