# How to change the shape of a function generator keeping the rate?

I'm making a sort of Envelope Function Generator. At the moment, I'm calculating only the the "rise" stage, which goes from 0 to 10 V; than, brutally, I back it to the beginning.

Here's the code I have, which emulate 10 cycles with a change of the shape (from linear to exp) at the 4° cycle and 120° sample:

#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 lin = (copysignf(1.0f, delta) * 10.0) / length;

float exp = (M_E * delta) / length;
return interpolate(lin, exp, shape * 0.90f);
}

int main() {
float in = 10.0;
float out = 0.0;

float shape = 0.0;
float lengthInSeconds = 1e-2; // * powf(2.0, 1.0 * 10.0);

int numCycles = 10;
for(int cycle = 0; cycle < numCycles; cycle++) {
int numSteps = 0;
while (in - out > 1e-3) {
// change shapes
if(cycle == 4 && numSteps == 120) {
shape = 1.0;
}

float delta = in - out;
out += shapeDelta(delta, lengthInSeconds, shape) * (1.0 / sampleRate);

numSteps++;
}

std::cout << "cycle: " << cycle << " | num steps: " << numSteps << " | value: " << out << std::endl;
out -= 10.0;
}
}


The problem is that changing the shape, change the "lenght" of the generated signal (i.e. change the rate; just looks at the number of samples used for each cycle).

How can I change it without change the rate? And keeping a "non steppy" signal (i.e. avoid brutal transient).