Gadgeteer and MIDI: Making Music with Microcontrollers
At the end of what's been a kind of tough week, with a spring cold making its way through my entire family (one of the perils of having young kids at home), I got a nifty package in the mail. Inside was an anti-static foil bag containing the parts for a nifty addition to my Gadgeteer hardware collection, the new MIDI Module created by my friend and fellow Microsoftie Pete Brown. I should have thought to snap a photo of the kit before assembling it, but I was sufficiently excited I could hardly wait to heat up the soldering iron. Here's what the finished module looks like:
So, OK, you might ask. Looks neat, and all, but what does it DO?
Well, for the uninitiated, MIDI stands for Musical Instrument Digital Interface, and the short definition is that it's a serial protocol specification that lets musical instruments "talk" to one another. MIDI allows devices to communicate musical information (which note to play, how loudly to play it, etc.) digitally in a highly efficient format. Instead of creating a waveform and pushing it through limited bandwidth pipes, MIDI allows a controller device to simply provide instructions on what note should be played, which channel it should be played on (MIDI supports up to 16 channels per interface), along with any information on the specific sound (referred to in MIDI parlance as a patch) and parameters (referred to as control change) for the target device. Then the controller leaves the actual generation of the sound up to the receiving device.
So what Pete's module does is allow a .NET Gadgeteer program to act as a sender or receiver of MIDI data. Which can be pretty fun stuff, with just a little work.
MeeBlip, You Blip, We All Blip!
In addition to his Gadgeteer hobby/habit, Pete is also a collector of various MIDI synthesizer gear. Most of what he plays with doesn't fit within my budget, but about a month ago he sent me a link to a neat open source hardware/software synth called the MeeBlip. From the "What is MeeBlip?" page:
MeeBlip is a hackable, affordable digital synthesizer, made for accessible sound and hands-on control. It can be someone’s first synth. It can be a unique-sounding addition to your music setup, playable with MIDI hardware and software. It can be a synth you open up and modify, learning about sound creation, code, and electronics. Or it can be the basis of new projects and ideas.
The MeeBlip SE, at $149, is pretty cheap as synths go, but what hooked me was the MeeBlip micro, which omits all the knobs and switches, and requires assembly, but costs less than 40 bucks. I ordered one, and it arrived a couple of weeks ago.
The Meeblip micro is a very simple beast. It's got a microprocessor that generates tones using open-source firmware (so if you're not completely happy with the generated sound, you can tweak it to your heart's content), based on the note information received at its MIDI in port, then outputs those tones to a 1/8" audio jack. It can be powered by a wall-wart or 9v battery (I wired up a snap-on 9v battery terminal in addition to the barrel jack that came with the kit). If you want to control the parameters that allow you to shape the sounds, you can add header pins to connect analog controls (knobs or sliders) and switches, which would give you something roughly equivalent to the MeeBlip SE.
Or you can simply use MIDI control change messages to control all these parameters. And that, my friends, sounds like a job for .NET Gadgeteer!
Introducing the MeeBlipiator
When I got the MIDI module from Pete, and got it all assembled, I plugged the module into my FEZ Spider mainboard, and connected the Meeblip micro to the MIDI out jack on the module. The first test program I wrote simply sent a series of notes on channel 1 (the MeeBlip micro is set to listen to channel 1 by default), like so:
midi.SendNoteOn(MidiChannel.Channel01, 60, 100);
Thanks to Pete's nicely polished driver code, it's a breeze to send the note info. When I dragged the MIDI module onto the design surface in my project, it automatically named it "midi" making it intuitive to use. In the above line, 60 represents the note to be played (60 is the value for middle "C"), while 100 is the "velocity" which is MIDI's way of representing the loudness of a given note. Both note and velocity have a range of 0-127.
Designer view for the MeeBlipiator
Once I got the basics working, I figured it would be fun to build something that could send note information to the MeeBlip, while also allowing me to manipulate some of the parameters that affect the tone generated, so I could combine programmed playback with realtime control. An arpeggiator is perfect for this, so I set out to create a simple one-octave 8-step arpeggiator modeled after the nifty Bliptronic 5000 from ThinkGeek (I bought a couple of these for my boys last Christmas, and they love them).
For the UI, I connected the 3.5" touch screen LCD from my Spider starter kit, and added a button module for starting and stopping the arpeggiator, and a Joystick module for controlling two separate parameters at the same time. You can see how these modules are connected in the image above. In the physical world, I had most of this hardware already connected in my customized Gadgeteer Arcade enclosure, so I just added the MIDI module to the mainboard, and I was good to go, hardware-wise.
To design the UI, I decided to use GHI's GLIDE UI library. While you can design your UI in Gadgeteer using WPF, and it works pretty well, WPF on .NET Micro Framework doesn't support XAML, so you end up doing things programmatically. That's not a terrible thing, but as a web geek, I find markup much more intuitive to work with for UIs. GLIDE uses XAML-like markup to define your UI, and also provides a designer that gives you some WYSWIG-ish functionality:
I used RadioButtons in vertical groups for each step in the arpeggiator, and each radio button represents a specific note, from middle "C" at the bottom, to the C above middle "C" at the top…essentially all the natural notes of a C scale. Here's what the markup looks like for one of the RadioButton controls:
<RadioButton Name="C1" X="0" Y="196" Width="28" Height="28" Alpha="255" Value="60" Checked="True" GroupName="1" ShowBackground="True" Color="d4d4d4" OutlineColor="b8b8b8" SelectedColor="358bf6" SelectedOutlineColor="002dff"/>
In this case, "C1" indicates that this is the first C in the first group of RadioButton controls, also indicated by the GroupName of 1. Each step of the arpeggiator has its own GroupName, so only one note can be selected per step (I restricted this because the MeeBlip can only play one note at a time…you could use Checkbox controls if you were using this to drive a polyphonic synth). The Value is the MIDI note number to be played when this RadioButton control is selected.
I also included a ProgressBar at the bottom to indicate which note is currently being played, and a Slider to control playback speed. The gray boxes that you see in the image above are Image controls, which will be replaced at runtime by bitmaps stored as resources.
The currently available GLIDE runtime is version 1.0.3, but the designer is 1.0.4, and the XML it generates (you can get the XML by selecting Window > Show XML) will have that version number, which may cause errors when you try to run it. Once I get the UI to a certain point, I typically save it in my project as an XML file, where I can make modifications locally using Visual Studio's XML editor. One of the first things I do is make sure the version string matches the runtime version of GLIDE I'm using, in my case 1.0.3. For convenience in loading the XML, I usually save the XML as a string resource, and then load it as follows:
window = GlideLoader.LoadWindow(Resources.GetString(Resources.StringResources.ApeggiatorUI));
Here's a shot of what it looks like when first run:
When I press the button, a timer defined in the program will start running, with the interval of the timer being adjustable via the Slider control. At each timer tick, the program will look at the current RadioButtonGroup, find which RadioButton is selected, and retrieve its value, which contains the MIDI note number to be played. Then the group number is incremented, the note played, and so on.
Also at each timer tick, the position of the joystick is retrieved, and used to send MIDI control change messages for the filter resonance and filter cutoff parameters of the MeeBlip (cc 48 and 49, respectively. You can view a full list of the MIDI cc mappings for the MeeBlip micro at the bottom of this page).
Remaining tasks include adding another UI page (or set of pages) to control the rest of the available parameters on the MeeBlip micro, including perhaps re-mapping the joystick to different parameters during playback, as well as possibly adding the SD card module so I can save and load "patches" of different settings for the MeeBlip micro parameters, so once I find a really sweet sound, I can save it and reproduce it whenever I want.
In addition to using this very simple arpeggiator program, Pete's MIDI module also has MIDI in, and you can easily enable "soft" MIDI thru, which essentially echos whatever commands it receives at the MIDI in port to the MIDI out port. So I could plug a keyboard or other MIDI controller into the module and use it to drive the MeeBlip as well.
Of course, I can't leave my readers without a video of the project in action:
While creating a simple arpeggiator may not seem like the most practical project in the world, it's quite fun, and more importantly, it highlights how quickly .NET Gadgeteer allows you to put together disparate pieces of hardware and software to come up with something fun and/or useful. With loads of modules already on the market, and more becoming available soon, building hardware-based solutions has never been more accessible. Whether you want to build your first robot, a weather station, or whatever you can dream up, .NET Gadgeteer can help you get there fast.
Oh, and did I mention that I managed to get the basic arpeggiator working in just one evening? That's why Gadgeteer is called a *rapid* prototyping platform.
Want the code? You can download a ZIP file containing the whole project here (MS-PL). You should follow me on twitter to keep up with all my Gadgeteer, Kinect, and Windows 8 hackings. And if you like what you see, please use the tweet, like, or share buttons at the top of the post to let your friends know!