How to keep the same length interpolating points linearly or exponentially?

DSP, Plug-in and Host development discussion.
User avatar
Nowhk
KVRian
871 posts since 2 Oct, 2013

Post Thu Mar 14, 2019 1:07 am

Hi guys 8)

This is the code I have for a "function generator" signal that I'll use to modulate some params (taken inspiration from Rampage module, within VCV Rack):

Code: Select all

#include <iostream>
#include <math.h>

const double sampleRate = 44100.0;

inline float interpolate(float a, float b, float frac) { 
    return a + frac * (b - a); 
}

inline float shapeDelta(float delta, float length, float shape) {
    float mul = 1.0;
    
	float lin = copysignf(1.0f, delta) * 10.0 / length;
	float exp = mul * M_E * delta / length;

	return interpolate(lin, exp, shape * 0.90f);
}

int main() {
    float lengthInSeconds = 1e-2;
    float in = 10.0;
    
    // linear
    float out = 0.0;
    float shape = 0.0;
    int numSteps = 0;
    while (in - out > 1e-3) {
        float delta = in - out;
        float inc = shapeDelta(delta, lengthInSeconds, shape) * (1.0 / sampleRate);
        
        out += inc;
        numSteps++;
    }
    std::cout << "shape: " << shape << " | num steps: " << numSteps << " | value: " << out << std::endl;
    
    // exp
    out = 0.0;
    shape = 1.0; // changing the shape
    numSteps = 0;
    while (in - out > 1e-3) {
        float delta = in - out;
        float inc = shapeDelta(delta, lengthInSeconds, shape) * (1.0 / sampleRate);
        
        out += inc;
        numSteps++;
    }
    std::cout << "shape: " << shape << " | num steps: " << numSteps << " | value: " << out << std::endl;    
}
With shape = 0, its linear, and it takes (length) 441 samples to complete (0.01 seconds).
With shape = 1, its exponential, but it takes (length) 582 samples to complete (more than 0.01 seconds).

I'd like to keep the same (~) length, using both linear or exp (also considering to modulate/change shape in the middle of the cycle).

I guess that all I need is to change that mul factor (due to the position/delta/shape?!?!).
That's the question: how would you manage that mul?

It seems to me a nice way of easily generate CV signal, but I'd like to keep fixed the time of each cycle while changing the shape.

Thanks guys, as usual!

sault
KVRist
45 posts since 4 Sep, 2014

Re: How to keep the same length interpolating points linearly or exponentially?

Post Thu Mar 21, 2019 10:39 pm

The first thing I see is that you never have a fully exponential shape because of the 0.9 * shape in the shapeDelta function... but no, changing mul won't help because mul is a linear operation and we need an exponential operation.

One way to calculate things might be

decay = exp( ln(target_val)/(srate*ms) );

In other words, for you

decay = exp( ln(0.001)/(srate*0.01) );

In the case of the srate being 44100 that gives us about 0.984458 which when raised to the 441st power is right about 0.001. So you need to have that e^x thing going on in there somewhere.

Return to “DSP and Plug-in Development”