Here's the main interpolate function, using Least Squares AutoRegression (LSAR):
| 80 | // Here's the main interpolate function, using |
| 81 | // Least Squares AutoRegression (LSAR): |
| 82 | void InterpolateAudio(float *buffer, const size_t len, |
| 83 | size_t firstBad, size_t numBad) |
| 84 | { |
| 85 | const auto N = len; |
| 86 | |
| 87 | wxASSERT(len > 0 && |
| 88 | firstBad >= 0 && |
| 89 | numBad < len && |
| 90 | firstBad+numBad <= len); |
| 91 | |
| 92 | if(numBad >= len) |
| 93 | return; //should never have been called! |
| 94 | |
| 95 | if (firstBad == 0) { |
| 96 | // The algorithm below has a weird asymmetry in that it |
| 97 | // performs poorly when interpolating to the left. If |
| 98 | // we're asked to interpolate the left side of a buffer, |
| 99 | // we just reverse the problem and try it that way. |
| 100 | Floats buffer2{ len }; |
| 101 | for(size_t i=0; i<len; i++) |
| 102 | buffer2[len-1-i] = buffer[i]; |
| 103 | InterpolateAudio(buffer2.get(), len, len-numBad, numBad); |
| 104 | for(size_t i=0; i<len; i++) |
| 105 | buffer[len-1-i] = buffer2[i]; |
| 106 | return; |
| 107 | } |
| 108 | |
| 109 | Vector s(len, buffer); |
| 110 | |
| 111 | // Choose P, the order of the autoregression equation |
| 112 | const int IP = |
| 113 | imin(imin(numBad * 3, 50), imax(firstBad - 1, len - (firstBad + numBad) - 1)); |
| 114 | |
| 115 | if (IP < 3 || IP >= (int)N) { |
| 116 | LinearInterpolateAudio(buffer, len, firstBad, numBad); |
| 117 | return; |
| 118 | } |
| 119 | |
| 120 | size_t P(IP); |
| 121 | |
| 122 | // Add a tiny amount of random noise to the input signal - |
| 123 | // this sounds like a bad idea, but the amount we're adding |
| 124 | // is only about 1 bit in 16-bit audio, and it's an extremely |
| 125 | // effective way to avoid nearly-singular matrices. If users |
| 126 | // run it more than once they get slightly different results; |
| 127 | // this is sometimes even advantageous. |
| 128 | for(size_t i=0; i<N; i++) |
| 129 | s[i] += (rand()-(RAND_MAX/2))/(RAND_MAX*10000.0); |
| 130 | |
| 131 | // Solve for the best autoregression coefficients |
| 132 | // using a least-squares fit to all of the non-bad |
| 133 | // data we have in the buffer |
| 134 | Matrix X(P, P); |
| 135 | Vector b(P); |
| 136 | |
| 137 | for(size_t i = 0; i + P < len; i++) |
| 138 | if (i+P < firstBad || i >= (firstBad + numBad)) |
| 139 | for(size_t row=0; row<P; row++) { |
no test coverage detected