Saturday, March 23, 2013

Polysix - Arduino and DAC to Bend the Pitch

Earlier in the week, I'd made good progress on getting the new keybed and keyscanner into shape so that it could drive my Korg Polysix via an Arduino.  While it was exciting to simply get the keybed to work in the Polysix, that was not really my goal.  My real goal is to use the new keybed to enable aftertouch (and eventually velocity sensitivity) in my Polysix.  Now is the time when I make the bits between the Arduino and the Polysix so that the aftertouch actually does something.  This is where I make the Arduino have arbitrary control over the pitch of the Polysix's voices.

Creation is a Messy Process!
The first step is to make sure that I have a clear idea of what my approach is going to be for the aftertouch to command pitch on the Polysix.  Below is a block diagram showing the major components that I settled on and how they connect.

Here's How I Am Implementing Aftertouch
Listening for MIDI Aftertouch:  User, of course, is interacting with the keyboard via the keybed.  The keybed is connected to the keyscanner (both from Keyparts UK), which looks for which notes are pressed on the keybed.  The keyscanner outputs the notes via a MIDI stream, which is received by an Arduino Mega.  The MIDI stream includes the "note on" and the "note off" messages, as one would expect.  The keyscanner, though, also reads the aftertouch pressure sensor built into the keybed.  Therefore, the MIDI stream also contains the aftertouch commands.  So, after getting the keybed and keyscanner and Arduino hooked together, I used the Arduino to listen to the MIDI stream to ensure that the aftertouch messages were present.  They weren't.  After exchanging a few emails with the good folks at Keyparts, they sent me a new software build for the keyscanner (uploaded to the keyscanner using a very nice and very simple method via USB), which solved the problem.

Aftertouch for Vibrato:  With the aftertouch messages successfully reaching the Arduino, now the question is what to do with the messages.  In modern synths, the aftertouch can be mapped to a range of functions.  For me, I want to start simple -- I just want the aftertouch to create vibrato, much like what the mod wheel currently does.  The key is that I somehow need to command a smoothly-changing pitch from the Polysix.  I could implement this in a whole bunch of ways (and I even tried a couple).  Instead of going through the whole list that I came up with, I'm just going to talk about what ended up being successful.

Polysix Pitch CV:  First, let's talk about how the stock Polysix creates each note's pitch.  In the polysix, the sound that you hear starts with the VCOs (one for each voice).  The VCO is told what pitch to create via an analog voltage signal that is between 0 to +5V.  This is the "Pitch CV".  In a stock Polysix, the 8049 key assigner has 8 output pins, which are connected to an R-2R ladder circuit (a type of digital-to-analog converter) to create the Pitch CV (see schamtic below).  For each note being played by the Polysix, the 8 output pins of the 8049 are set in a particular combination of high (5V) or low (0V) states so that the correct CV value is created for the pitch that you want.  While it is a very nice system, it can only generate pitches that are precisely on the note you want -- it cannot create any pitches that are in-between notes.  As a result, I cannot exploit this circuitry to create the smoothly-varying pitches that I want for my aftertouch.

R-2R Ladder Used by the Polysix to Make Each Note's Pitch Control Voltage (CV)
DAC for Adjusting Pitch:  My solution is to use my own digital-to-analog converter (DAC) to create as smoothly-varying as a Pitch CV as I can. Granted, any DAC can only produce discrete voltages, but if the DAC has sufficient resolution (enough bits) then your ear will be tricked into hearing smoothly-varying pitch.  For expediency, I chose to use this product from Adafruit, which is an MCP4725 12-bit DAC mounted on a nice break-out board.  It's a fine device, but the best part is that Adafruit provides an easy-to-use software library for use with the Arduino.  It took zero debugging to get this to work.

DAC to Generate Pitch CV:  Ideally, I would have been able to use the DAC alone to be my sole device for create the Pitch CV in the Polysix.  In theory, it should have made the R-2R ladder unnecessary.  Unfortunately, when I actually tried to use the DAC this way, the pitches didn't sound right and weren't stable as I'd like.  So, either 12-bits isn't enough resolution for the full 10 octave span, or my use of it wasn't quite right.  Regardless, I abandoned the use of the DAC as sole generator of the Pitch CV and went to a hybrid approach.

Using both the DAC and the R-2R Ladder:  In my hybrid approach, I return to using the R-2R ladder for the main part of the Pitch CV and use the DAC to provide a tweak to the Pitch CV to bend the pitch one way or the other.  To implement this hybrid approach, I needed to find a summing junction in the Polysix circuit that could be used to mix the DAC's CV with the R-2R's CV.  After trying a bunch of spots (including where the bend wheel injects its signal), I settled on injecting the DAC CV right after the R-2R ladder, at the junction of R33 and R34 (see schematic above).

Connect via 10K Resistor:  An important detail is that the 0-5V DAC signal must connected to this location via its own 10K resistor.   This makes the electrical summing at this junction scale correctly.  The reason that you need a 10K is that, for simplicity, I'd like our 0-5V DAC output to have the same pitch scaling as the 0-5V output of the R-2R ladder.  Since the R-2R ladder connects to this summing junction via 10K, then we should connect via 10K, too.  A second reason for the 10K is that the R-2R ladder uses +5V to represent the lowest note and 0V to represent the highest note.  So, we can call +5V to be the reference voltage with the higher pitches going down from there.  This is fine except that the VCOs can't work with that signal.  They need something more like 0V with higher pitch going up from there.  So, the designers included this summing junction using the -15V to strip off the +5V reference (see how the ratio of 10K to 30K is important!) and, by entering at the "-" input, the sign of the CV gets flipped.  It just so happens that this summing junction is a great place for us to inject our DAC signal as long as we connect via 10K and as long as we make our DAC output with a 5V reference where increasing pitch requires the DAC to put out a lower voltage value.  The 10K resistor is easy, and the rest we do in software on the Arduino.

Real-World Implementation of Hybrid Pitch Control Via the 8049 Pins Plus DAC
Wiring it All Together:  The picture above shows the messy real-world wiring for all of these bits and pieces.  It shows the rainbow-colored ribbon of wires going from the Arduino to the 8049 socket.  It also shows the DAC signal getting injected at R33/R34 via the black clip-lead.  Sure, it's ugly, but it works!  Well, I should say that, after a whole bunch of debugging of my software whatnot, it works!  I can receive MIDI messages from the keyscanner, interpret them in the Arduino, command the main part of the pitch via the 8049 socket, and command pitch adjustments (such as vibrato) via the DAC.  Nice!

Next Steps:  As shown in the very first picture at the top of this post, my system may function, but it is barely holding itself together.  Also, you'll notice that I've not yet included any demos...that's because there is still a big distance between being able to generate arbitrary pitches (including those critical in-between pitches) and getting a useful aftertouch-driven vibrato.  So, in my next posts, I'll talk about implementing the aftertouch vibrato (with portamento as a bonus!) and about my approach for cleaning up all that wiring so that the installation is a bit more permanent.  Stay tuned!

Update: Here's a demo once the synth was buttoned-up for the first time
Update: Mounting the Arduino in the Polysix
Update: The flexibility of this system also let me add detuning to my Polysix

No comments:

Post a Comment