Sunday, April 28, 2013

Mono/Poly - Amount of Detuning

In the process of adding detuning to my Korg Polysix, I spent a bit of time looking in detail at the detuning on my Korg Mono/Poly.  I've always liked the sound of the Mono/Poly's 4-voice unison with the Detune knob cranked up a bit.  So, as I was setting up the detuning functions on my Polysix, I looked at the detuning on my Mono/Poly to act as a guide.  This is the story about what I found...

Mono/Poly VCO2 with Maximum Detuning -- Flat by 30-35 cents.

I started my investigation experimentally.  I put the Mono/Poly in Unison mode and locked in a "C" using the Hold button.  Using each voice's Level knob, I listened to the pitch of each voice by itself.  By turning the Detune knob, I could hear what the detuning did to each voice.  To my surprise, the Detune knob had no effect on VCO1 or VCO3 -- it only affected VCO2 and VCO4.  At this point, if you look at the block diagram in the Mono/Poly service manual (see the figure below), it clearly shows that Detuning only affects voice 2 and 4.  I had never noticed this before.  I found it to be an interesting design choice by the Korg engineers.

Block Diagram from Mono/Poly Service Manual.  Detuning is only on VCO2 and VCO4.

My next goal was to quantify the amount of detuning that is generated by the Mono/Poly.  Looking at the schematic (see the bottom of page for the KLM-357 PCB), the circuitry involved with distributing and scaling the detuning control signal is too complicated for me to figure out quickly.  So, instead, I returned to my experimental approach and just measured the out-of-tuneness generated by the detune knob.

Mono/Poly VCO4 with Maximum Detuning -- Sharp by 20-25 cents.

I found that with the Detune knob set to maximum, VCO2 was driven flat by 30-35 cents and that VCO4 was driven sharp by 20-25 cents.  While it's somewhat interesting that the pitch deviations are slightly different for the two VCOs, I'm thinking that the difference is not purposeful and is actually just due to imprecision in the circuit components.  What I think is more interesting is that they chose to do a balanced de-tuning with one voice driven sharp and another voice driven flat.  Taken as an ensemble, therefore, the overall pitch of the four oscillator cluster is basically unchanged for any setting of the Detune knob.

Compare this approach to your more typical 2-oscillator-per-voice monosynth or polysynth.  Whether it's an old Minimoog or a Prophet-5, it is my impression that detuning is usually effected by changing the pitch of just the 2nd oscillator while leaving the 1st oscillator at the original pitch.  If this is true, it means that the ensemble of the two voices together is always a bit sharp or a bit flat.  Since these other synths are wonderful instruments and people love them, this unbalanced detuning must be an acceptable approach...but I've always felt that the detuned sound of the Mono/Poly just felt more "right".  So, in adding detuning to the Polysix, I chose to use the balanced detuning approach.

Due to the limited number of knobs and switches on the Polysix that are seen by my replacement Key Assigner (ie, my Arduino), I don't have a knob that I can dedicate to the Detune function.  Instead, I'm going to use a push button to turn the Detuning "on" with some default detuning factor.  I did include a method to adjust the amount of detuning (a complicated press-the-button-while-turning-the-knob combination), but I'd like to get the default detuning correct so that adjustments are usually unnecessary.

How much detuning to I want to be my defualt?  On the Mono/Poly, when i'm really getting the party started, I like to set the Detune knob to 5-6, which is 50%-60% of the total amount of detuning available on the Mono/Poly.  Given that full detuning is (take the average of VCO2 and VCO4) is about 27 cents, my target detuning amount for the Polysix should be about 14-16 cents.  The Polysix has six voices to detune, so I chose to detune two voices by 14-16 cents (one sharp and one flat), two voices by 7-8 cents, and two voices were left unchanged.  I then coded these values into my detuning routines on my Arduino and, as you can see below, I got 15-20 cents...pretty darned close to my 14-16 cents target!

Detuning Amount on my Polysix...about 15-20 cents.  Just what I wanted!
Like you can see in my demo video, the detuning works well on the Polysix -- I find the sound very engaging.  My experience with the Mono/Poly was really helpful in tweaking the detuning so that it sounds right.  Thank you Mono/Poly!

Saturday, April 27, 2013

Polysix - Adding "Detune"

After adding the hardware and software to implement aftertouch vibrato and portamento, I realized that I could command the Polysix to do all sorts of arbitrary pitch-manipulation effects.  With just a little bit of additional software, I could do pitch bends, pitch wobbles, pitch slides (hence the portamento), pitch transposition, or...wait for it...pitch detuning.  I love the detuned unison sound on my Mono/Poly and now I can get it on my Polysix!

It should be noted that the Polysix already has a little detuning purposely built into its Unison mode.  The circuit below is on the KLM-366 PCB and is only active in Unison mode.  Via voltage dividers (R120-R122 per voice combined with R116 for all voices), this circuit generates a small voltage that is used to shift the pitch of each voice to be a little sharp or a little flat.

Polysix's Built-in Detuning Circuit for the Unison Mode
By looking at this piece of the schematic, it looks like this circuit leaves Voices 1 and 6 unchanged.  It appears to shift Voices 2-4 up or down by between 16 and 33 mV.  The schematic says that the pitch scale is 5V/oct at this point, so the per-voice pitch detuning is about 4-8 cents (4-8% of one half step).  While that's enough to give a nice little swirl to the Unison mode, it doesn't give that meaty, fat detuned sound that has become popular in some electronic dance music styles.  I intend to change that.

In terms of approach, one could simply modify the existing circuit.  By replacing R116 with a bigger resistor (say 400-600 ohms), the detuning would get much more intense.  It would still be a fixed amount of detuning, but it would be a very easy modification.  The down side is that it is not adjustable (unless you wired in a potentiometer) and that it only applies to Unison mode -- it is not usable by Chord Memory mode.

Since I already have my Polysix modified with an Arduino and a digital-to-analog converter (DAC), I can do arbitrary pitch shifts and pitch bends on a per voice basis in any of the Polysix's modes of operation.  That's a lot of pitch-mangling power.  So, I wrote a little bit of software that, when I commanded the Arduino to effect "Detuned Mode", it would command a slight pitch shift to each of the Polysix's voices.  How much pitch shift per voice?

Well, following from the Polysix's built-in detune, I left two of the voices at normal pitch and bent the other voices in pairs (one up, one down) to different degrees.  The overall scale factor for the detuning I left as a variable that I could adjust on-the-fly so that I could control how much detuning I wanted.

Spectrogram of Output of Polysix While Adjusting the Amount of Detuning
For my user interface, I've temporarily mapped "Detune Activate" to my Polysix's arpeggiator button.  Pressing the arp button activates or deactivates the detuning.  Then, I can control the amount of detuning by holding down the arpeggiator button and turning the arpeggiator's "speed" knob.  My Arduino sees the button being held and sees the knob being turned and interprets that as a command to adjust the detuning.  It works great!  The spectrogram above really shows how the voices spread apart as the amount of detuning is increased.

How does it sound?  Well, the video is a demo of the audio coming out of my modified Polysix.  At the very beginning, you hear me load up the six voices playing the same note.  I lock in the six voices using the Chord Memory button. You hear that the voices are in pretty good unison.  Then you hear me kick in the detuning.  I like it a lot.  Yes.  A lot.

Thanks for reading!

More Info: Choosing my Polysix's default detuning amount based on the Mono/Poly
More Info: Disabling the Polysix's built-in detuning to improve the control over the detuning amount.
Update: I shared my Arduino code here.

Sunday, April 14, 2013

Portamento Voice Spreading from the Mono/Poly

Getting aftertouch and portamento hacked into my Korg Polysix felt like a pretty good achievement.  Now comes the part where I tune their response so that they feel just right.  Last time, I spent some time adjusting the feel of the aftertouch.  This time, I'm tuning the feel of the portamento.  Specifically, I'm stealing some ideas from my Korg Mono/Poly to make the portamento more exciting and more engaging.

When I first implemented portamento, I coded it up as quickly as I could, which meant that I kept it as simple as possible.  I wrote a nice pitch-slurring portamento function for my Arduino key assigner, the core of which boils down to equation below.

change_in_note = (desired_note - current_note) / time_constant;
current_note = current_note + change_in_note;

In my Polysix, the Arduino's job is to continually looping over each voice to update its pitch (and whether it is "on" or "off").  Based on the last MIDI note received from the keyboard, the Arduino knows what the desired note is for each voice.  Because of the portamento, though, we need to transition from the current note up to the desired note.  As the Arduino loops over each voice (returning to a given voice every 6 ms or so), it updates the pitch of the voice using the equation above.  Since all six voices use the exact some portamento equation, they all slide in the exact same way.  Easy enough.

The result of this portamento approach is shown in  spectrogram below (time on the horizontal axis, pitch on the vertical axis).  This spectrogram was created based on an actual recording from my Polysix with all six voices active and set to a "C".  I then step from C1 up to C4.  As you can see, the pitch transition is nice and smooth from low to high (nice exponential!).  It sounds nice and smooth, too.  The problem, though, is that it's too "nice" and too "smooth"'s a bit boring.

Output from Polysix, Initial Portamento Algorithm.  6 Voices.  Smooth Shift from C1 to C4.  
On my Korg Mono/Poly, the portamento sounds much more exciting and engaging.  Why?  I don't know why.  To figure out why, I made a recording of the Mono/Poly and made a spectrogram.

Output from Mono/Poly with Portamento.  4 Voices.  Smooth Shift from C1 to C4.
How is it different from the spectrogram of my portamento on the Polysix?  Well, a careful eye will see that each spectral line gets fatter during the transition from low to high.  What's going on there?  What's making it fatter?  To figure that out, let's zoom out and then plot what's happening to the higher frequencies during this portamento slide.

Zoom to Higher Frequencies Where the Mono/Poly's Voices Are Spread by the Portamento.
Up at these higher frequencies, the harmonics are finally spread out enough for the spectrogram to have enough resolution to see what's happening.  And what do we see?  We see that the four individual voices of the Mono/Poly are getting spread out during the slide up to the new note.  They aren't playing one uniform pitch during the slide -- they're playing four different pitches during the slide.  Eventually, the four voices settle onto the same pitch, but during the transition they're all different.  That would certainly make for a more interesting sound!

Looking at the schematic for the Mono/Poly (KLM-354), you can actually see that the designers purposely used different capacitor values in the portamento circuit for each voice.  This means that each voice has a different time constant (ie, speed) for its portamento pitch changes.  That's cool!  Different time constants for each voice?  I could do that in my portamento equation!

Looking at the spectrograms for the Mono/Poly, I see that the slowest pitch change takes about 30-50% longer than the fastest pitch change.  So, that means that the time constants differ by 30-50%.  In my portamento equation, that means that "change_in_note" needs to be scaled different for each voice so that they don't all move together.  Below is one way of making the note change be voice dependent with fixed-point math.  This will result in the slowest voice taking 42% longer to get to its steady value compared to the fastest voice.

int voice_time_constant = time_constant;
int spread[] = {12 13 14 15 16 17}; //spread the voices!
voice_time_constant = (voice_time_constant * spread[voice_index]) / 12;
change_in_note = (desired_note - current_note) / voice_time_constant

When I implement these equations in my Arduino portamento routine, here's how the Polysix responded.  Looks pretty good!

Revised Portamento in my Polysix.  6 Voices.  Notice the Spreading of the Voices!
So, how does it sound?  You can hear it for yourself in the YouTube movie at the top of this post.  I think that it sounds far more exciting and engaging than the original portamento algorithm.  I really like the spreading of the voices.  To my ears, it sounds fantastic.  Does anyone know if other old analog synths purposely spread the voices in this way?  Or, was the Mono/Poly unique?

Next Step: The voice spreading for the portamento made me realize that I could add detuning to my Polysix!

Tuesday, April 9, 2013

Polysix - Aftertouch Curves

After the success of simply getting the aftertouch system working on my Korg Polysix, now comes the effort to tune the response of the system so that the *feel* of the aftertouch is just right.  The feel of the aftertouch has a bunch of components: the physical resistance of the keybed, the force needed to initiate the aftertouch, and the sensitivity of the aftertouch to increasing pressure.  This last bit is defined by the "response curve", and it's the creation of my own response curve that I'm focusing on today.

Gathering Aftertouch Data via my Arduino Mega (the Blue Board in the Back)
The first step in tuning the aftertouch response is to be clear how aftertouch works in my system.  My new Fatar keybed (bought from Keyparts UK) has the aftertouch pressure sensor built-in.  This analog sensor is a long force sensitive resistor whose resistance drops when pressure is applied.  The sensor strip is plugged into the keybed scanning electronics (also from Keyparts UK).  The electronics include some sort of circuit that senses the resistance of the strip and generates a MIDI aftertouch message as pressure is applied.  The MIDI message includes a data field who's value is increases with increasing pressure.  What this sensor looks like, or how they convert their measured value into a MIDI data value, I'm not sure...but it has a strong effect on how the aftertouch feels.  It is especially important for defining the force required for the onset of the aftertouch effect.  Currently, I have no control over this part of the aftertouch response.

Once the electronics generate a MIDI aftertouch message, it is conveyed to my Arduino Mega via the Arduino's built-in TX/RX serial connections.  When the Arduino receives an aftertouch command, it induces pitch changes (vibrato) in the Polysix.  The magnitude of the vibrato is proportional to data value in the aftertouch MIDI message.  So, more key pressure generates a MIDI message with a bigger data value, which causes my system to put more vibrato on the pitch.  Easy.  But to be musically useful, the amount of vibrato needs to be controllable via the amount of force that I put on the keybed (not just ON or OFF), which means that the scaling between key force and vibrato response needs to be just right.

So, to get that scaling "just right", we need to get quantitative.  I need to record the actual aftertouch values generated by my system as I press on the keys.  Since I've got the Arduino in the system, I'm able to easily echo the MIDI aftertouch messages through the Arduino to my PC for logging and analysis.  Below is a plot of the aftertouch data values logged by my PC for three key presses.

As you can see, the aftertouch values span 0-127, which the full range allowed in the 7-bit space afforded by aftertouch MIDI message.  The next thing to notice how steep the curves are at the beginning and end of the each key press.  Being very steep means that my vibrato comes on strongly and suddenly.  My goal is to smooth that out so that I can have better control over more subtle amounts of aftertouch-induced vibrato.

My approach is to take the in-coming aftertouch value and to re-map it to a new value using my own aftertouch response curve.  The new response curve will be shaped to reduce the slope of the onset of the aftertouch.  Since I don't have the ability to set the response curve inside the keyscanning electronics (yet), I will have to implement the new response curve in the Arduino.  Fine.  But what response curve should I use?  I don't know.  We'll have to try some out.

Below is one of the first candidate curves that I tried.  It is simply two linear segments stitched together.  For small aftertouch values (like the onset), the slope is reduced so that the onset is more gentle.  This sounds like what I want.  The plot on the right shows the data from one of the key presses from the graph above.  The blue curve is the raw data.  The green curve is the re-mapped data.  Note that, yes, the steep onset is reduced, but I don't like that flat plateau that follows the onset.  That plateau will feel like a dead spot where nothing happens.  That isn't good.  Pressing harder should give a stronger response.  This is a Fail.

My next attempt at a new response curve was just a shot in the dark.  I tried an exponentially shaped curve because I knew that it would have a gentle slope at the beginning of the response and that it would smoothly transition up to its steeper portion (see the left-hand plot below).  Sounds good, right?  Unfortunately, as you can see in the right-hand plot, it's onset is far too gentle and its output stays low for far too long.  Then, finally, towards the climax of the keypress event (when the force is highest), the response suddenly leaps relatively from a low value up to the maximum allowed value.  Bad.  Again, Fail.

I then tried a whole bunch of other curves.  Lots and lots.  You can see many of them plotted together in the figure below.  Some of them looked decent enough on paper to be worth trying on the Arduino.  So, I coded them up as a simple look-up table and gave them a test drive.

After trying a bunch of curves, and after iterating the details of the most promising candidate, I finally converged to the curve below -- a curve made up of 4 linear segments.  As you can see in the right-hand plot, the new onset and release seen in the green curve is very smooth.  It gives me the best control (that I could find through this guess-try-and-tweak method) over both subtle and strong amounts of vibrato.  It feels pretty darned good!

My remaining criticism with the response of my aftertouch is that it takes too much force to get the aftertouch started.  Sadly, I have no control over when the aftertouch starts -- the start of the aftertouch is entirely set by when the keyscanning electronics decide to start generating MIDI aftertouch messages.  Don't get me wrong, I think that the folks over at Keyparts UK set a very good general-purpose aftertouch threshold into their keyscanning electronics.  I just think that *I* like my aftertouch to start with far less force than most other folks.  I like it to start with a mere feather of a amount that would drive other folks crazy.

To address this "problem", I'm thinking that there's probably a configuration setting in the keyscanning electronics that'll let me adjust the aftertouch threshold.  The electronics are amazingly configurable and under continued development.  I think that it's time for me to dive in and figure it out.  Fun!

Next Step: Tuning the Portamento

Thursday, April 4, 2013

Polysix - Mounting the Arduino

While I was pretty excited to jump straight to the end of my story to show a working demo of my aftertouch and portamento, there was actually quite a lot of work that had to get done to get to that demo.  That's why I'm now going back and hitting some of the details, like my last post on how I re-purposed the Arp controls for controlling the aftertouch vibrato.  In this new post, I'm going to talk about how I went about physically mounting my Arduino -- the brain for the aftertouch and portamento -- into my Polysix.  So that you can see where I'm headed, below is the final picture of it mounted inside my Polysix.

My Arduino Mega (in Blue) Mounted Next to the Power Supply
Compared to my Mono/Poly, the Polysix has far less space inside for adding stuff, and the Arduino Mega is not a small board to try to squeeze in.  Luckily, there is a nice open space on the sheet metal control panel, on the vertical part right next to the power supply PCB (see pic below).  It seems just right for the shape of the Arduino Mega.  But how will I actually attach it?

Well, because the Arduino Mega already has some mounting holes in it, I could just use screws.  But, to prevent pressing the backside of the Arduino against the electrically-conductive sheet metal, I need some standoffs.  Since most standoffs are threaded on both ends, the plan is to drill some small holes in the Polysix's sheet metal, mount the standoffs via screws through those holes, and then to use more screws to attach the Arduino to the standoffs.  Even for me -- the mechanically dis-inclined -- this seems feasible.

That Empty Spot is Where I'll Put the Arduino.  One Standoff is Already Mounted.
The first step was for me to find some standoffs.  For no particular reason (other than that they were easy for me to get), I got some #4-40 threaded aluminum standoffs (see below).  Plastic ones would probably work fine, too.  I think that I got standoffs that are 1/2" long, but they might have been a little shorter.  I also got a bunch of really short #4-40 screws and a few washers.  My screws were regular silver/gray color, which means that you can easily see the screw heads on the outside of the synth.  If I did it again, I'd try to find black screws so that they'd blend in better.

Threaded Aluminum Standoffs For Mounting the Arduino to the Inside of the Polysix.
With the standoffs in-hand, I then proceeded to drill the holes in the Polysix's sheet metal enclosure.  Drilling into sheet metal is not something that I wasn't familiar with, so I asked around at my work place.  Apparently, my regular (ie, cheap) drill bits can cut into sheet metal just fine.  Cool!  The only trick is that the drill bits have a hard time getting started on sheet metal.  Until they can bite in, they tend to wander around the surface of the metal, which makes it hard to get the hole where you want it.  So, according to one of helpful co-workers, I should use a punch-thingy to put a small indentation in the surface of the metal, which allows the drill bit to bite more easily.  The punch that I borrowed is shown below.

Spring-Loaded Punch for Making it Easier to Drill into Metal
Once I decided where I wanted a hole (by holding the Arduino up to the metal panel and using a thin pencil stuck through the Arduino's mounting holes to mark the spot on the sheet metal), I grabbed hold of the Polysix's panel, pressed in the punch, and waited for it to "pop!".  When it finally popped, it really startled my wife in the next room.  It's not particularly loud, but it is a bit sharp sounding and totally unlike any other sound that I usually make when futzing with my instruments.  It's good to keep things interesting around here.

Pressing in the Spring-Loaded Punch.
I'd like to now show a picture of the tiny dimple that was made by the punch, but it's really too small for me to take a good picture.  So, you'll just have to imagine a very very small dimple in the surface of the sheet metal.  I couldn't really believe that it was big enough to help the drill bit seat, but it was.  It worked marvelously.

With the dimple to get me started, I used a small drill bit to get my initial hole through the sheel metal.  Since I have old bits that aren't very good, it took me a while to get through.  Once I was through, I stepped up to a bigger bit to enlarge the hole so that my #4 screws would pass through.  

To then mount the standoff, you use one screw (and washer) from the outside of the back of the synth, you pass it through the hole that you just made, and you screw into the female threads in the standoff.  After tightening, the standoff is nicely attached to the synth.  In the picture above, you can see that two standoffs are already in place.

Once all the standoffs are in place (I used three), you can place the Arduino over the standoffs and use more screws to attach the Arduino to the standoffs.  If you're really lucky, you located your standoffs correctly and they line up with the holes in the Arduino.  I was mostly lucky...two holes lined up well and one was a smidgen off.  It was close enough, though, that I could angle the screw a bit and get it to seat sorta good enough.  As usual for me, it's ugly but it works.

Below is another picture of the Arduino fully-mounted inside my Polysix.  Not bad!

The Arduino is Fully-Mounted Inside my Korg Polysix
Now that I'm looking at this picture with fresh eyes, I sure do see a lot of loose wires running round.  In particular, lots of wires are needed in order to connect the Adruino, which is replacing the Key Assigner 8049 microprocessor, to the socket that used to hold the 8049 microprocessor.  The 8049 was located just underneath the keybed, so that's why you see the rainbow of wires passing from the Arduino on the right to the underside of the keybed on the left.  I'd definitely like a better way of handling all this wiring.  As usual, there's always more "cleaning up" that could be done!

Thanks for reading!

Tuesday, April 2, 2013

Polysix - Re-Using the Arp Clock for the Aftertouch LFO

In a previous post, I demonstrated aftertouch in my Korg Polysix.  The aftertouch is used add vibrato -- an oscillating modulation of the pitch of the current note -- which is very similar to the effect of the mod wheel that is already built-in to the Polysix.  In fact, I originally planned on having the aftertouch utilize the same modulation generator (LFO) as used by the mod wheel.  But then I thought that it might be better to have the vibrato clocked by its own LFO thereby leaving the Polysix's built-in modulation generator free to do other effects like filter sweeps or tremolo.  Doing a vibrato-dedicated LFO in software in the Arduino is trivial, but how do I control its speed?  Is there a control on the front of the Polysix that I can re-purpose for controlling the vibrato LFO's speed?  Well, there is.  I chose to re-purposed the Arpeggiator's "Speed" knob.  Here's the story of how I did it.  (Note that I go into some gory details here, so you might just want to browse the pictures below and then go watch some funny cat videos.  I recommend this one).

The key limitation in this hack is that I do not (yet) want to add any more knobs or switches to my Polysix.  I would like to re-purpose one of the built-in knobs or switches.  This is made more challenging in that, because I have so far only replaced the Key Assigner microprocessor, I only have access to the knobs and switches that are serviced by the Key Assigner.  Most of the knobs and switches are actually serviced by the main processor in the Polysix, not the Key Assigner.  The only controls that serviced by the Key Assigner are (as shown in the picture below) the Arpeggiator controls and the Key Assign Mode button.  You know, that Arpeggiator "Speed" knob looks like it could be pretty useful...

One convenient property of the Arpeggiator controls is that they serve no purpose when the Arpeggiator is off.  Conversely, when the Arpeggiator is on, one is not likely to care about applying aftertouch vibrato.  So, we have a nice opportunity here to use the Arpeggiator controls for the Arpeggiator when in Arp mode, and an opportunity to re-use the Arpeggiator controls for another purpose when in normal mode.  Sounds good!

In the Arpeggiator controls, we see that we have a nice knob named "Speed".  It even has a blinky LED to indicate its current speed.   This seems like a perfect control for me to use to control my aftertouch vibrato.  How do we go about doing it?  Well, first we need to learn about what that knob is attached to, which means that we need to learn about the Polysix's Arpeggiator clock...

The Arp's "Speed" knob is wired into the circuit shown in the schematic below.  It is a circuit for generating clock pulses.  These pulses are used to drive the Arpeggiator when the synth is in Arpeggiator mode.  The "Speed" knob is wired into this circuit such that it changes the rate of these pulses so that the Arpeggiator goes faster or slower as desired.  It looks like the best way for me to re-use the Arp's "Speed" knob is to simply listen to the "ACKI" line and respond to changes in the rate of the pulses.

Looking at other parts of the schematic (KLM-366), the ACKI line is brought back to the Key Assigner's 8049 microprocessor.  Since I just replaced this microprocessor with my Arduino, it means that I have easy access to this signal.  I just need to figure out the best way to get the Arduino to respond to the arrival of these short pulses.  Using one of the Arduino's interrupt pins is clearly the best solution. If you're not familiar with interrupt pins, here's the idea:

Some of the Arduino's pins are special -- they can be configured so that they are always being monitored for changes, even while the Arduino is doing its other work.  Whenever a change is detected on one of these pins, the Arduino interrupts what it was doing and executes a special piece of code that you write called an "interrupt service routine" (ISR).  In the ISR, I would write the logic to measuring the timing of received pulses so that, back in the main part of the code, the vibrato LFO can adjust its speed.  There are three steps to implementing this:  (1) connect the ACKI line  to a one of the interrupt-enabled pins on my Arduino, (2) write an ISR, and (3) "attach" the ISR to the interrupt pin.  Let's go!

Step 1, Connect ACKI to an Interrupt Pin:  The Arduino's interrupt pins are discussed on this page.  I'm using an Arduino Mega and you'll see that there are six pins that are capable of being interrupt pins.  For no particular reason, I chose to go with Interrupt 4, which means that I should use pin 19.  So I brought a wire from the ACKI line in my Polysix (from the now-empty 8049 socket) out to pin 19 on my Arduino Mega.

Step 2, Write the ISR:.  The ISR is a software routine will be called whenever a pulse is received from the Arp clock via the ACKI line.  After thinking about how to handle the timing of the vibrato's software LFO, I've decided that the ISR only needs to measure the time that has passed between the previous Arp clock pulse and the newly-receive Arp clock pulse.  Once I know the time between pulses, I can adjust my software LFO in the Arduino so that it'll cycle at the same rate.  Below is my ISR code for measuring the time between pulses.  The Arduino executes it whenever a new pulse is detected on my interrupt pin.

typedef unsigned long micros_t;         //data type returned by micros();
volatile micros_t previous_ARP_micros = 0;     //don't forget "volatile"!
volatile micros_t ARP_period_micros = 1000000; //don't forget "volatile"!

void measureInterruptTiming(void)
  //get the current time
  micros_t current_ARP_micros = micros();  

  //compute how much time has passed since the last pulse

  ARP_period_micros = current_ARP_micros - previous_ARP_micros;

  //save the current time for use when the next pulse arrives

  previous_ARP_micros= current_ARP_micros;

Step 3, Attach the ISR to the Interrupt Pin:  With the ISR written, now I need to tell the Arduino to execute this code whenever it detects a change on my particular interrupt pin.  This is called "attaching" the interrupt.  Following the documentation in the Arduino link above, I add this command to my void setup() routine:

attachInterrupt(4, measureInterruptTiming, RISING);

And we're done!  The result of this process is that the user (me!) can turn the "Speed" knob on the front of my keyboard, which changes the rate of pulses from the Arp clock, which is noticed by the Arduino via Interrupt #4 (aka, Pin 19), which causes it to run my ISR routine, which writes the time between pulses to a global variable, which is then acted upon in the main part of the Arduino software (not in the ISR) to adjust the rate of the vibrato.  Stated more succinctly, turning the "Speed" knob will now change the speed of my aftertouch vibrato.  And I did it without needing to cut any new holes in my Polysix for new knobs or buttons.  Mission accomplished.  Thank you Arduino!  Thank you Polysix!  Thank you reader!

Next Step: Mounting the Arduino in my Polysix
Next Step: With this success, I also use the Arp Speed knob to control detuning in my Polysix