An Audio Synthesis Textbook For Musicians, Digital Artists and Programmers by Mike Krzyzaniak

  1. //CubicInterpolation.c
  2. //gcc MKAiff.c CubicInterpolation.c -o CubicInterpolation
  3. void cubicInterpolateBuffer(float* previous3Frames, int numChannels, float* input, int inNumFrames, float* output, int outNumFrames)
  4. {
  5. int i, j, index;
  6. double distance, prev, prevPrev, next, nextNext;
  7. double a, b, c, d;
  8. for(i=0; i<outNumFrames; i++)
  9. {
  10. for(j=0; j<numChannels; j++)
  11. {
  12. distance = i * (inNumFrames / (double)outNumFrames);
  13. index = ((int)distance) * numChannels + j;
  14. nextNext = input[index ];
  15. next = distance < 1 ? previous3Frames[index + 2*numChannels] : input[index - numChannels];
  16. prev = distance < 2 ? previous3Frames[index + numChannels ] : input[index - 2*numChannels];
  17. prevPrev = distance < 3 ? previous3Frames[index ] : input[index - 3*numChannels];
  18. distance -= (int)distance;
  19. a = nextNext - next - prevPrev + prev;
  20. b = prevPrev - prev - a;
  21. c = next - prevPrev;
  22. d = prev;
  23. output[i*numChannels+j] = ((a * distance * distance * distance) + (b * distance*distance) + (c * distance) + (d));
  24. }
  25. }
  26. for(j=0; j<numChannels*3; j++)
  27. previous3Frames[j] = input[(inNumFrames - 3) * numChannels + j];
  28. }

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:
Cubic

Explanation of the Code

Code Explanation