Removed ResamplerFilterDifference

It takes 1 extra multiply to calculate the correct interpolation,
but I think the improvement in cache locality (and binary size) outweighs that.
This commit is contained in:
Brick 2023-08-23 19:09:03 +01:00 committed by Ryan C. Gordon
parent 9f7a22fa45
commit fba6e1e3d3
3 changed files with 20 additions and 538 deletions

View file

@ -50,6 +50,7 @@ gcc -o genfilter build-scripts/gen_audio_resampler_filter.c -lm && ./genfilter >
#define RESAMPLER_BITS_PER_ZERO_CROSSING ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1)
#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << RESAMPLER_BITS_PER_ZERO_CROSSING)
#define RESAMPLER_FILTER_SIZE (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS)
#define RESAMPLER_TABLE_SIZE (RESAMPLER_FILTER_SIZE + RESAMPLER_ZERO_CROSSINGS)
/* This is a "modified" bessel function, so you can't use POSIX j0() */
static double
@ -75,25 +76,21 @@ bessel(const double x)
/* build kaiser table with cardinal sine applied to it, and array of differences between elements. */
static void
kaiser_and_sinc(double *table, double *diffs, const int tablelen, const double beta)
kaiser_and_sinc(double *table, const int tablelen, const double beta)
{
const double bessel_beta = bessel(beta);
int i;
table[0] = 1.0;
diffs[tablelen - 1] = 0.0;
for (i = 1; i < tablelen; i++) {
const double kaiser = bessel(beta * sqrt(1.0 - pow((double)i / (double)(tablelen - 1), 2.0))) / bessel_beta;
const double kaiser = bessel(beta * sqrt(1.0 - pow((double)i / (double)(tablelen), 2.0))) / bessel_beta;
const double x = (((double) i) / ((double) RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) * M_PI;
table[i] = kaiser * (sin(x) / x);
diffs[i - 1] = table[i] - table[i - 1];
}
}
static double ResamplerFilter[RESAMPLER_FILTER_SIZE + 1];
static double ResamplerFilterDifference[RESAMPLER_FILTER_SIZE + 1];
static double ResamplerFilter[RESAMPLER_FILTER_SIZE];
static void
PrepareResampleFilter(void)
@ -101,7 +98,7 @@ PrepareResampleFilter(void)
/* if dB > 50, beta=(0.1102 * (dB - 8.7)), according to Matlab. */
const double dB = 80.0;
const double beta = 0.1102 * (dB - 8.7);
kaiser_and_sinc(ResamplerFilter, ResamplerFilterDifference, RESAMPLER_FILTER_SIZE + 1, beta);
kaiser_and_sinc(ResamplerFilter, RESAMPLER_FILTER_SIZE, beta);
}
int main(void)
@ -139,20 +136,18 @@ int main(void)
"#define RESAMPLER_BITS_PER_ZERO_CROSSING ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1)\n"
"#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << RESAMPLER_BITS_PER_ZERO_CROSSING)\n"
"#define RESAMPLER_FILTER_SIZE (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS)\n"
"#define RESAMPLER_TABLE_SIZE (RESAMPLER_FILTER_SIZE + RESAMPLER_ZERO_CROSSINGS)\n"
"\n", RESAMPLER_ZERO_CROSSINGS, RESAMPLER_BITS_PER_SAMPLE
);
printf("static const float ResamplerFilter[RESAMPLER_FILTER_SIZE] = {");
for (i = 0; i < RESAMPLER_FILTER_SIZE; i++) {
j = (i % RESAMPLER_ZERO_CROSSINGS) * RESAMPLER_SAMPLES_PER_ZERO_CROSSING + (i / RESAMPLER_ZERO_CROSSINGS);
printf("%s%12.9ff,", (i % RESAMPLER_ZERO_CROSSINGS) ? "" : "\n ", ResamplerFilter[j]);
}
printf("\n};\n\n");
printf("static const float ResamplerFilterDifference[RESAMPLER_FILTER_SIZE] = {");
for (i = 0; i < RESAMPLER_FILTER_SIZE; i++) {
j = (i % RESAMPLER_ZERO_CROSSINGS) * RESAMPLER_SAMPLES_PER_ZERO_CROSSING + (i / RESAMPLER_ZERO_CROSSINGS);
printf("%s%12.9ff,", (i % RESAMPLER_ZERO_CROSSINGS) ? "" : "\n ", ResamplerFilterDifference[j]);
printf("static const float ResamplerFilter[RESAMPLER_TABLE_SIZE] = {");
for (i = 0; i < RESAMPLER_TABLE_SIZE; i++) {
double v = 0.0;
if (i < RESAMPLER_FILTER_SIZE) {
j = (i % RESAMPLER_ZERO_CROSSINGS) * RESAMPLER_SAMPLES_PER_ZERO_CROSSING + (i / RESAMPLER_ZERO_CROSSINGS);
v = ResamplerFilter[j];
}
printf("%s%12.9ff,", (i % RESAMPLER_ZERO_CROSSINGS) ? "" : "\n ", v);
}
printf("\n};\n\n");