Monday, September 13, 2021

DIY Vocoder: Robots Feelin' It

The vocoder.  It's undeniably attention-grabbing.  And, for many, it is also completely off-putting.  It is absolutely the anchovies-on-pizza of the synthesizer world.  I like anchovies.  But would I like a vocoder?  I needed to find out...so, I built my own!


What is a Vocoder?  A vocoder is an effect that makes a synthesizer sound like your voice.  You sing or talk into a microphone and you play your synthesizer.  The vocoder transfers certain qualities of your voice onto your synthesizer.  Like a wah pedal, equalizer, or filter, a vocoder doesn't make its own sound; it manipulates and changes the sound from another device, such as a synthesizer.

Setup.  As shown below, a vocoder needs a microphone and a synthesizer.  The two are plugged into the vocoder.  The output of the vocoder goes out to your PA or DAW.  Pretty easy.  It's what's inside the vocoder that is the magic.

Starting Simple: 1-Band Vocoder.  Before we get too deep, we should look at a simpler example.  Since a vocoder processes many frequency bands in parallel, lets start by looking a simple 1-band vocoder.  As I've illustrated below, a 1-band vocoder has two elements: a block to sense the instantaneous loudness of the voice ("RMS", which is an envelope follower) and a gain block (a VCA) to change the loudness of the synth in response to the voice's loudness.  This is the core unit from which we will build up a vocoder.
 

What Does It Sound Like?
  This basic effect changes the overall loudness of the synthesizer.  When the voice is loud, it allows the synth to be loud.  When the voice is quiet, it forces the synth to be quiet.  It responds very quickly and very naturally.  While that is cool, it does not actually sound like the voice. Just changing the loudness is not enough to sound like your voice. 

Tracking Your Voice's Formants.  To add more voice-like qualities, a real vocoder looks at the loudness of many different frequency regions of your voice.  The different frequency regions are chosen to sense the different frequency regions associated with the different vowel sounds.  As you make the different vowel sounds, you change the shape of your mouth (and nasal passages) to enhance or attenuate the different harmonics contained in your voice.  This shaping is why an "A" sounds different from an "E" and from an "O"; the peaks in the frequency response (the "formants") are very different for the different vowel sounds.  A vocoder detects this frequency shaping and applies the same frequency shaping to the synthesizer's audio.  The result is a voice-like quality to the sound of the synth.


Multiband Vocoder.  Our 1-band vocoder changed the loudness of the overall signal -- all frequencies were affected equally.  To make the synth more voice like, we want to sense the frequency shaping (the formants) as it dynamically changes to make the different vowels.  Therefore, we need to break up the audio so that we can control the loudness of individual slices of the frequency spectrum.  To make this give us this finer control, we copy our 1-band vocoder many times in order to get a multiband vocoder.  The illustration below expands our 1-band vocoder into a 3-band vocoder.

Breaking Up the Audio into Frequency Bands.   The core of this system are still the green RMS blocks (envelope followers) and orange gain blocks (VCAs) as discussed before.  This system still controls loudness.  But, note that we precede each of these channels with a bandpass filter.  Therefore, each channel is controlling the loudness of just one frequency region.  In this simple 3-band example, the first filter might isolate the low frequencies so that that loudness of the low frequencies are made to be the same between the synth and the voice. The middle filter and last filter would do the same for the middle and high frequencies.  Now, we are impressing more of the voice's qualities onto the synth.  A real vocoder uses 8-16 of these channels, which gives it much better resolution, making the output even more voice-like.

Making My Own Vocoder.  In the old days, the bandpass filters, RMS blocks, and gain blocks would all be implemented by actual electronic circuits.  Today, however, it's much easier to write signal processing software to perform these functions.  That's what I did.   I used an open-source digital audio device from Blackaddr (the "Teensy Guitar Audio Pro", TGA) and wrote software to implement the vocoder.  The TGA uses a Teensy 3.6 as its processor, which can be programmed in the Arduino IDE, This is great because Arduino is what I use for many of my other synth hacks.   I've shared my Teensy/Arduino vocoder software on my GitHub here.

Filtering and Processing Speed.  Having up to 16 channels, and needing at least two filters per channel, a vocoder needs a lot of filters.  So, your choice of filter is important as it can consume a lot of the available processing power.  I used the multimode filter model that comes in the Teensy Audio Library  They implemented the filter as a time-domain IIR filter with fixed-point operations.  I ended up using two filters in series to sharpen the filter's response (though I'm not sure that was really necessary).  Even with the burden of the extra filtering, the Teensy 3.6 was fast enough to enable a 16-band vocoder.  With the double-filtering, that's 64 filters in total!  I was pleased.  


Filter Frequencies.  An important choice is to pick the frequency bands for your vocoder's filters.  I know that the frequencies should be tailored to the human voice, but I had no specific guidance on what frequencies to use.  After a bit of trial-and-error, I chose to center my first filter at 125 Hz and then I step the frequency upward by a factor of  1.319x for each subsequent filter.  This seemingly-bizarre value is partway between half-octave steps (1.414x) and third-octave steps (1.260x).  Using this step size, my filters end up being centered at: 125 Hz, 165 Hz, 218 Hz,...<etc>..., 4595 Hz, 6063 Hz and 8000 Hz.  To me, this felt like a good span for the human voice.

Make Your Own!  To be clear, when I wrote this vocoder, many of my choices were arbitrary.  Don't be afraid to make your own choices!  Choose a different type of bandpass filter.  Choose different filter frequencies.  Use FFTs instead of time-domain filters.  That's the beauty of hacking using open technology: you can try things out for yourself!  Go and have fun!

Thursday, September 2, 2021

DIY Beat Box to MIDI Converter

It was the best spouse's workplace party ever.  I got to talk with a guy about how he could make his modular synth respond to his voice.  How cool is that!  I was inspired.  So, while I don't have a modular synth, I do have an 808-style drum machine.  Here is a joyous toast to you, the best spouse's workplace party ever: my voice-driven drum machine!


DIY Voice-to-MIDI Converter.  The key to this hack is making a device that can listen to my voice and can distinguish between my different voice sounds.  When I make a low-pitched sound ("boom"), it should issue a MIDI command for a kick drum.  When I make a high-pitched sizzly sound ("tsst") it should command a hi-hat.  And when I make a mid-frequency sound ("kuh"), it should command a snare/clap sound.  I have a mic for my voice.  I have a MIDI-compatible drum machine for drum sounds.  What I needed was a voice-to-MIDI converter.  That is what I made.


Hardware.  For this voice-to-MIDI converter, I used an open-source audio processing device called a "Teensy Guitar Audio Pro" (TGA) from Blackaddr.  As the name implies, it is intended for guitar.  But, knowing that dynamic microphones share many qualities with guitar pick-ups, I knew that the device would work just fine with my old, cheap dynamic mic.  The TGA has tons of hardware features, but what's important for this hack is that it has a MIDI output.  What hackable guitar processor includes MIDI?  This is what makes the TGA the perfect tool for this hack.

Teensy Guitar Adapter Processes the Mic Signal to Generate MID Commands

Programmable.  The processor in the TGA is an open-source device that is programmable through the Arduino IDE.  This is perfect for me since many of my hacks are built around Arduino.  I have an old version of the TGA, which is built around a Teensy 3.6, which is 180 MHz processor with floating point support.  Newer versions of the TGA bump that up to a Teensy 4.1, which is 600 MHz!  Either way, the Teensy is great because there's an Audio-processing library and an active community to learn from.  The fine folks at Blackaddr also provide a bunch of example programs to help with TGA-specific features.

The Teensy Guitar Adapter is Powered by a Teensy 3.6

How Are the Sounds Different?  The main challenge for me was designing the audio processing.  How do I get the Teensy to automatically detect which sound I was making with my voice?  The first step is always to figure out what you, as the human, to understand what makes the sounds different.  A good way to do this is to make recordings of the three sounds ("boom", "tsst", and "kuh") and to compare the frequency spectrum of each.  


Frequency Spectra.  Using the TGA as an audio interface for my computer (thanks to Teensy's USB Audio features!), I plugged in my microphone and recorded myself beat boxing.  I then manually sliced up the recording and excerpted the first 50 msec of each sound sample.  I pulled the excerpts into Matlab and computed the average spectrum for all the kick sound ("boom"), hi-hat sounds ("tsst") and clap sounds ("kuh") that I made.  You can see the average spectra below.

Lows, Mids, and Highs.  After normalizing all the excerpts to the same loudness (I don't want to throw off my voice classifier just because I happened to be quite or loud), the plot of the spectra shows what is the same and what is different about my three voice sounds.  In their normalized form, the amount of low frequency sound is similar.  But, the mids and highs are quite different:
  • The "boom" sound for the kick has little mids and little highs. 
  • The "tsst" for hi-hats have little mids but lots of highs.  
  • The "kuh" for the clap has lots of mids and lots of highs.
Classify Based on Mids and Highs.  So, the mids and highs are the key.  The figure below plots measurement for each individual beatbox sound that I recorded.  I plotted each excerpt's mid-frequency energy on the horizontal axis versus its high-frequency energy on the vertical axis.  Notice how the three types of sounds nicely separate from each other!  This plot is the key to making the voice classifier. 

All The Pieces of the Voice Classifier.  Having figured out how to distinguish between the three voice sounds, we know what we need to do.  Once we detect that a voice sound is preset at all (such as by simply looking for the overall loundess of my voice), here are three steps of the classifier:

  1. Measure the mid and high frequency energy (via some sort of filters)
  2. Compare the measured mids and highs to the 2D plot above classify the sound
  3. Issue a MIDI command for the sound we want

Implementing the Classifier via Filters.  Based on the average spectra, it looks like I want a lowpass filter with a cutoff around 1200 Hz, a bandpass filter passing 1200 Hz to 3000 Hz, and a highpass filter with a cutoff at 3000 Hz.   Given the filter types available in the Teensy Audio library, I used the state-variable filter because it offers lowpass, bandpass, and highpass outputs.  To get a sharper frequency response, each "filter" is actually three of these filters in series.

Threshold Detection.  With the signals filtered into three streams (low, mid, high), I wrote a simple audio class to compute the RMS envelope of each signal.  After extracting he envelop, I compare the level to a threshold to detect when the sound is loud enough that we can assume that my voice is present.  That is a "detection".  There is a voice sound that needs to be classified into kick, hihat, or clap.

Classify.  Having run my three filters, I have three measured values for each detection: the low-frequency loudness, the mid-frequency loudness, and the high-frequency loudness.  I normalize for the overall loudness by dividing each value by the sum of the three values.  Then, for the mid and high frequency values, I compare them to my 2D plot shown earlier.  Where do they fall in this plot?  Depending upon where it falls, I issue a MIDI "note on" for the kick (note 36), hi-hat (note 42), or clap (note 39).

Tuning  Of course, the development of this hack did not go as smoothly as was implied here.  It took a lot of experimentation and tuning.  The final code is here on my GitHub. 


Having Fun. Once I got it working, it was fun to make deep 808 kicks with my voice.  It was fun to use my same voice sounds to trigger other drum sounds (like the cowbell!).  And, since the system simply outputs MIDI notes, I used it to drive my synthesizer.  If I had a sampler, it would have been fun to trigger silly sounds on the sampler using silly sounds from my voice.  If you try this yourself, let me know what fun you have with it!

Monday, September 2, 2019

DIY MIDI Breath Controller

Breath controllers are a difficult subject to bring up.  They have a bit of a bad reputation...perhaps because of synthesized saxophone sounds.  Breath controllers often induce people to roll their eyes dismissively.  It's kinda like how many people respond to keytars.  Are they awesome?  Or are they cheesy?  How can you know, if you've never played one?  Well, a buddy of mine started sending me links about DIY breath controllers (see Mixtela's MK1 and MK2).  He knows I'm a sucker for DIY.  So, with this as motiviation, I pulled together my own plan and made my own DIY MIDI breath controller.


Breath Controller?  The idea of a breath controller is that you use your pressure from your breath to control some aspect of your synthesizer.  The harder you blow, you make your synth louder, or you open its filter more, or you bend its pitch.  Some breath controllers are shaped like wind instruments and include both breath sensitivity and buttons (keys) to change notes.  Other breath controllers (such as mine) are simpler and just have the breath-sensitive part.  With only the breath-sensitive part, you control sound parameters on our synth, like having a breath-controlled mod wheel.

My Approach.  I'm choosing to have my breath controller use MIDI messages to control my synth.  Therefore, I'll need to (1) choose a pressure sensor, (2) connect it to some sort of electronics to read the signal, and (3) write some software to send MIDI messages to my synth.  Let's do it!




The Shopping List.   First, let's go shopping.  There are lots of ways to build this device.  Below are the components that I used:

  • Pressure Sensor: Honeywell NSCDRRN0001NDUNV.  This is a differential pressure sensor whose output voltage changes as pressure (positive or negative!) is applied.  The pressure range of this sensor is +/- 1 inch of water (about +/- 250 Pa).  It can be bought it from Mouser, but it's not cheap.  Cheaper sensors will probably work, too. 
  • Flexible Tubing: I used Tygon clear tubing.  To fit onto the sensor's snout, you need a short length of 1/16" ID tubing (here), but most of your length should be 1/8" ID (here).  You want that larger diameter so that you can push enough air through it to be comfortable.  Bigger tubing might be even better.
  • Electronics:  I used an Arduino Uno because I had one around.  You can probably use any hobbyist microcontroller board (including the Redboard or Metro) but you want one that'll mate to your MIDI Interface.
  • MIDI Interface:  I used the Sparkfun MIDI Shield.  I like that it has built-in pots so that I can adjust things while playing.  Note that it does not come with the header pins, so be sure to buy some...you should definitely buy stackable headers.
  • Prototyping Supplies:  I did my prototyping on a solderless breadboard.  I also used some little jumper wires that are typical in the Arduino world.   
  • Power:  During development, I powered the system from my computer's USB port.  But, when I was done, I wanted to be free from the computer.  So, I've been using USB power wall-wart like this one along with a standard USB cable.

Wiring It Up.  After assembling the MIDI shield and plugging it on top of the Arduino, I needed to figure out how to wire up the pressure sensor. After digging through the datasheet for the pressure sensor, I found the information I needed (copied it below).  It has three types of connections: power pin, ground pin, and two output voltage pins (and you can ignore one of them, if you want).  Easy.



Using the solderless breadboard and my jumper wires, I connected the sensor to the Arduino via the MIDI Shield's stackable headers:
  • Sensor Pin 1 to Arduino 5V
  • Sensor Pin 2 to Arduino analog input A2
  • Sensor Pin 3 to Arduino analog input A3
  • Sensor Pin 4 to Arduino ground
After adding the flexible tubing to the snout of the pressure sensor, the hardware is ready.


Arduino Software.  Once it is assembled, you need to write a software to command the Arduino to read the sensor and to issue MIDI commands.  There are lots of choices here, but at it's core, it is three steps:
  • An "analogRead" to measure the output of the pressure sensor
  • Arithmetic to convert the measurment to a valid MIDI value (usually 0-127)
  • A few "Serial.write" commands to send the MIDI message to the synth
In practice, things are modestly more complicated.  Really, though, the primary question is what MIDI message you want to send.  Everything depends upon that. 

Choose Your MIDI Command!  There are many ways to command your synth via MIDI.  You need to find out what MIDI commands your synth can respond to and what is easy for you to configure (three good choices are shown below).  On my synth, aftertouch is very easy to set up without any menu diving.  So, I chose to have my breath controller send aftertouch MIDI messages.  Later, I made it more complicated, but aftertouch is still what I use most of the time.  My code is available on my GitHub here.

From midi.org
Initial Disappointment.  Once I got my system working, I had to learn how to play a breath controller with my synth.  I quickly become bored because all I could make it do were relative slow filter sweeps or unusable pitch bends.  There was no way to give it articulation because it was simply about lung pressure...and my chest does not have much dexterity for quick motions.  Disappointment.

The Key is Airflow.   After some messing around, I had the idea to poke a hole in my tubing so that some air could flow through the tube and out the hole.  Once I did that, everything changed.  I quickly found that I could use very quick motions like tongue-stops on the tip of the tube (in my mouth).  Suddenly, it could respond quickly, like any other wind instrument.  Without the hole, tongue-stops had no effect because the sealed tube kept the pressure high.  With the hole, however, the air vents out when the tongue stops its end.  Therefore, the sensor sees a quick change in pressure and articulation is achieved.  It's so much more varied and expressive this way.  The vent hole in the tube is the key.

It's Fun.  With this modification, I found myself having fun with the breath controller.  Yes, I could still do slow swells on sustained pads.  But, now I could also articulate fast riffs, giving them a new kind of bounce.  Using the breath controller on repetitive arps, I could literally "breathe" life into them via breath-modulating the filter.  And, for single note work, the breath controller is great for contouring one's phrases in a way that is very difficult to do any other way.  So, while I wouldn't use a breath controller in every situation, it is a good time.  I recommend trying it.  And maybe even making it yourself!

Wednesday, April 6, 2016

DIY Ribbon Controller - CV

In sharing my work on a MIDI-enabled ribbon controller, a couple of the good folks at Muff Wiggler wanted more.  They wanted to see a CV-enabled ribbon.  So, as I'm always ready for more hacking, today I present for your enjoyment: my home-brew CV ribbon controller.


Switching from MIDI to CV:  This CV-enabled ribbon builds directly upon my MIDI ribbon.  It uses literally the same ribbon, which I built (like everyone) using a $20 soft-pot sensor.  Like my MIDI ribbon, This CV ribbon also uses an Arduino to sense ribbon and to generate the commands for the synth.  The main thing that is different with the CV ribbon is that I needed to add a digital-to-analog converter (DAC) to generate the CV signals that'll drive my old synths.

The only difference between the MIDI ribbon and the CV ribbon is how the Arduino outputs its commands.  The MIDI ribbon uses an Arduino "MIDI Shield" to send the MIDI messages whereas the CV Ribbon uses a DAC to generate the CV voltages.

Using a DAC:  A DAC is a device for generating arbitrary analog voltage signals.  You send it commands (such from an Arduino) and its output jumps to the voltage level that you desire.  They're very handy devices for synth hacking.  My experience is with the MCP4922, which is a 2-output, 12-bit DAC.  After refreshing my memory using its datasheet, I decided to wire the DAC to the Arduino as shown in the schematic.

The ribbon (left)  is wired to the Arduino (left-center).  The Arduino is wired to the DAC (right-center).  The DAC is wired to the CV outputs (right).  Easy.

Wiring the DAC:  From this schematic, I used a solderless breadboard to wire up my DAC.  I chose to use an Arduino Micro because it easily fits into the breadboard (unlike an Arduino Uno).  Wiriting software for the Micro is the same as for the Uno, so it's a trivial swap.  The wiring diagram below (go Fritzing!) shows my plan for wiring the DAC to the Arduino.  I added the headphone jacks to make it easy to get the signal in from the ribbon and to get the CV signals out to the synth.  For breadboarding, I like using this jack with this breakout from Sparkfun.

My wiring plan for the Arduino Micro and the MCP4922 DAC.  Power is supplied from USB connection to the Arduino.

Real-World Wiring:  Of course, once real wires are involved, it never looks as pretty as the plan.  The picture below shows my actual breadboard with its actual wires.  All the connections are the same, but the routing is different.  Also, I moved where I put the headphone jacks: the ribbon input is the one on the bottom right and the two output jacks are dangling off the back (one is black, the other beige).  Note my use of the blue rubber band to keep the output jacks somewhat contained.

The real-world wiring is never as nice as the plan.

Pitch and Trigger CV Signals:  For this hack, I'm generating three signals to control my synth: a pitch CV, a trigger (a.k.a. gate) signal, and a filter CV.  The pitch CV controls the pitch of the synth.  It's a signal that can take any value between zero volts (a low pitched signal) and 5V (a high pitched signal).  The trigger signal, by contrast, is simply low (0V) or high (5V).  It tells the synth whether the note is "on" or "off".  Since it is just a LOW/HIGH signal, it is generated by one of the Arduino's digital pins, not the DAC.

Filter CV:  The last signal that the system generates -- the filter CV -- controls the cutoff frequency of the filter.  Like the pitch CV, it can be any value between 0-5V, and so I use the 2nd channel of the DAC to generate it.  I added this capability to the system (like I did with the MIDI version) so that the filter opens up a bit as you play higher notes.  This is the same kind of interaction you'd get with the keyboard if you had the "keyboard tracking" turned up about half-way.  Adding this behavior made the ribbon feel more natural and more engaging.

In response to the ribbon, the Arduino+DAC generates three signals: pitch CV, trigger CV, and filter. CV 

Arduino Software:  With the hardware assembled, and with my CV signals decided, I wrote the software for the Arduino.  I reused my software for the MIDI ribbon and simply added the functions to drive the MCP4922 DAC.  My code is available on my GitHub here.  Having both the MIDI and CV functionality in one program makes it more complicated to read, but it gets the job done.

The Korg Mono/Poly has good flexibility for interfacing to external gear.  Here, my circuit is creating CV signals that I'm injecting to control the filter cutoff ("VCF fcM IN", on the left), to control the gating of the note ("TRIG IN"), and to control the pitch of the note ("CV IN").

Putting it All Together:  With the software written, and with the CV signals injected into the correct locations on the back of the synth (see pic above), I was ready to get to the business of playing.  Of course, it didn't work the first time,but after some debugging (should the Trigger signal be set high or low on the Mono/Poly?), I got it to work pretty well.  Interestingly, I found myself playing the ribbon differently when attached to my Mono/Poly than when it was connected to my Prophet 6.  I think that it had something to do with the CV vs MIDI.  MIDI is designed for discrete pitch instruments (like keyboards).  I feel that the continuous pitch of a ribbon is just better suited to CV.

My old Mono/Poly, with the magnet-backed ribbon just above the keybed, and with my magnet-backed breadboard controller in the upper-left.

Next Steps:  Now that I have a DAC working, it opens all sorts of possibilities.  A DAC could be used to generate audio signals directly, not just CV signals.  By directly synthesizing its own audio, I could make the ribbon a stand-alone instrument.  Yes, using these electronics to create a wavetable ribbon synth could very, very interesting.

Wednesday, March 30, 2016

DIY MIDI Ribbon Controller

In a previous age of the world (2011), I built myself a ribbon controller.  I used it to drive my Korg Mono/Poly via CV.  And it was good.  But, that was before "synthhacker" first awoke under the stars on the shores of Cuivienen.  Has its glory been forever lost?  No!  The ribbon lives again!  And it has been updated!  Behold:


The Overall Setup:  This ribbon is just a controller -- it controls a synthesizer.  It doesn't make noise itself.  Those black-and-white keys that are built into the synthesizer are also just a controller.  They tell the brain of the synth to make noise at fixed pitches.  My ribbon controller uses the synth's MIDI interface to tell the synth to make noise across a continuous spectrum of pitches.  More bendy.  More swoopy.  Fun!  My controller has two parts: the ribbon itself, and some electronics (Arduino +  MIDI Shield) to do the ribbon-to-MIDI conversion.



The Ribbon Parts:  The ribbon itself, I built a long time ago.  But, as stores on the internet never forget what you've ordered, I easily went back and looked it up.  The core of the ribbon controller is a 500mm-long "soft pot" (Sparkfun).  This is the part that senses where you touch.  Since it is soft and floppy, however, I also bought a 2-ft long strip of plastic (McMaster) to act as a backbone.  For the electrical connection to the ribbon, I used a headphone jack (Sparkfun) and a small perfboard (Sparkfun).  The only real innovation with my ribbon controller (there are lots of DIY ribbons out there) is that I also added a magnetic strip along its back (McMaster).  Since most of my synths  have a metal front panel, the magnetic strip is a great way of keeping the ribbon in place!

Components of the Ribbon Controller

The soft pot is on the top.  The magnetic strip (partly unrolled) is in my hand.

Assembling the Ribbon:  I started with the plastic strip.  Its edges were surprisingly shart, so I got out some sandpaper to smooth the edges.  Now it's much nicer to touch.  After cleaning off the sandy bits, I spray-painted the whole thing black.  When fully dry, I attached the magnetic strip and the soft pot, both via their adhesive backing.  Then, I carefully soldered the ribbon's terminals (don't melt the soft pot!) to the perfboard and then to the audio connector.  I wired the connector so that the "top" of the pot was to the tip, "bottom" of the pot was to the sleeve, and the "wiper" of the pot was to the ring.  Once it was all soldered together, I epoxied the perfboard to the plastic strip to make it all nice and solid.

Headphone jack is connected to the perfboard, which is connected to the soft pot.  The whole thing is epoxied to the plastic strip, for strength.

Arduino-MIDI Electronics:  The ribbon is just a potentiometer -- it needs electronics to interface to a MIDI synth.  After my previous project making an MIDI-to-trigger converter, I realized that I could re-use that exact same hardware for this ribbon-to-MIDI converter.  Repeating the recipe list from that project, my parts include an Arduino Uno, a MIDI Shield* from Sparkfun, some stackable headers, and a 3.5 mm stereo headphone jack (or maybe one like this).

(* Note: I used the old Sparkfun MIDI Shield but, presumably, the new model linked above works well, too).

Components for the "Brain" of the Ribbon Controller

Assembling the Electronics:  I soldered together the MIDI shield, including soldering on the stackable headers.  I then soldered some wires to the audio jack and soldered those wires (being sneaky) to the header pins sticking down from the MIDI shield (detailed soldering pics here).  Once it was all assembled, I connected the ribbon to the MIDI shield using a standard 3.5 mm audio cable.  I also connected a USB cable to my laptop so that I could power it and program it.  The photo below also shows the MIDI cable connected, but we're not quite ready for that, yet.

Connecting my ribbon controller to the MIDI Shield (the Arduino is under the MIDI shield).

The Ribbon is a Potentiometer:  Touching the ribbon (the "soft pot") is like turning the knob on a potentiometer to a particular spot.  If I touch it near the low end, it'll show a low resistance.  If I touch it near the high end, it'll have a high resistance.  The job of the Arduino, therefore, is to sense the resistance of the ribbon so that it knows what note to play.  In theory, pretty easy.  But, to get some details on how this works, I hooked used my setup to collect some actual data.

The Ribbon's Response via Arduino:  To measure the response of the ribbon with an Arduino, I used the setup described above, which has the wiper of the pot connected to one of the Arduino's analog input pins (A3).  The bottom of the pot is tied to ground.  I activated the input pin's pullup resistor (via pinMode(A3, INPUT_PULLUP)) and started reading ribbon values via AnalogRead(A3).  I printed the values to the serial port so that I could see them on the P and log them to a file.  Sliding my finger to different octave points on the ribbon, I made the plot below,

The AnalogRead() Values Generated by the Arduino when Touching the Ribbon at Different Spots.

Values When Not Touching the Ribbon:  The first thing to notice is what happens when *not* touching the ribbon: the ribbon shows a very high value.  The high value results from the fact that the wiper is floating when you're not touching the ribbon.  As a result, the pull-up resistor on the analog input pin is able to pull the value all the way to the maximum value (which is 1023 on the Arduino Uno).  So, it's easy to know when you're touching the ribbon versus non touching the ribbon -- just look to see if the value is near 1023.

Values When Touching the Ribbon:  The middle of the graph shows the values when I touch the ribbon between its bottom (C1) and its top (C4), Looking at the detailed values, the lowest value seen in my ribbon (C1) is about 12 whereas the highest value (C4) is about 339.  So, I know that I have to program the Arduino to map values between 13-339 to musical notes between C1-C4.

Touching the Ribbon To Record the Arduino's AnalogRead() Value at Different Locations.

Software:  After seeing how the ribbon responds, I wrote my Arduino software.  It's basically a big loop that reads the ribbon value, converts it to a MIDI note number, and sends those MIDI commands to my synth.  While it seems conceptually simple to do an AnalogRead() for the ribbon followed by a Serial.write() to send the corresponding MIDI message, it does actually take some thought to get it to respond the way that you'd like.  Also, to make the ribbon pitches change continuously (and not be quantized like with the piano keys), you need to compute and transmit all the pitch bend commands.  It takes some work to get it right.  If you're interested, my Arduino code is available on my GitHub here.

Linearizing the Response:  One tricky spot is if you want the pitch to track linearly with your finger position on the ribbon.  In my case, I found that the notes were too closely-spaced at the top of the ribbon and too widely-spaced at the bottom.  I didn't like that.  The key to linearizing the response is to recognize that the ribbon and the Arduino's pull-up resistor actually form a voltage divider.  Once you do the math on that voltage divider, you program the Arduino to better deduce the note you want given the apparent voltage at the soft pot's wiper.  It's not perfect, but it's much better than before.

I was lucky at how well the ribbon fits on the face of the synth.  I took the extra effort to make the software fit well, too.
Bend Range:  The ribbon is fun because you can use your finger to sweep through all the pitches in between the normal notes.  Since the MIDI messages assume a piano-like keyboard, you do these "in between" pitches by commanding a note to one of the standard pitches followed by commanding a pitch bend to get the in-between pitch that you actually want.  Ideally, you could set the synth so that its allowable amount of bend would span the whole ribbon.  Unfortunately, on the Prophet 6, the max bend amount is +/- 1 octave.  As a result, with my setup, I get a brief note discontinuity when I try to continuously slide across more than 1 octave.  This is a limitation of the synth, not my ribbon controller. (If the synth's software were open source, I could fix that!)

Wobbling Pitch (ie, Pitch "Noise"):  Another subtlety that I uncovered is related to the fact that one's ear is very sensitive to changes in pitch.  The issue is that any noise in the measurement of the ribbon value will directly translate into wobble (instability) in the pitch commands sent to the synth.  When I was powering my system from the laptop and when the laptop was running on battery, my system sounded great.  But, when I plugged the computer into AC power, the pitch wobbled a lot.  It was quite unpleasant.  My solution was to add a 33 nF capacitor between the ribbon's analog input pin and ground and to add some filtering in software (revised code is here).

Future Work:  It's pretty fun to have my ribbon controller working with my MIDI synth.  Sure, I don't like that there is still a note discontinuity that happens when I try to exceed the 12-step max bend allowed by the Prophet 6, but it's still quite fun.  (Maybe I can sweet talk someone at Dave Smith Instruments to help me out on that one remaining issue :).  Looking for other ways to improve the ribbon, I'm considering adding a DAC so that the the Arduino (or Teensy!) can directly create its own audio without needing to command an external synthesizer.  That'd be fun.  How about a ribbon wavetable synth!  Or, how about a ribbon FM synth?  Fun!

Follow-Up:  I also made a version of this ribbon that outputs CV signals.  Now it can drive my old pre-MIDI synths like my Korg Mono/Poly.  Check it out here!

Saturday, February 27, 2016

Replacing Key Contacts on Korg Mono/Poly

When I first got my Korg Mono/Poly off eBay, quite a few of the keys didn't play.  After some searching around, I tried some CaiKote on the rubber key contacts (as I described here) and it worked great.  When I bought a Korg Polysix off eBay, it had the same problem...and CaiKote saved the day again.  But, now that it's been a few years, some of the keys on the Mono/Poly have stopped working again.  Let's fix this problem for-real.  Let's replace the key contacts!

New Key Contacts from LA Synth Co

When I first had my problem with dead keys, I couldn't find anyone who sold new key contacts for these old synths.  So, I had to use the CaiKote to restore the old ones.  That was pretty cheap and pretty easy.  I now know, however, that it's a fix that only lasts a few years.  In that time, LA Synth Co has started to sell brand new key contacts that fit a bunch of old synths from that era.  Fantastic!  So, $100 later, I've got a complete set to fit my Mono/Poly.  Let's take the old girl apart and swap in these new parts!

First, remove the five screws on the bottom of the synth to release the keybed.  Then, remove the screws holding on the metal panel so that you can get inside.  Finally, unplug the keybed from the Mono/Poly circuitry

Getting started is pretty easy.  As shown above, I unscrewed the keybed and the main front panel.  Then, I opened up the synth and disconnected the keybed from the circuitry.  At that point, I was able to pull out the keybed.

The keybed has been removed from the Mono/Poly.

With the keybed out of the synth, you can look at the side of the keybed and see how, when pressing a key, the key smashes down a gray rubber button (the "key contact") onto the circuit board underneath.  It is through this contact that the brains of the synth know that the human has pressed a key.

You can see how pressing a key acts to press down the gray rubber key contact.

On the underside of the keybed, you can see the brown circuit board.  The key contacts are attached to this board.  We need to remove this board to get access to the key contacts.

The underside of the keybed has a brown circuit board.  Remove the screws to release the board.

Removing the screws, the brown circuit board is easily removed.  Flipping it over, you can see all of the gray rubber key contacts.  They come off simply by tugging on them.

Removing the circuit board, the gray key contacts are revealed.

Pulling on the gray rubber strips, the key contacts are easily removed.

With the old key contact strips removed, now was a good opportunity to get out a little alcohol and clean the contacts on the circuit board.  I probably should have used higher quality alcohol (only 70%?), or something better than a cotton rag for my scrubber, but this is what I had.

Time to clean the circuit board.

With the board cleaned, I got out the new key contacts and lined them up to make sure that I had the correct assortment -- they're not all the same and I was worried that I might not have been sent the right ones.  Luckily, LA Synth Co know what they are doing.  I had what I needed.  They lined up great and I attached them simply by pushing them on.

Getting ready to attach the new key contacts
The new key contacts are attached simply by pushing them on.

With the key contacts attached, I start putting the synth back together again.  First, I have to re-attach the key contact circuit board to the bottom of the keybed.  The only trick is getting the key contacts to fit inside their respective holes in the bottom of the keybed.  It isn't hard, but you do have to pay attention.

These are the holes on the bottom of the keybed into which the key contacts must fit. 

After getting the board onto the keybed and screwed together, I did a visual inspection and saw that one key contact wasn't seated correctly (as shown below).  So, I unscrewed the board and was more careful in putting them together.  The second time, all the key contacts were seated nicely.

Here, after assembly, one of the key contacts didn't seat correctly.  I simply took it apart and was more careful when I put it together again.

That's it!  The key contacts are done!  The only thing left to do is to put the synth back together again.  I have to put the keybed back in, screw it in, and screw the front panel back down.

Time to put everything back together again!

Fully re-assembled, I also to this as an opportunity to clean the keys and the front surface.  Looks great!

The re-assembly went easily.  I also used my rag and alcohol to clean the tops of the keys and the control panel.  She looks great now!

Plugging her in, they keys all work.  The joy!  Not only is it a joy to play an instrument that works, it's a real satisfaction to have fixed it myself.  Fixes don't really come any easier than this one.  Thanks LA Synth Co!

Friday, January 1, 2016

PCB For Polysix OTA Overdrive

Before today, I had made exactly one PCB.  It was a very simple design, yet it was still a painful experience.  I am not an expert -- that's for sure.  Yet, here I'm going to give it another go.  I'm going to dive in and design myself a custom circuit board.  This PCB is going to host my OTA Overdrive Mod for my Korg Polysix.  It'll contain an Arduino-controlled digipot, including my own Arduino as part of the same PCB.  Given my inexperience, this is pretty bold stuff.  I'm nervous and I'm excited.  Can I make it work?

Here's the PCB design that I made using Fritzing.  It's only a two layer board, but it looks awfully complicated for a newbie such as myself.  Does it have any chance of working?

Laying the Groundwork:  Over the last several posts, I've been figuring out most of the elements of this modification, including the digipot and the Arduino.  I know that I want to put all of those elements onto one board and fit it inside my Polysix.  My biggest remaining unknown is how to physically attach my components to the Polysix's circuitry.

Use One of the Built-In DIP Sockets:  A good trick is to re-use one of the DIP sockets that a used throughout the Polysix circuitry.  This is the same trick that I used when installing my mod to add velocity sensitivity to my Polysix.  For this OTA Overdrive Mod, I'm going to use the DIP socket that the OTA itself lives in (ie, IC20 on the KLM-368 "Effects" PCB).

DIP Socket and DIP Connector:  As shown in the picture below, I'm going to pull IC20 out of its DIP socket and I'm going to insert a pinned DIP-style connector in its place.  My PCB will solder to this pinned connector.  To reconnect IC20 into the circuit, my PCB will include its own DIP socket (and associated wiring).  My PCB will include the wiring to connect IC20 back into the Polysix's circuitry via the pinned connector.

I'm going to attach my PCB via the DIP socket for IC20.  It's great that the Polysix came with so many socketed ICs to enable this kind of hack.

Circuit Block Diagram:  Before diving into PCB design, it's important that I understand what it is that I want to do.  The block diagram below shows my overall approach for this PCB.  It shows the DIP connector and DIP socket, it shows the digipot that controls the overdrive, and it shows the Arduino-style microcontroller that controls the digipot.  It also shows the headers that I'll used to program the Arduino ("ICSP" and "FTDI") as well as a bunch of pins and headers that'll let me be flexible in how I choose to connect the various audio and synth control signals that I might wish to manipulate.

Here's a block diagram of what I'm hoping to build.  I want to include lots of pin headers so that I have plenty of flexibility for modifying my own circuit once it's built.

Which PCB Layout Software?  In my previous attempt at a PCB design, I used CadSoft Eagle This is the PCB layout software common throughout the Maker community, probably because there is a free version that is pretty capable.  Both Sparkfun and Adafruit seem to think that it's a good choice for their open source designs.  I didn't like it, though.  I thought that it was hard to learn and didn't promote self-discovery.  I felt like trying a new tool instead.  I almost went for a cloud-based software tool like Autodesk's 123D Circuits, but at the last moment I ended up downloading and trying Fritzing.  I found Fritzing to be very approachable, and unlike 123D Circuits, it's been around long enough for the forums to have a good number of threads for me to learn from.

To layout my PCB, I tried Fritzing.  It seemed much more approachable than CadSoft Eagle.

Parts then Schematic then PCB:  One should only start a PCB design when you already have a good idea about what you want to build.  That's why I started with the block diagram shown earlier and that's why I spent so much time breadboarding the key elements of my circuit in previous posts.  Once you know what elements are going to be in your circuit, only then should you start with the PCB design software.  PCB design software generally follows a three-step process: (1) choose the parts for your design, (2) draw your schematic using your parts, (3) layout your PCB based on your schematic.  OK, here we go...

Step 1A: Choosing my Parts.  Looking back at my block diagram, my major parts are the LM13600 OTA, the AD5262 dual digipot, and the ATMega 328P microcontroller.  For minor parts, there will be a bunch of resistors and capacitors, some pin headers, and an oscillator/clock for the microcontroller.  Fritzing is already well stocked with parts for me to use for these minor components.  So, it's the major components that I need to focus on.  Lucikly, Fritzing already has the version of the ATMega 328P that I want to use (the surface mount TQFP package).  What Fritzing doesn't have is the LM13600 OTA or the AD5262 digipot.  I needed to make these two parts myself.

Step 1B: Creating the Missing Parts.  Making parts is often the hardest part of using PCB design software.  It's such a pain.  I figured it out through a combination of the Fritzing documentation plus lots of trial and error.  The key to making any progress is that Fritzing already had built-in components of the right size.  They weren't the correct part, but they were the correct size (they already had a TSSOP-16 like my digpot and they already had a DIP-16 like my OTA).  As a result, my task was simply to copy the existing parts and re-name the pins.  Through a combination of the built-in part editor (see screenshot below) and a text editor (to change the labels on the SVG graphics), I was able to create my two parts.  If you're interested, I've shared my Fritzing library on my GitHub here.

One of the hardest part of designing one's own PCB is creating models for the parts that don't come in the standard library. Here, I'm making a model for the AD5262 digipot, which is a TSSOP-16 package.  I also did this for the LM13600 OTA, which is a DIP-16.  This process always seems harder than it should be.

Step 2: Create the Schematic.  With my parts created (go me!), I started creating the schematic.  My final schematic is shown below.  In the upper left, you can see a block corresponding to the DIP connector that'll be used to connect this PCB to the Polysix's KLM-368 PCB.  You can see that most of the pins of the DIP connector get routed down to a DIP socket that I'll put on my board to host the LM13600 OTA chip itself.  You can also see that I've broken out few of the LM13600 pins so that I can manipulate the signals (ie, enable overdrive) with the other parts of my circuit.  The rest of the schematic shows the other elements of my circuit -- in particular, you can see the block for the digipot (bottom left) and the big block for the ATMega 328P microcontroller (center).  The critical connections for the 328P (such as the reset circuit) I copied from the Sparkfun Arduino Pro.  That Sparkfun design is also where I learned the layout for the two programming headers (the FTDI and the ICSP headers).

This is the schematic of all the elements that will go into my PCB.  This defines all the connections between the different circuit elements.

Make it Hackable.  As already mentioned, this design breaks out extra Arduino pins, includes some unconnected "spare pins", and includes a second set of pins for both pots in my digipot.  All of these extra access points are to enable future hacking of my own PCB.  I wanted to include flexibility the design of my PCB so that I can make different connections between the OTA, the digipot, and the Arduino.  Who knows what kind of mods I might dream of in the future?!?  With these extra pins, it'll be easier to have fun explorations.  You've got to be prepared to be spontaneous!

Step 3: Layout the PCB.  With the schematic complete, I started the PCB layout process.  I placed my components onto a notional PCB and started laying wires ("traces") between them.  Below is a screenshot showing all of the parts on a notional PCB outline.  I've got about 2/3rds of the traces complete.  To make a trace you simply choose which side of the PCB you want (top or bottom) and then right-click on one of the "air wires" to create the actual trace.  Because the default trace is pretty thick, I would click on the trace and, in the "Inspector" window pane on the bottom right, choose a thinner size like 12 mil.  Finally, click and drag points on the trace to manually route the trace where you want it.  If a trace needs to jump between layers to avoid existing traces, you create a "via" between the layers by right-clicking on the desired spot on the wire.  This is easy!

This is the PCB layout view in Fritzing.  I'm about 2/3rds complete in laying out the board.
Surface Mount vs Through Hole:  I'm not very experienced with surface mount parts (though I have soldered this TSSOP digipot before), so most of my parts in this design are through hole parts (PTH).  The only two surface mount parts (SMT) are the digipot and the ATMega 328P.  In laying out the PCB, the main issue with mixing PTT and SMT parts is that the grid size (which helps keep your traces orderly) really wants to be different for the PTT components vs the SMT components.  For the PTT parts, grid sizes of 0.1", 0.05" or 0.025" all work well.  By contrast, the TQFP package for the ATMega 328P works better with a 0.8 mm (0.0315") grid.  Annoyingly, for the TSSOP package for the digipot, the best grid size is yet a different value (0.0254").  It gets very tedious manually switching between the different grid sizes.

Finishing the PCB:  Once I got all the traces where I wanted them, I started adding text to the PCB so that I could know where to connect my different signals.  I also put a name and date on the board so that I could know which iteration of he board I was using (surely, I would need to iterate the board to fix errors).  Finally, on the bottom layer, I told Fritzing to do a "copper fill".  This is a common technique to try to reduce unwanted noise that may be transmitted between closely spaced circuit boards (such between this PCB and the Polysix KLM-368 that'll be right underneath it).  A screenshot with my final PCB is shown below.  I shared my Fritzing design files on GitHub here.

Still in Fritzing, I have finished my PCB design, including a big copper fill on the bottom for the ground plane.

Design Rule Check:  Throughout the PCB layout process, I would periodically use the software's built-in tool for confirming that my traces were not overlapping with anything else on the board.  The traces on a PCB can get pretty convoluted, so using an automated tool is a great benefit.  This tool is called the "design rule check" (DRC) and is included with almost any PCB design software.  In Fritzing, when I'd run the DRC, I'd get a big pile of error messages like shown in the window below.

The "design rule check" (DRC) gives lots of errors for my design when using the default DRC rules.

Shrinking the Keepout Distance:  When I would try to find these errors in my PCB, I often saw no issue.  The traces (especially around the SMT components) may have been close, but they were not interfering.  I was confused.  The answer is that the default rules used by the DRC algorithm were too tight for my small SMT components.  When I changed the DRC "keepout" distance from its default 0.01" value to a smaller 0.008" value (see screenshot below), almost all of my errors went away.  The remaining DRC errors were legitimate problems, which I found and fixed.

With such small SMT components, you need to reduce the "keepout", thereby telling the DRC algorithms that it is OK if the traces are close together.  I dropped the keepout from 0.01 inches to 0.008 inches.

Shrinking the keepout (plus fixing some actual errors in my PCB) eventually lets me pass the DRC.

Export for Production:  Once my design was complete and the DRC results came back clean (see screenshot above...I was so happy when I saw this message!), it's time to export the design so that it can be sent out to be printed.  The exported production files are often called "Gerber Files".  In Fritzing, I chose to export to "Extended Gerber Files".  It created a collection of files that define the top and bottom copper traces, the drill locations for the vias and the PTT components, the top and bottom solder mask, and the top and bottom silkscreen (ie, text and graphics).  These are the files that the printing company need to make the PCB.

Tailor for Your PCB Print Company:  Unfortunately, every PCB printing company is a little different in their requirements for the Gerber files.  As a result, the Gerbers may have to be tweaked specifically for different printing companies.  For me, I chose to use OSH Park to print my board.  Looking at their requirements, the Fritzing Gerber files were all fine, except I had to change my drill file to end with ".xln".  That's all I had to do!  My Gerber files are zipped up on my GitHub here.

Send to Printer:  I uploaded my zipped Gerber files to OSH Park.  Their automated system interprets the files and then shows you illustrations of your design so that you can confirm that they interpreted your files correctly.  In my case, the top and bottom views of my board are shown below.  They look pretty good.



Top and Bottom View of my PCB as Generated by OSH Park.  $21.75 for three.  Let's get it printed!

Order the PCB:  In general, the cost for PCBs is driven by the number of layers (a two-layer board is cheaper than a six-layer board) and by the area of the board (a smaller board is cheaper than a large board).  I tried to make my board pretty small.  I was hoping to get under $20, but I only got it down to $21.75.  Given that OSH Park sends you three copies of your board for that price (plus free shipping!), I'm still pretty happy.  Anyone can order my board from OSH Park here.

Waiting:  So, now I wait for the board to get printed and sent to me.  It generally takes 2-3 weeks.  I'm so excited to get it.  Waiting is agony!