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!

1 comment:

  1. In trying to answer my own question regarding voice-spreading portamento on other synths, check out this link discussing the Oberheim OB-X analog polysynth:

    If you skip down quite a bit (~2/3rds of the way), he talks about using the synth in Unison mode, which reveals the synth's imperfections in the polyphonic glide, which causes different glide rates for each voice. He is clearly in love with this sound, just like me.

    Based on his text, though, it does not appear that the circuit for the OB-X was *purposely* designed to spread the voices -- it doesn't sound like Oberheim was purposely trying to have the glide rates be different. So, the purposely-detuned portamento in the Mono/Poly could still be a unique feature to itself.