Here's a short project I did with a cheap MIDI guitar a while ago.
The Controller!
First off, can you believe this thing was made? A +102 button MIDI guitar hidden in a video game controller! There were made for Rock Band 3 in what must have been a reaction to all those annoying "you're not playing real guitar!" posts back when Guitar Hero/Rock Band was a marketable franchise. God, that seems like an eternity ago, right? Anyway, Madcatz produced these controllers for Wii, PS3, and XBox 360. While they can be used wirelessly with their respective systems, they also include MIDI out! Being a hunk of plastic almost a decade old, you can find these controllers relatively cheap (~20$) at used video game stores or goodwill, making it a no-brainer if you're even a little interested in a guitar-style MIDI controller.
It Works!
I first hooked this thing up to a Casio Priva piano to test it out, everything worked just like I expected, the strings are even velocity-sensitive. The buttons are tied to octave and program-change commands, there's better documentation of that here. There's even a mode where just pressing a fret transmits the associated note command (without needing to strum).
Hooking the controller up to my Volca FM, however, I found that it would only play notes on one string (high E). The Volca is set up to only receive MIDI on one channel at a time, and mine was set to channel 1. It turns out, the guitar transmits notes from each of the strings on different MIDI channels, 1-6. This is apparently typical for guitar controllers. I don't know the history here, but there's probably a potential for message confusion if there are too many note on/note off commands happening in a short period of time. Anyway, this meant that the controller couldn't effectively be used with the Volca which was pretty disappointing.
It Could Work Better!
Not one to give up on such a cool toy, I started thinking about a "man-in-the-middle" message handler which could look at note data coming from a controller and change its channel before passing it on to the receiving device. It could be pretty simple, MIDI is basically just UART with some simple isolation between devices. There are a million Arduino MIDI sketches out there to use as examples of receiving and transmitting MIDI. Even better, there are plenty of readymade MIDI shields for Arduino.
Okay, so hardware looks easy. How about software? Looking at the MIDI Protocol, channel specific messages like Note On and Note Off consist of a status byte followed by one or more data bytes. I'll tell you all a secret: I'm not very good at programming and I get myself mixed up on what are probably simple tasks, like managing data on a serial port. When I first looked at the protocol I thought I would have to create some functions to grab sequences of 3 bytes, make sure the first one I pulled was the status byte, then manipulating the data and sending it back out in the right order. Probably not too complicated for someone who knows what they're doing, but I don't have much experience with that.
Fortunately, on a closer look at the MIDI communication protocol, I noticed that all of the status bytes related to channel-specific messages fall between 0b1000nnnn and 0b1110nnnn, where "nnnn" is the associated channel, 0b0000-0b1111. Even better, all data bytes are limited to being between 0b00000000 and 0b01111111, which means that it's actually really easy to figure out what kind of MIDI message you're looking at based on a single byte! The status byte indicates which channel the message is addressed to, since the only thing I wanted the program to do was change the message channel, all I cared about were status bytes between 0b10000000 and 0b11101111 (0x80 and 0xEF).
My program is therefore very simple. It looks at each byte being transmitted by the controller. If it's outside the range 0x80 to 0xEF, then the command just gets sent along unchanged. If it's within that range, then the program does a bitwise AND with the received message and 0b11110000 (0xB0). This leaves the first 4 bits (which identify the type of status message) unchanged, while changing the last 4 bits (which identify channel) to 0 (MIDI channel 1). Easy! And something this simple will take practically no time to process so there's little risk of adding any latency to the MIDI messages.
It Works Better!
Using the super cheap arduino middleman, I can now get the Volca to play notes from all 6 strings! As far as I can tell, there isn't any note confusion happening as a result of throwing everything onto a single MIDI channel, maybe the Volca being limited to 3-note polyphony keeps things simple?
It Could Be Easier!
As nice as this is, the MIDI Middleman needs its own power supply, not to mention it requires an extra MIDI-MIDI cable, and I only have the two of them. That controller is awfully big, I bet there's room on the inside for a microcontroller that could do the message manipulation before the data even reaches the MIDI port...
No comments:
Post a Comment