65 lines
1.3 KiB
C++
65 lines
1.3 KiB
C++
#ifndef INCLUDE_INTERPOLATOR_H
|
|
#define INCLUDE_INTERPOLATOR_H
|
|
|
|
#include "dsptypes.h"
|
|
|
|
class Interpolator {
|
|
public:
|
|
Interpolator();
|
|
|
|
void create(int nTaps, int phaseSteps, double sampleRate, double cutoff);
|
|
|
|
bool interpolate(Real* distance, const Complex& next, bool* consumed, Complex* result)
|
|
{
|
|
while(*distance >= 1.0) {
|
|
if(!(*consumed)) {
|
|
advanceFilter(next);
|
|
*distance -= 1.0;
|
|
*consumed = true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
doInterpolate((int)floor(*distance * (Real)m_phaseSteps), result);
|
|
return true;
|
|
}
|
|
|
|
|
|
private:
|
|
std::vector<Real> m_taps;
|
|
std::vector<Complex> m_samples;
|
|
int m_ptr;
|
|
int m_phaseSteps;
|
|
int m_nTaps;
|
|
|
|
void createTaps(int nTaps, double sampleRate, double cutoff, std::vector<Real>* taps);
|
|
|
|
void advanceFilter(const Complex& next)
|
|
{
|
|
m_ptr--;
|
|
if(m_ptr < 0)
|
|
m_ptr = m_nTaps;
|
|
m_samples[m_ptr] = next;
|
|
}
|
|
|
|
void doInterpolate(int phase, Complex* result)
|
|
{
|
|
int sample = m_ptr;
|
|
const Real* coeff = &m_taps[phase * m_nTaps];
|
|
Real rAcc = 0;
|
|
Real iAcc = 0;
|
|
|
|
for(int i = 0; i < m_nTaps; i++) {
|
|
rAcc += *coeff * m_samples[sample].real();
|
|
iAcc += *coeff * m_samples[sample].imag();
|
|
sample++;
|
|
if(sample >= m_nTaps)
|
|
sample = 0;
|
|
coeff++;
|
|
}
|
|
*result = Complex(rAcc, iAcc);
|
|
}
|
|
};
|
|
|
|
#endif // INCLUDE_INTERPOLATOR_H
|