Electric Melodica, or: the Breath Controller Mk II
14 Dec 2015 Progress: Complete
Last year I built something that successfully emulates a Yamaha BC3a breath controller. It plugs into a Yamaha keyboard and a series of midi controller values are sent out. Although I can't compare its performance to the real thing, it certainly seemed to behave correctly. But it never saw as much use as I'd planned because the whole thing didn't feel right. It's not so much about latency, more the temporal quantization. The keyboard only samples it every few milliseconds, and then the synthesizer has its own buffer of a few milliseconds which quantizes it further. The overall effect is just nowhere near what it feels like to play a real melodica. A few milliseconds is nothing for pressing piano keys, but a breath controller really needs as much bandwidth as a microphone.
With my synth cables that have no envelopes or volume control it seemed a nice idea to interface the breath controller to them in a completely analogue way. And so I built the following device, which interfaces to the breath controller via the same protocol as the Yamaha keyboard, and directly uses the analogue voltage to variably attenuate an audio stream. The 3.5mm jacks mean it can also be used with other synthesizers or audio sources.
I started by upgrading the breath controller itself to have external controls for gain and offset. This meant repackaging into a case that had a flat surface. The circuit is essentially the same as before, just an inverting amplifier. This time I gave it a fixed gain of about 20 and used the gain knob just to attenuate the pressure sensor's signal. I did this because I was seeing some ringing and thought it might be a unity-gain stability issue. As it happens, being able to turn up the gain is something I regret not adding sooner - more sensitivity is almost always welcome.
In order to construct a voltage-controlled-amplifier/attenuator we need a voltage-controlled-resistor. It's possible to use a jFET as one, but the range of voltages in which it behaves correctly is quite limited. A much simpler way is to use an LDR and an LED. The LED lights up, the resistance of the LDR drops. I was a little sceptical about how well this would work but after a few experiments I was convinced that an LED/LDR arrangement easily had enough bandwidth to transmit audio frequencies.
I know you're probably laughing right now, but it really does work very well. I wrapped it in black heatshrink to keep out ambient light...
An additional benefit to doing it this way is the optoisolation lets us keep the breath controller's power supply totally separate; the grounds can be kept apart. Any audio stream can be plugged in and will pass through without any risk of ground loops.
Schematic – remember that with the BC3a (and my imitation) the voltage is high when idle, and lowers when you start breathing.
The offset knob on the controller is essential for this to work well, as the LED needs around 1.2 volts before it starts to emit any light. The knob lets you set the voltage to just a fraction below illumination. The offset position is of course different when used with the Yamaha keyboard, but that's why we stuck the knob on the outside.
The first one was built in mono only, which was rather short sighted and I later added a second channel which left the circuit board quite cramped. A jam was scheduled for that evening and in my rush to get this finished in time, I didn't think to match the components for each channel. Unfortunately one channel ended up with a different offset to the other. Whether this is the LEDs being different or the LDRs being different I couldn't say, I'd already wrapped them in heatshrink. I swapped one of the current limiting resistors for a trimpot which approximately fixes the problem, but there's still a difference between each channel's behaviour. If I was making this again I might try and use a single LED to light both LDRs.
The cable on the left is a standard 5.5/2.1 barrel jack giving it 5V power. A standard melodica tube is connected to the breath controller via a short length of silicone and a plastic connector that actually started life as one of those needle covers on a syringe. It has a series of little holes in the side, so sliding the silicone over it controls the air leak. I had made that for the original breath controller, but since making this more responsive version I no longer feel the leak is needed and I've left all the holes covered.
In fact the response is so great that if you apply a DC voltage to the input, and talk into the breath controller, it will send the audio of your voice to the speakers. This also means you can sing into the tube and just about get a beat frequency with your synthesizer. What I actually want the breath controller for - quickly tongued articulation - works perfectly, and with no latency or quantization of course. Brilliant.
Here are some thoughts on this invention.
In trying to recreate the responsiveness of a real melodica, one of the things I worried about was the momentum of the air in the instrument. The piezoelectric pressure sensor doesn't measure quite the same thing. To add some momentum artificially, I used a diode, capacitor and a trimmer to build a peak-detector with adjustable release time. This worked but felt very odd, as even very short breaths had long release times. I abandoned this idea in favour of just turning up the gain. As it happens, there seems to be some hysteresis / capacitance to the LDRs anyway: if you play continuously but stop blowing, the output drops sharply to a point, but then decays exponentially. It sounds a little bit like there's reverb applied.
Dynamic range, I will admit, is an issue. The problem with linear attenuation is that volume is proportional to amplitude squared. The sensor has a linear response, the LED and LDR are fairly linear too. This can be skewed a little by the current limiting resistor, but really it could do with a much heavier non-linear gain curve. Basically you can control on/off beautifully, with fantastic articulation, but once you're blowing, blowing twice as hard produces only a small increase in volume. I could possibly experiment with this some more.
I think I'd like to make this a little more convenient for use in a jam. Unfortunately using a headphone cable to extend the breath controller's connection does not work well at all: pushing tens of milliamps through for the LEDs means heavy losses and the offset moves, and with the TRS arrangement of the BC3a the ground is not on the shielding, and so the whole thing is extremely sensitive to noise and ground hum. I could extend just the tube, but I fear for the dispersion that would introduce. The only practical thing to do is extend the audio itself, so I use a bunch of headphone cables going to and from the contraption which then hangs around my neck. Live jamming is possible like this but it's a little clumsy and could do with improvement. Also a durable enclosure wouldn't hurt.
The whole thing only attenuates an analogue audio stream. This is perfectly usable with software synths, but any persistent effects like reverb get attenuated too. It would be nice to attenuate it before the filter stage. The latency probably isn't an issue if we can get enough bandwidth through, and there is a way to do that, by using the computer's microphone input port. That's AC coupled of course, so we'd need to modulate the signal. I think I might build an oscillator circuit that produces something like a 5kHz sine wave, that's then attenuated by the breath controller arrangement, and then feeds into the line-in of my laptop. The synth would then demodulate this to get the envelope and then directly apply that to the synthesis at the needed stage.
To conclude, I am writing this up about a month after building it, and in that month I've used it more than I ever used the first version. This really hit home when I picked up my real melodica, and playing a few notes, thought to myself, 'boy, that's laggy!'