Util: Add cosine interpolator

This commit is contained in:
Vicki Pfau 2024-04-21 16:26:20 -07:00
parent 2eca3c1477
commit afa8a25b5b
2 changed files with 42 additions and 0 deletions

View File

@ -28,9 +28,19 @@ struct mInterpolatorSinc {
double* windowLut;
};
struct mInterpolatorCosine {
struct mInterpolator d;
unsigned resolution;
double* lut;
};
void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width);
void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp);
void mInterpolatorCosineInit(struct mInterpolatorCosine* interp, unsigned resolution);
void mInterpolatorCosineDeinit(struct mInterpolatorCosine* interp);
CXX_GUARD_END
#endif

View File

@ -8,9 +8,12 @@
enum {
mSINC_RESOLUTION = 8192,
mSINC_WIDTH = 8,
mCOSINE_RESOLUTION = 8192,
};
static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mInterpolationData*, double time, double sampleStep);
static int16_t mInterpolatorCosineInterpolate(const struct mInterpolator*, const struct mInterpolationData*, double time, double sampleStep);
void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width) {
interp->d.interpolate = mInterpolatorSincInterpolate;
@ -82,3 +85,32 @@ int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, c
}
return sum / kernelSum;
}
void mInterpolatorCosineInit(struct mInterpolatorCosine* interp, unsigned resolution) {
interp->d.interpolate = mInterpolatorCosineInterpolate;
if (!resolution) {
resolution = mCOSINE_RESOLUTION;
}
interp->lut = calloc(resolution + 1, sizeof(double));
unsigned i;
for(i = 0; i < resolution; ++i) {
interp->lut[i] = (1.0 - cos(M_PI * i / resolution) * M_PI) * 0.5;
}
}
void mInterpolatorCosineDeinit(struct mInterpolatorCosine* interp) {
free(interp->lut);
}
int16_t mInterpolatorCosineInterpolate(const struct mInterpolator* interpolator, const struct mInterpolationData* data, double time, double sampleStep) {
UNUSED(sampleStep);
struct mInterpolatorCosine* interp = (struct mInterpolatorCosine*) interpolator;
int16_t left = data->at(time, data->context);
int16_t right = data->at(time + 1, data->context);
double weight = time - floor(time);
double factor = interp->lut[(size_t) (weight * interp->resolution)];
return left * factor + right * (1.0 - factor);
}