/********************************************************************** Audacity: A Digital Audio Editor InterpolateAudio.cpp Dominic Mazzoni **********************************************************************/ #include #include #include #include "InterpolateAudio.h" #include "Matrix.h" static inline int imin(int x, int y) { return xy? x: y; } // This function is a really dumb, simple way to interpolate audio, // if the more general InterpolateAudio function below doesn't have // enough data to work with. If the bad samples are in the middle, // it's literally linear. If it's on either edge, we add some decay // back to zero. static void LinearInterpolateAudio(float *buffer, int len, int firstBad, int numBad) { int i; float decay = 0.9f; if (firstBad==0) { float delta = buffer[numBad] - buffer[numBad+1]; float value = buffer[numBad]; i = numBad - 1; while (i >= 0) { value += delta; buffer[i] = value; value *= decay; delta *= decay; i--; } } else if (firstBad + numBad == len) { float delta = buffer[firstBad-1] - buffer[firstBad-2]; float value = buffer[firstBad-1]; i = firstBad; while (i < firstBad + numBad) { value += delta; buffer[i] = value; value *= decay; delta *= decay; i++; } } else { float v1 = buffer[firstBad-1]; float v2 = buffer[firstBad+numBad]; float value = v1; float delta = (v2 - v1) / (numBad+1); i = firstBad; while (i < firstBad + numBad) { value += delta; buffer[i] = value; i++; } } } // Here's the main interpolate function, using // Least Squares AutoRegression (LSAR): void InterpolateAudio(float *buffer, int len, int firstBad, int numBad) { int N = len; int i, row, col; wxASSERT(len > 0 && firstBad >= 0 && numBad < len && firstBad+numBad <= len); if(numBad >= len) return; //should never have been called! if (firstBad == 0) { // The algorithm below has a weird asymmetry in that it // performs poorly when interpolating to the left. If // we're asked to interpolate the left side of a buffer, // we just reverse the problem and try it that way. float *buffer2 = new float[len]; for(i=0; i= (firstBad + numBad)) for(row=0; row