I've put together a little Raspberry Pi synthesizer/sampler/sound module in a box, with stomp switches and a 16x2 character LCD. It has 1/4" audio outputs connected to a sound card inside the box connected to one of the Pi 2's USB ports, which provides good sound quality and low latency. One of the other USB ports is extended to the side of the box for a MIDI controller/keyboard. The Pi runs a script on startup that lets you choose sounds/presets by pressing the buttons, or open a menu by holding one of the buttons for ~2 seconds. The LCD displays preset info and menus.

## Reasons

My motivation for making this and putting it into a stompbox was my Alesis Vortex keytar controller. I like the freedom and expressiveness one has when playing a keytar. I've owned a few - a Roland AX-1, an AX-7, and even a little Rock Band keytar (which sends real MIDI from it's 5-pin DIN port). The AX-7 had great sounds, but I found I preferred the controllers for the lower weight, awkwardness, and battery usage. Plus, the Vortex has *wireless USB*.

I also prefer controllers because I like the versatility of experimenting with software instruments and effects. I've performed using DAWs and VSTs running on a laptop to trigger sounds, effects, loops, and backing tracks, but I wanted something more portable that could work reliably in a performance setting without a lot of keyboard-and-mouse jockeying. I decided that since guitars use effects pedals, the keytar should have one too - so I set out to build a synthesizer stompbox.

I settled on the idea of FluidSynth running on a Raspberry Pi. FluidSynth's design around soundfonts and built-in effects like reverb and chorus hearkens me back to the ROMpler synths of my youth, and the high availability of free soundfonts is a big bonus. The Raspberry Pi can fit in a small enclosure, and it's easy to add buttons and an LCD so I can interact with FluidSynth and have some visual feedback, and I can write a simple interface/FluidSynth wrapper that runs on startup, so I can toggle through presets that I create with some sort of config files.

## Building It

The first challenge was audio. The Pi's headphone jack was a non-starter - it downsamples to 11kHz and has a lot of latency due to how it's connected to the CPU. I tried some USB audio cards, and was eventually able to get FluidSynth working through ALSA with low enough latency for live playing by adjusting the `audio.period-size` and `audio.buffers` settings. I've read some posts about getting better sound and lower latency by creating a custom/bare-metal OS using something like Buildroot, but I knew that would take me much longer to develop, and I think the ease of customization and functionality I get with Raspbian actually make it a better choice for this project.

At this point I have a python script that starts on boot and communicates with FluidSynth through the `subprocess` library. It reads YAML config files that can describe different presets, which can include soundfont assignments for each MIDI channel, routing rules for MIDI messages, and even a way to link control change (CC) messages to things like the reverb and chorus parameters.

I built my device into an aluminum Hammond 1590BB enclosure - the kind often used for guitar effects pedals. I drilled out holes and did some cutting with a jigsaw to get square openings for the LCD and USB ports. I assembled the electronics on a perma-proto Pi hat, with a USB-B port connected to the 5V rail to provide power and a USB-A port for the controller, with an extender cable connected to one of the Pi's USB ports. I had trouble cramming the electronics and cables into the box, and solved this by removing the case of the USB sound card and *making* cables out of more flexible ribbon cable. There's a wifi dongle in the Pi so I can ssh in and make changes, and it doesn't seem affected by being inside a metal box.

![JamPi proof of concept](/media/blog_images/jampi_proofofconcept.jpg)

There's still a lot to do. Reliability needs to be improved - I often get things stuck in an unplayable state, from which I need to log in remotely or plug in a screen/keyboard to recover. There are probably cleaner ways to control FluidSynth than relying on using subprocess to talk to the command shell, and there are lots more features I'd like to implement, but it works. For now, I'm calling it the JamPi, since my vision for it is walking into a jam session with my keytar on my back and just plugging this thing in to play.