Exponential interpolation between two points (for glide/portamento)

I am building a step sequencer module which uses a DAC to output a 'control voltage' used to determine the musical note played on a synthesizer voltage-controlled-oscillator, and I would like it to have a built in glide/portamento functionality in code, so that when glide is enabled, a note will exponentially travel to the next note.

I've googled around a bit, and it looks as though most modules that include glide do so with a hardware low pass filter. I would like to be able to affect the amount of portamento per-step which would require making a voltage controlled low pass filter. The increased complexity makes me want to do this in software instead.

However I'm having a hard time finding any example code for portamento.

Math is not my strong suit, but I can figure it out if I knew roughly how to achieve this. Even a vague hint would be helpful at this point.

Also for synth players, since pitch control voltage is already exponential, could I just linearly interpolate the control voltage and it will 'sound' exponential?

Music is not my strong suit

do I get that you have a start note or frequency and a target note / frequency and you want some sort of exponential function going from the start to the target in a certain number of steps?

No. The steps in the interpolation must be chosen to model the exponential (logarithmic, actually) intervals.

Since you have a DAC, you have full control over the binary values sent to it.

Correct. The number of steps, ideally, is adjustable, lengthening the time between the start note and the target note.

Oh very interesting, thank you. Pitch CV is exponential, glide as modulation is logarithmic. Dizzying!

I'm aware of the log() function but need to figure out how to use it now!

in math terms, if at T0=0 you are at value Y0 and you want to move to YN at TN=N

a common exponential function is Yt = Y0 . (( YN / Y0)1/N)t

for example if you want 30 steps (N=30) and Y0 is 10 at t=0 (point A) and Y30 is 40 (point B)

the curve would look like this
image

if Y30 is 5 (point B)
image

( YN / Y0)1/N - 1 is called the decay or growth factor

Most people use a lookup table, but to create one, you need to know the endpoint values and number of steps.

Thank you so much, this helps tremendously. I now have to change this to a logarithmic function (per the other comment) but given what's here I think I can figure it out. As I'm reading, a logarithmic funtion is just the inverse of an exponential one so I just have to figure out how to do this but mirrored.

Does that mean I have to make a lookup table for each portamento 'depth' amount? It looks like it's a tradeoff between using an expensive algorithm, vs. using a lookup table and a limited number of portamento depths.

The calculations can be done either during or before implementation. If you are not time constrained, calculate the steps on the fly.

1 Like

so you want the curve to move faster to the destination ?

This prompted a long and confusing internet rabbithole. Confusing because the terms are used interchangeably when referring to synthesizers like Moogs, who usually stick to one formula (e.g. one Moog synth won't have log, while another Moog is exp)

Just realized that a software synthesizer I own has an adjustable portamento response from logarithmic > linear > exponential.

After some testing it appears that logarithmic is the way that I'm most used to hearing. Some synths have linear responses as well, which is also acceptable after some testing.

Human senses like vision (light intensity) and hearing (sound pressure level and pitch perception) have logarithmic response curves, and most audio gear already takes that into account behind the scenes.

For example, audio volume controls are almost always logarithmic.

Oh that makes perfect sense, what with logarithmic potentiometers and everything. Thank you!

They are called logarithmic, but the resistance as a function of position is actually an exponential, or rather a very crude approximation to exponential.

The position is a logarithmic function of resistance as that's the inverse function of course.

Portamento is usually a first order filter, ie decaying exponential function, which is easiest to implement as a digital filter in software, ie you regularly do:

  output += alpha * (output - target) ;

where target is the destination note 'control voltage', output is the gliding 'control voltage', and alpha is a parameter between 0 and 1 that controls the rate of decay relative to how often you compute the output.

No, that's a completely separate issue - human pitch sensing is already logarithmic function of true frequency (again people are sloppy about log v. exponential!), but the glide dynamics are about change over time and also need a response - linear will have an abrupt end to the glide whereas decaying exponential lacks this discontinuity.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.