I made an interpolator module using Reaktor Core: link
I wrote about how it was put together. The first part of the MOTIVATIONS section and the CONCLUSIONS section are the most accessible. Venture into the DERIVATION section at your own risk, though anyone that's familiar with basic calculus should have no problem understanding the derivation, it really isn't anything special.
MOTIVATIONS
I recently found the need for an interpolator module with dynamic duration. The interpolators included with Reaktor, unfortunately, do not allow the duration of the interpolation to be changed during a performance. My goal is to implement an algorithm that will create a smooth curve between two values. The curve should be continuous, and the slope of the curve should also be continuous, in order to reduce any unwanted high frequencies in the output.
The amplitude of the first value (A_i) should usually be equal to the previous destination value that the user has given, except when the user has not provided such a value, in the intialization state, in which case the user should input an initial amplitude or accept the default value of 0, and in the case that the user submits data while the algorithm is still interpolating. The amplitude of the second value provided by the user (A_f) is the value which the algorithm will interpolate towards. The slope of the curve should approach zero as the curve approaches A_f.
The algorithm should account for the scenario in which the user inputs a destination value while interpolation is taking place. In this case, then the algorithm should provide a smooth curve based on the parameters:
A_i - The output amplitude of the algorithm when the trigger is received to begin interpolation.
S_i - The slope of the output amplitude when the trigger is received to begin interpolation.
A_f - The destination amplitude provided by the user.
The choice of curve is cubic. Polynomials are fairly easy to work with, and a simple solution is preferable. A quadratic solution does not exist, because the slope of the curve required for interpolation must equal 0 in exactly two places. Then, a cubic polynomial curve is a good choice due to both its simplicity, and just sufficient complexity.
This line of reasoning also implies that a quartic solution may be preferable if it is desired that the user should also be allowed to adjust the curve shape. In this case it is not necessary.
DERIVATION
Start with a general equation for a cubic curve over time (t on the interval [0,1]):
C(t) = a*(t^3) + b*(t^2) + c*t + d
Where a, b, c, and d are arbitrary constants.
The equation for the slope of the curve is then equivalent to the derivative of C(t) with respect to t.
C'(t) = 3*a*(t^2) + 2*b*t + c
It is given, by the nature of the problem, that:
C(0) = A_i
C(1) = A_f
C'(0) = S_i
C'(1) = 0
A solution for the arbitrary constants a, b, c, d in terms of the given values A_i, A_f and S_i is desired.
Since C(0) = d and C(0) = A_i, then d = A_i.
Also, since C'(0) = c and C'(0) = S_i, then c = S_i.
We are left with two equations and two unknowns:
C(1) = A_f = a + b + c + d = a + b + S_i + A_i
C'(1) = 0 = 3*a + 2*b + c = 3*a + 2*b + S_i
Solving for a and b yields the following solutions:
a = -2*A_f + S_i + 2*A_i
b = -3*A_i - 2*S_i + 3*A_f
Finally, an equation for the general curve, which can be applied over the desired duration simply by scaling t appropriately.
C(t) = (-2*A_f + S_i + 2*A_i)*(t^3) + (-3*A_i - 2*S_i + 3*A_f)*(t^2) + S_i*t + A_i
CONCLUSIONS
The algorithm works quite well using the equation derived above. I have provided a sample output in the form of a screen capture that was produced during unit testing.
The CPU load required for this module seems low on my system. Some optimizations were implemented, especially to minimize processor usage while the algorithm is idle (not interpolating). The amount of code required for this implementation seems very small. It is a compact solution, as well as an efficient one.
While the factory module for interpolation requires less CPU usage, it is limited in its usefulness; the duration of interpolation is not dynamic. The interpolator module I have produced, however, can also be used as an n step envelope module, or as a low frequency oscillator, depending on how it is implemented.
In short, I am satisfied with this solution, and I have finally, successfully eliminated all the clicks from the output of the Resynth granular synthesis module I like so much.
Thanks for reading, I hope you've found this post useful.
