Keep bsinc info together in a struct
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
#include "static_assert.h"
|
||||
|
||||
#include "mixer_defs.h"
|
||||
#include "bsinc_inc.c"
|
||||
|
||||
#include "backends/base.h"
|
||||
|
||||
@@ -225,20 +226,6 @@ void aluInit(void)
|
||||
*/
|
||||
ALboolean BsincPrepare(const ALuint increment, BsincState *state)
|
||||
{
|
||||
static const ALfloat scaleBase = 1.510578918e-01f, scaleRange = 1.177936623e+00f;
|
||||
static const ALuint m[BSINC_SCALE_COUNT] = { 24, 24, 24, 24, 24, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 12 };
|
||||
static const ALuint to[4][BSINC_SCALE_COUNT] =
|
||||
{
|
||||
{ 0, 24, 408, 792, 1176, 1560, 1944, 2328, 2648, 2968, 3288, 3544, 3800, 4056, 4248, 4440 },
|
||||
{ 4632, 5016, 5400, 5784, 6168, 6552, 6936, 7320, 7640, 7960, 8280, 8536, 8792, 9048, 9240, 0 },
|
||||
{ 0, 9432, 9816, 10200, 10584, 10968, 11352, 11736, 12056, 12376, 12696, 12952, 13208, 13464, 13656, 13848 },
|
||||
{ 14040, 14424, 14808, 15192, 15576, 15960, 16344, 16728, 17048, 17368, 17688, 17944, 18200, 18456, 18648, 0 }
|
||||
};
|
||||
static const ALuint tm[2][BSINC_SCALE_COUNT] =
|
||||
{
|
||||
{ 0, 24, 24, 24, 24, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 12 },
|
||||
{ 24, 24, 24, 24, 24, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 0 }
|
||||
};
|
||||
ALfloat sf;
|
||||
ALsizei si, pi;
|
||||
ALboolean uncut = AL_TRUE;
|
||||
@@ -246,7 +233,7 @@ ALboolean BsincPrepare(const ALuint increment, BsincState *state)
|
||||
if(increment > FRACTIONONE)
|
||||
{
|
||||
sf = (ALfloat)FRACTIONONE / increment;
|
||||
if(sf < scaleBase)
|
||||
if(sf < bsinc.scaleBase)
|
||||
{
|
||||
/* Signal has been completely cut. The return result can be used
|
||||
* to skip the filter (and output zeros) as an optimization.
|
||||
@@ -257,7 +244,7 @@ ALboolean BsincPrepare(const ALuint increment, BsincState *state)
|
||||
}
|
||||
else
|
||||
{
|
||||
sf = (BSINC_SCALE_COUNT - 1) * (sf - scaleBase) * scaleRange;
|
||||
sf = (BSINC_SCALE_COUNT - 1) * (sf - bsinc.scaleBase) * bsinc.scaleRange;
|
||||
si = fastf2i(sf);
|
||||
/* The interpolation factor is fit to this diagonally-symmetric
|
||||
* curve to reduce the transition ripple caused by interpolating
|
||||
@@ -273,17 +260,17 @@ ALboolean BsincPrepare(const ALuint increment, BsincState *state)
|
||||
}
|
||||
|
||||
state->sf = sf;
|
||||
state->m = m[si];
|
||||
state->l = -(ALint)((m[si] / 2) - 1);
|
||||
state->m = bsinc.m[si];
|
||||
state->l = -((state->m/2) - 1);
|
||||
/* The CPU cost of this table re-mapping could be traded for the memory
|
||||
* cost of a complete table map (1024 elements large).
|
||||
*/
|
||||
for(pi = 0;pi < BSINC_PHASE_COUNT;pi++)
|
||||
{
|
||||
state->coeffs[pi].filter = &bsincTab[to[0][si] + tm[0][si]*pi];
|
||||
state->coeffs[pi].scDelta = &bsincTab[to[1][si] + tm[1][si]*pi];
|
||||
state->coeffs[pi].phDelta = &bsincTab[to[2][si] + tm[0][si]*pi];
|
||||
state->coeffs[pi].spDelta = &bsincTab[to[3][si] + tm[1][si]*pi];
|
||||
state->coeffs[pi].filter = &bsinc.Tab[bsinc.to[0][si] + bsinc.tm[0][si]*pi];
|
||||
state->coeffs[pi].scDelta = &bsinc.Tab[bsinc.to[1][si] + bsinc.tm[1][si]*pi];
|
||||
state->coeffs[pi].phDelta = &bsinc.Tab[bsinc.to[2][si] + bsinc.tm[0][si]*pi];
|
||||
state->coeffs[pi].spDelta = &bsinc.Tab[bsinc.to[3][si] + bsinc.tm[1][si]*pi];
|
||||
}
|
||||
return uncut;
|
||||
}
|
||||
|
||||
+990
-970
File diff suppressed because it is too large
Load Diff
@@ -707,7 +707,6 @@ SET(ALC_OBJS Alc/ALc.c
|
||||
Alc/effects/null.c
|
||||
Alc/effects/reverb.c
|
||||
Alc/helpers.c
|
||||
Alc/bsinc.c
|
||||
Alc/hrtf.c
|
||||
Alc/uhjfilter.c
|
||||
Alc/ambdec.c
|
||||
|
||||
@@ -71,7 +71,7 @@ extern enum Resampler ResamplerDefault;
|
||||
*/
|
||||
typedef struct BsincState {
|
||||
ALfloat sf; /* Scale interpolation factor. */
|
||||
ALuint m; /* Coefficient count. */
|
||||
ALsizei m; /* Coefficient count. */
|
||||
ALint l; /* Left coefficient offset. */
|
||||
struct {
|
||||
const ALfloat *filter; /* Filter coefficients. */
|
||||
@@ -382,7 +382,6 @@ inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max)
|
||||
{ return minu64(max, maxu64(min, val)); }
|
||||
|
||||
|
||||
extern alignas(16) const ALfloat bsincTab[18840];
|
||||
extern alignas(16) const ALfloat sinc4Tab[FRACTIONONE][4];
|
||||
|
||||
|
||||
|
||||
+60
-36
@@ -245,16 +245,32 @@ static void BsiGenerateTables()
|
||||
for(si = 1; si < BSINC_SCALE_COUNT; si++)
|
||||
i += BSINC_PHASE_COUNT * mt[si];
|
||||
|
||||
fprintf(stdout, "static const float bsincTab[%d] =\n{\n", i);
|
||||
fprintf(stdout, "/* Generated by bsincgen, do not edit! */\n\n"
|
||||
"/* Table of windowed sinc coefficients and deltas. This 11th order filter\n"
|
||||
" * has a rejection of -60 dB, yielding a transition width of ~0.302\n"
|
||||
" * (normalized frequency). Order increases when downsampling to a limit of\n"
|
||||
" * one octave, after which the quality of the filter (transition width)\n"
|
||||
" * suffers to reduce the CPU cost. The bandlimiting will cut all sound after\n"
|
||||
" * downsampling by ~2.73 octaves.\n"
|
||||
" */\n"
|
||||
"static const struct {\n"
|
||||
" alignas(16) const float Tab[%d];\n"
|
||||
" const float scaleBase, scaleRange;\n"
|
||||
" const int m[BSINC_SCALE_COUNT];\n"
|
||||
" const int to[4][BSINC_SCALE_COUNT];\n"
|
||||
" const int tm[2][BSINC_SCALE_COUNT];\n"
|
||||
"} bsinc = {\n", i);
|
||||
|
||||
fprintf(stdout, " /* Tab */ {\n");
|
||||
/* Only output enough coefficients for the first (cut) scale as needed to
|
||||
perform interpolation without extra branching.
|
||||
*/
|
||||
fprintf(stdout, " /* %2d,%2d */", mt[0], 0);
|
||||
fprintf(stdout, " /* %2d,%2d */", mt[0], 0);
|
||||
for(i = 0; i < mt[0]; i++)
|
||||
fprintf(stdout, " %+14.9ef,", filter[0][0][i]);
|
||||
fprintf(stdout, "\n\n");
|
||||
|
||||
fprintf(stdout, " /* Filters */\n");
|
||||
for(si = 1; si < BSINC_SCALE_COUNT; si++)
|
||||
{
|
||||
const int m = mt[si];
|
||||
@@ -262,7 +278,7 @@ static void BsiGenerateTables()
|
||||
|
||||
for(pi = 0; pi < BSINC_PHASE_COUNT; pi++)
|
||||
{
|
||||
fprintf(stdout, " /* %2d,%2d */", m, pi);
|
||||
fprintf(stdout, " /* %2d,%2d */", m, pi);
|
||||
for(i = 0; i < m; i++)
|
||||
fprintf(stdout, " %+14.9ef,", filter[si][pi][o + i]);
|
||||
fprintf(stdout, "\n");
|
||||
@@ -271,6 +287,7 @@ static void BsiGenerateTables()
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
// There are N-1 scale deltas for N scales.
|
||||
fprintf(stdout, " /* Scale deltas */\n");
|
||||
for(si = 0; si < (BSINC_SCALE_COUNT - 1); si++)
|
||||
{
|
||||
const int m = mt[si];
|
||||
@@ -278,7 +295,7 @@ static void BsiGenerateTables()
|
||||
|
||||
for(pi = 0; pi < BSINC_PHASE_COUNT; pi++)
|
||||
{
|
||||
fprintf(stdout, " /* %2d,%2d */", m, pi);
|
||||
fprintf(stdout, " /* %2d,%2d */", m, pi);
|
||||
for(i = 0; i < m; i++)
|
||||
fprintf(stdout, " %+14.9ef,", scDeltas[si][pi][o + i]);
|
||||
fprintf(stdout, "\n");
|
||||
@@ -287,6 +304,7 @@ static void BsiGenerateTables()
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
// Exclude phases for the first (cut) scale.
|
||||
fprintf(stdout, " /* Phase deltas */\n");
|
||||
for(si = 1; si < BSINC_SCALE_COUNT; si++)
|
||||
{
|
||||
const int m = mt[si];
|
||||
@@ -294,7 +312,7 @@ static void BsiGenerateTables()
|
||||
|
||||
for(pi = 0; pi < BSINC_PHASE_COUNT; pi++)
|
||||
{
|
||||
fprintf(stdout, " /* %2d,%2d */", m, pi);
|
||||
fprintf(stdout, " /* %2d,%2d */", m, pi);
|
||||
for(i = 0; i < m; i++)
|
||||
fprintf(stdout, " %+14.9ef,", phDeltas[si][pi][o + i]);
|
||||
fprintf(stdout, "\n");
|
||||
@@ -302,6 +320,7 @@ static void BsiGenerateTables()
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
fprintf(stdout, " /* Scale phase deltas */\n");
|
||||
for(si = 0; si < (BSINC_SCALE_COUNT - 1); si++)
|
||||
{
|
||||
const int m = mt[si];
|
||||
@@ -309,67 +328,67 @@ static void BsiGenerateTables()
|
||||
|
||||
for(pi = 0; pi < BSINC_PHASE_COUNT; pi++)
|
||||
{
|
||||
fprintf(stdout, " /* %2d,%2d */", m, pi);
|
||||
fprintf(stdout, " /* %2d,%2d */", m, pi);
|
||||
for(i = 0; i < m; i++)
|
||||
fprintf(stdout, " %+14.9ef,", spDeltas[si][pi][o + i]);
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
}
|
||||
fprintf(stdout, "};\n\n");
|
||||
fprintf(stdout, " },\n\n");
|
||||
|
||||
/* The scaleBase is calculated from the Kaiser window transition width.
|
||||
It represents the absolute limit to the filter before it fully cuts
|
||||
the signal. The limit in octaves can be calculated by taking the
|
||||
base-2 logarithm of its inverse: log_2(1 / scaleBase)
|
||||
*/
|
||||
fprintf(stdout, " static const ALfloat scaleBase = %.9ef, scaleRange = %.9ef;\n", scaleBase, 1.0 / scaleRange);
|
||||
fprintf(stdout, " static const ALuint m[BSINC_SCALE_COUNT] = {");
|
||||
fprintf(stdout, " /* scaleBase */ %.9ef, /* scaleRange */ %.9ef,\n", scaleBase, 1.0 / scaleRange);
|
||||
fprintf(stdout, " /* m */ {");
|
||||
|
||||
fprintf(stdout, " %d", mt[0]);
|
||||
for(si = 1; si < BSINC_SCALE_COUNT; si++)
|
||||
fprintf(stdout, ", %d", mt[si]);
|
||||
|
||||
fprintf(stdout, " };\n");
|
||||
fprintf(stdout, " static const ALuint to[4][BSINC_SCALE_COUNT] =\n {\n { 0");
|
||||
fprintf(stdout, " },\n");
|
||||
fprintf(stdout, " /* to */ {\n { %5d", 0);
|
||||
|
||||
i = mt[0];
|
||||
for(si = 1; si < BSINC_SCALE_COUNT; si++)
|
||||
{
|
||||
fprintf(stdout, ", %d", i);
|
||||
fprintf(stdout, ", %5d", i);
|
||||
i += BSINC_PHASE_COUNT * mt[si];
|
||||
}
|
||||
fprintf(stdout, " },\n {");
|
||||
for(si = 0; si < (BSINC_SCALE_COUNT - 1); si++)
|
||||
{
|
||||
fprintf(stdout, " %d,", i);
|
||||
fprintf(stdout, " %5d,", i);
|
||||
i += BSINC_PHASE_COUNT * mt[si];
|
||||
}
|
||||
fprintf(stdout, " 0 },\n { 0");
|
||||
fprintf(stdout, " %5d },\n { %5d", 0, 0);
|
||||
for(si = 1; si < BSINC_SCALE_COUNT; si++)
|
||||
{
|
||||
fprintf(stdout, ", %d", i);
|
||||
fprintf(stdout, ", %5d", i);
|
||||
i += BSINC_PHASE_COUNT * mt[si];
|
||||
}
|
||||
fprintf (stdout, " },\n {");
|
||||
for(si = 0; si < (BSINC_SCALE_COUNT - 1); si++)
|
||||
{
|
||||
fprintf(stdout, " %d,", i);
|
||||
fprintf(stdout, " %5d,", i);
|
||||
i += BSINC_PHASE_COUNT * mt[si];
|
||||
}
|
||||
fprintf(stdout, " 0 }\n };\n");
|
||||
fprintf(stdout, " %5d }\n },\n", 0);
|
||||
|
||||
fprintf(stdout, " static const ALuint tm[2][BSINC_SCALE_COUNT] = \n {\n { 0");
|
||||
fprintf(stdout, " /* tm */ {\n { 0");
|
||||
for(si = 1; si < BSINC_SCALE_COUNT; si++)
|
||||
fprintf(stdout, ", %d", mt[si]);
|
||||
fprintf(stdout, " },\n {");
|
||||
for(si = 0; si < (BSINC_SCALE_COUNT - 1); si++)
|
||||
fprintf(stdout, " %d,", mt[si]);
|
||||
fprintf(stdout, " 0 }\n };\n\n");
|
||||
fprintf(stdout, " 0 }\n }\n};\n\n");
|
||||
}
|
||||
|
||||
|
||||
/* These methods generate a much simplified 4-point sinc interpolator using a
|
||||
* Kaiser windows. This is much simpler to process at run-time, but has notably
|
||||
* Kaiser window. This is much simpler to process at run-time, but has notably
|
||||
* more aliasing noise.
|
||||
*/
|
||||
|
||||
@@ -377,30 +396,35 @@ static void BsiGenerateTables()
|
||||
#define FRACTIONBITS (12)
|
||||
#define FRACTIONONE (1<<FRACTIONBITS)
|
||||
|
||||
static double SincKaiser(double r, double x)
|
||||
{
|
||||
/* Limit rippling to -60dB. */
|
||||
return Kaiser(CalcKaiserBeta(60.0), x / r) * Sinc(x);
|
||||
}
|
||||
|
||||
static void Sinc4GenerateTables(void)
|
||||
{
|
||||
static double filter[FRACTIONONE][4];
|
||||
|
||||
int i;
|
||||
for(i = 0;i < FRACTIONONE;i++)
|
||||
const double width = CalcKaiserWidth(BSINC_REJECTION, 4);
|
||||
const double beta = CalcKaiserBeta(BSINC_REJECTION);
|
||||
const double scaleBase = width / 2.0;
|
||||
const double scaleRange = 1.0 - scaleBase;
|
||||
const double scale = scaleBase + scaleRange;
|
||||
const double a = MinDouble(4.0, 4.0 / (2.0*scale));
|
||||
const int m = 2 * (int)floor(a);
|
||||
const int l = (m/2) - 1;
|
||||
int pi;
|
||||
for(pi = 0;pi < FRACTIONONE;pi++)
|
||||
{
|
||||
double mu = (double)i / FRACTIONONE;
|
||||
filter[i][0] = SincKaiser(2.0, mu - -1.0);
|
||||
filter[i][1] = SincKaiser(2.0, mu - 0.0);
|
||||
filter[i][2] = SincKaiser(2.0, mu - 1.0);
|
||||
filter[i][3] = SincKaiser(2.0, mu - 2.0);
|
||||
const double phase = l + ((double)pi / FRACTIONONE);
|
||||
int i;
|
||||
|
||||
for(i = 0;i < m;i++)
|
||||
{
|
||||
double x = i - phase;
|
||||
filter[pi][i] = Kaiser(beta, x / a) * Sinc(x);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "static const float sinc4Tab[%d][4] =\n{\n", FRACTIONONE);
|
||||
for(i = 0;i < FRACTIONONE;i++)
|
||||
fprintf(stdout, "alignas(16) const float sinc4Tab[FRACTIONONE][4] = {\n");
|
||||
for(pi = 0;pi < FRACTIONONE;pi++)
|
||||
fprintf(stdout, " { %+14.9ef, %+14.9ef, %+14.9ef, %+14.9ef },\n",
|
||||
filter[i][0], filter[i][1], filter[i][2], filter[i][3]);
|
||||
filter[pi][0], filter[pi][1], filter[pi][2], filter[pi][3]);
|
||||
fprintf(stdout, "};\n\n");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user