Pre-apply the crossfeed filter gain to the input sample coefficients
This commit is contained in:
+6
-7
@@ -38,7 +38,7 @@ static void init(struct bs2b *bs2b)
|
||||
{
|
||||
float Fc_lo, Fc_hi;
|
||||
float G_lo, G_hi;
|
||||
float x;
|
||||
float x, g;
|
||||
|
||||
bs2b->srate = clampi(bs2b->srate, 2000, 192000);
|
||||
|
||||
@@ -89,21 +89,20 @@ static void init(struct bs2b *bs2b)
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
g = 1.0f / (1.0f - G_hi + G_lo);
|
||||
|
||||
/* $fc = $Fc / $s;
|
||||
* $d = 1 / 2 / pi / $fc;
|
||||
* $x = exp(-1 / $d);
|
||||
*/
|
||||
|
||||
x = expf(-2.0f * F_PI * Fc_lo / bs2b->srate);
|
||||
bs2b->b1_lo = x;
|
||||
bs2b->a0_lo = G_lo * (1.0f - x);
|
||||
bs2b->a0_lo = G_lo * (1.0f - x) * g;
|
||||
|
||||
x = expf(-2.0f * F_PI * Fc_hi / bs2b->srate);
|
||||
bs2b->b1_hi = x;
|
||||
bs2b->a0_hi = 1.0f - G_hi * (1.0f - x);
|
||||
bs2b->a1_hi = -x;
|
||||
|
||||
bs2b->gain = 1.0f / (1.0f - G_hi + G_lo);
|
||||
bs2b->a0_hi = (1.0f - G_hi * (1.0f - x)) * g;
|
||||
bs2b->a1_hi = -x * g;
|
||||
} /* init */
|
||||
|
||||
/* Exported functions.
|
||||
|
||||
+10
-19
@@ -59,9 +59,6 @@ struct bs2b {
|
||||
float a1_hi;
|
||||
float b1_hi;
|
||||
|
||||
/* Global gain against overloading */
|
||||
float gain;
|
||||
|
||||
/* Buffer of last filtered sample.
|
||||
* [0] - first channel, [1] - second channel
|
||||
*/
|
||||
@@ -93,11 +90,9 @@ void bs2b_clear(struct bs2b *bs2b);
|
||||
|
||||
/* Crossfeeds one stereo sample that are pointed by sample.
|
||||
* [0] - first channel, [1] - second channel.
|
||||
* Returns crossfided samle by sample pointer.
|
||||
* Returns crossfided sample by sample pointer.
|
||||
*/
|
||||
|
||||
/* sample points to floats */
|
||||
inline void bs2b_cross_feed(struct bs2b *bs2b, float *restrict samples)
|
||||
inline void bs2b_cross_feed(struct bs2b *bs2b, float *restrict sample)
|
||||
{
|
||||
/* Single pole IIR filter.
|
||||
* O[n] = a0*I[n] + a1*I[n-1] + b1*O[n-1]
|
||||
@@ -110,22 +105,18 @@ inline void bs2b_cross_feed(struct bs2b *bs2b, float *restrict samples)
|
||||
#define hi_filter(in, in_1, out_1) (bs2b->a0_hi*(in) + bs2b->a1_hi*(in_1) + bs2b->b1_hi*(out_1))
|
||||
|
||||
/* Lowpass filter */
|
||||
bs2b->last_sample.lo[0] = lo_filter(samples[0], bs2b->last_sample.lo[0]);
|
||||
bs2b->last_sample.lo[1] = lo_filter(samples[1], bs2b->last_sample.lo[1]);
|
||||
bs2b->last_sample.lo[0] = lo_filter(sample[0], bs2b->last_sample.lo[0]);
|
||||
bs2b->last_sample.lo[1] = lo_filter(sample[1], bs2b->last_sample.lo[1]);
|
||||
|
||||
/* Highboost filter */
|
||||
bs2b->last_sample.hi[0] = hi_filter(samples[0], bs2b->last_sample.asis[0], bs2b->last_sample.hi[0]);
|
||||
bs2b->last_sample.hi[1] = hi_filter(samples[1], bs2b->last_sample.asis[1], bs2b->last_sample.hi[1]);
|
||||
bs2b->last_sample.asis[0] = samples[0];
|
||||
bs2b->last_sample.asis[1] = samples[1];
|
||||
bs2b->last_sample.hi[0] = hi_filter(sample[0], bs2b->last_sample.asis[0], bs2b->last_sample.hi[0]);
|
||||
bs2b->last_sample.hi[1] = hi_filter(sample[1], bs2b->last_sample.asis[1], bs2b->last_sample.hi[1]);
|
||||
bs2b->last_sample.asis[0] = sample[0];
|
||||
bs2b->last_sample.asis[1] = sample[1];
|
||||
|
||||
/* Crossfeed */
|
||||
samples[0] = bs2b->last_sample.hi[0] + bs2b->last_sample.lo[1];
|
||||
samples[1] = bs2b->last_sample.hi[1] + bs2b->last_sample.lo[0];
|
||||
|
||||
/* Bass boost cause allpass attenuation */
|
||||
samples[0] *= bs2b->gain;
|
||||
samples[1] *= bs2b->gain;
|
||||
sample[0] = bs2b->last_sample.hi[0] + bs2b->last_sample.lo[1];
|
||||
sample[1] = bs2b->last_sample.hi[1] + bs2b->last_sample.lo[0];
|
||||
#undef hi_filter
|
||||
#undef lo_filter
|
||||
} /* bs2b_cross_feed */
|
||||
|
||||
Reference in New Issue
Block a user