An Audio Synthesis Textbook For Musicians, Digital Artists and Programmers by Mike Krzyzaniak
- //CubicInterpolation.c
- //gcc MKAiff.c CubicInterpolation.c -o CubicInterpolation
- void cubicInterpolateBuffer(float* previous3Frames, int numChannels, float* input, int inNumFrames, float* output, int outNumFrames)
- {
- int i, j, index;
- double distance, prev, prevPrev, next, nextNext;
- double a, b, c, d;
- for(i=0; i<outNumFrames; i++)
- {
- for(j=0; j<numChannels; j++)
- {
- distance = i * (inNumFrames / (double)outNumFrames);
- index = ((int)distance) * numChannels + j;
- nextNext = input[index ];
- next = distance < 1 ? previous3Frames[index + 2*numChannels] : input[index - numChannels];
- prev = distance < 2 ? previous3Frames[index + numChannels ] : input[index - 2*numChannels];
- prevPrev = distance < 3 ? previous3Frames[index ] : input[index - 3*numChannels];
- distance -= (int)distance;
- a = nextNext - next - prevPrev + prev;
- b = prevPrev - prev - a;
- c = next - prevPrev;
- d = prev;
- output[i*numChannels+j] = ((a * distance * distance * distance) + (b * distance*distance) + (c * distance) + (d));
- }
- }
- for(j=0; j<numChannels*3; j++)
- previous3Frames[j] = input[(inNumFrames - 3) * numChannels + j];
- }
Explanation of the Concepts
This is a cubic interpolation algorithm that is capable of stretching out or contracting a buffer of interleaved audio data.
In general, linear interpolation is somewhat inelegant, and a somewhat higher-fidelity result can be achieved by attempting to draw some sort of curve between the known sample-points. A cubic polynomial of the form
ax^3 + bx^2 + cx + d
works quite well, and results in a curve like this:
Explanation of the Code
Code Explanation