Use class methods for BandSplitter and SplitterAllpass filters

This commit is contained in:
Chris Robinson
2018-12-05 15:38:05 -08:00
parent 10b39d57d5
commit e60d0886d0
6 changed files with 60 additions and 65 deletions
+3 -3
View File
@@ -1549,11 +1549,11 @@ void ApplyStablizer(FrontStablizer *Stablizer, ALfloat (*RESTRICT Buffer)[BUFFER
{
if(i == lidx || i == ridx)
continue;
splitterap_process(&Stablizer->APFilter[i], Buffer[i], SamplesToDo);
Stablizer->APFilter[i].process(Buffer[i], SamplesToDo);
}
bandsplit_process(&Stablizer->LFilter, lsplit[1], lsplit[0], Buffer[lidx], SamplesToDo);
bandsplit_process(&Stablizer->RFilter, rsplit[1], rsplit[0], Buffer[ridx], SamplesToDo);
Stablizer->LFilter.process(lsplit[1], lsplit[0], Buffer[lidx], SamplesToDo);
Stablizer->RFilter.process(rsplit[1], rsplit[0], Buffer[ridx], SamplesToDo);
for(i = 0;i < SamplesToDo;i++)
{
+8 -11
View File
@@ -139,7 +139,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount
memset(dec->UpSampler, 0, sizeof(dec->UpSampler));
ratio = 400.0f / (ALfloat)srate;
for(i = 0;i < 4;i++)
bandsplit_init(&dec->UpSampler[i].XOver, ratio);
dec->UpSampler[i].XOver.init(ratio);
if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
{
periphonic = true;
@@ -216,7 +216,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount
ratio = conf->XOverFreq / (ALfloat)srate;
for(i = 0;i < MAX_AMBI_COEFFS;i++)
bandsplit_init(&dec->XOver[i], ratio);
dec->XOver[i].init(ratio);
ratio = powf(10.0f, conf->XOverRatio / 40.0f);
for(i = 0;i < conf->NumSpeakers;i++)
@@ -285,8 +285,8 @@ void bformatdec_process(struct BFormatDec *dec, ALfloat (*RESTRICT OutBuffer)[BU
if(dec->DualBand)
{
for(i = 0;i < dec->NumChannels;i++)
bandsplit_process(&dec->XOver[i], dec->SamplesHF[i].data(), dec->SamplesLF[i].data(),
InSamples[i], SamplesToDo);
dec->XOver[i].process(dec->SamplesHF[i].data(), dec->SamplesLF[i].data(), InSamples[i],
SamplesToDo);
for(chan = 0;chan < OutChannels;chan++)
{
@@ -344,8 +344,7 @@ void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*RESTRICT OutBuffer)[B
/* First, split the first-order components into low and high frequency
* bands.
*/
bandsplit_process(&dec->UpSampler[i].XOver,
dec->Samples[HF_BAND].data(), dec->Samples[LF_BAND].data(),
dec->UpSampler[i].XOver.process(dec->Samples[HF_BAND].data(), dec->Samples[LF_BAND].data(),
InSamples[i], SamplesToDo
);
@@ -365,7 +364,7 @@ void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device, ALfloat
ratio = 400.0f / (ALfloat)device->Frequency;
for(i = 0;i < 4;i++)
bandsplit_init(&ambiup->XOver[i], ratio);
ambiup->XOver[i].init(ratio);
memset(ambiup->Gains, 0, sizeof(ambiup->Gains));
if(device->Dry.CoeffCount > 0)
@@ -419,10 +418,8 @@ void ambiup_process(struct AmbiUpsampler *ambiup, ALfloat (*RESTRICT OutBuffer)[
for(i = 0;i < 4;i++)
{
bandsplit_process(&ambiup->XOver[i],
ambiup->Samples[HF_BAND], ambiup->Samples[LF_BAND],
InSamples[i], SamplesToDo
);
ambiup->XOver[i].process(ambiup->Samples[HF_BAND], ambiup->Samples[LF_BAND], InSamples[i],
SamplesToDo);
for(j = 0;j < OutChannels;j++)
MixRowSamples(OutBuffer[j], ambiup->Gains[i][j],
+30 -33
View File
@@ -9,37 +9,36 @@
#include "math_defs.h"
void bandsplit_init(BandSplitter *splitter, float f0norm)
void BandSplitter::init(float f0norm)
{
float w = f0norm * F_TAU;
float cw = std::cos(w);
if(cw > FLT_EPSILON)
splitter->coeff = (std::sin(w) - 1.0f) / cw;
coeff = (std::sin(w) - 1.0f) / cw;
else
splitter->coeff = cw * -0.5f;
coeff = cw * -0.5f;
splitter->lp_z1 = 0.0f;
splitter->lp_z2 = 0.0f;
splitter->hp_z1 = 0.0f;
lp_z1 = 0.0f;
lp_z2 = 0.0f;
hp_z1 = 0.0f;
}
void bandsplit_clear(BandSplitter *splitter)
void BandSplitter::clear()
{
splitter->lp_z1 = 0.0f;
splitter->lp_z2 = 0.0f;
splitter->hp_z1 = 0.0f;
lp_z1 = 0.0f;
lp_z2 = 0.0f;
hp_z1 = 0.0f;
}
void bandsplit_process(BandSplitter *splitter, float *RESTRICT hpout, float *RESTRICT lpout,
const ALfloat *input, int count)
void BandSplitter::process(float *RESTRICT hpout, float *RESTRICT lpout, const float *input, int count)
{
ASSUME(count > 0);
const float ap_coeff{splitter->coeff};
const float lp_coeff{splitter->coeff*0.5f + 0.5f};
float lp_z1{splitter->lp_z1};
float lp_z2{splitter->lp_z2};
float ap_z1{splitter->hp_z1};
const float ap_coeff{this->coeff};
const float lp_coeff{this->coeff*0.5f + 0.5f};
float lp_z1{this->lp_z1};
float lp_z2{this->lp_z2};
float ap_z1{this->hp_z1};
auto proc_sample = [ap_coeff,lp_coeff,&lp_z1,&lp_z2,&ap_z1,&lpout](const float in) noexcept -> float
{
/* Low-pass sample processing. */
@@ -60,36 +59,34 @@ void bandsplit_process(BandSplitter *splitter, float *RESTRICT hpout, float *RES
/* High-pass generated from removing low-passed output. */
return ap_y - lp_y;
};
std::transform<const float*RESTRICT>(input, input+count, hpout, proc_sample);
splitter->lp_z1 = lp_z1;
splitter->lp_z2 = lp_z2;
splitter->hp_z1 = ap_z1;
std::transform(input, input+count, hpout, proc_sample);
this->lp_z1 = lp_z1;
this->lp_z2 = lp_z2;
this->hp_z1 = ap_z1;
}
void splitterap_init(SplitterAllpass *splitter, float f0norm)
void SplitterAllpass::init(float f0norm)
{
float w = f0norm * F_TAU;
float cw = std::cos(w);
if(cw > FLT_EPSILON)
splitter->coeff = (std::sin(w) - 1.0f) / cw;
coeff = (std::sin(w) - 1.0f) / cw;
else
splitter->coeff = cw * -0.5f;
coeff = cw * -0.5f;
splitter->z1 = 0.0f;
z1 = 0.0f;
}
void splitterap_clear(SplitterAllpass *splitter)
{
splitter->z1 = 0.0f;
}
void SplitterAllpass::clear()
{ z1 = 0.0f; }
void splitterap_process(SplitterAllpass *splitter, float *RESTRICT samples, int count)
void SplitterAllpass::process(float *RESTRICT samples, int count)
{
ASSUME(count > 0);
const float coeff{splitter->coeff};
float z1{splitter->z1};
const float coeff{this->coeff};
float z1{this->z1};
auto proc_sample = [coeff,&z1](const float in) noexcept -> float
{
float out{in*coeff + z1};
@@ -97,5 +94,5 @@ void splitterap_process(SplitterAllpass *splitter, float *RESTRICT samples, int
return out;
};
std::transform(samples, samples+count, samples, proc_sample);
splitter->z1 = z1;
this->z1 = z1;
}
+12 -11
View File
@@ -6,29 +6,30 @@
/* Band splitter. Splits a signal into two phase-matching frequency bands. */
struct BandSplitter {
class BandSplitter {
float coeff{0.0f};
float lp_z1{0.0f};
float lp_z2{0.0f};
float hp_z1{0.0f};
};
void bandsplit_init(BandSplitter *splitter, float f0norm);
void bandsplit_clear(BandSplitter *splitter);
void bandsplit_process(BandSplitter *splitter, float *RESTRICT hpout, float *RESTRICT lpout,
const float *input, int count);
public:
void init(float f0norm);
void clear();
void process(float *RESTRICT hpout, float *RESTRICT lpout, const float *input, int count);
};
/* The all-pass portion of the band splitter. Applies the same phase shift
* without splitting the signal.
*/
struct SplitterAllpass {
class SplitterAllpass {
float coeff{0.0f};
float z1{0.0f};
};
void splitterap_init(SplitterAllpass *splitter, float f0norm);
void splitterap_clear(SplitterAllpass *splitter);
void splitterap_process(SplitterAllpass *splitter, float *RESTRICT samples, int count);
public:
void init(float f0norm);
void clear();
void process(float *RESTRICT samples, int count);
};
struct FrontStablizer {
+5 -5
View File
@@ -309,7 +309,7 @@ void BuildBFormatHrtf(const struct Hrtf *Hrtf, DirectHrtfState *state, ALsizei N
ALfloat temps[3][HRIR_LENGTH]{};
BandSplitter splitter;
bandsplit_init(&splitter, 400.0f / (ALfloat)Hrtf->sampleRate);
splitter.init(400.0f / (ALfloat)Hrtf->sampleRate);
for(ALsizei c{0};c < AmbiCount;++c)
{
const ALfloat (*fir)[2] = &Hrtf->coeffs[idx[c] * Hrtf->irSize];
@@ -334,10 +334,10 @@ void BuildBFormatHrtf(const struct Hrtf *Hrtf, DirectHrtfState *state, ALsizei N
else
{
/* Band-split left HRIR into low and high frequency responses. */
bandsplit_clear(&splitter);
splitter.clear();
for(ALsizei i{0};i < Hrtf->irSize;++i)
temps[2][i] = fir[i][0];
bandsplit_process(&splitter, temps[0], temps[1], temps[2], HRIR_LENGTH);
splitter.process(temps[0], temps[1], temps[2], HRIR_LENGTH);
/* Apply left ear response with delay. */
for(ALsizei i{0};i < NumChannels;++i)
@@ -354,10 +354,10 @@ void BuildBFormatHrtf(const struct Hrtf *Hrtf, DirectHrtfState *state, ALsizei N
}
/* Band-split right HRIR into low and high frequency responses. */
bandsplit_clear(&splitter);
splitter.clear();
for(ALsizei i{0};i < Hrtf->irSize;++i)
temps[2][i] = fir[i][1];
bandsplit_process(&splitter, temps[0], temps[1], temps[2], HRIR_LENGTH);
splitter.process(temps[0], temps[1], temps[2], HRIR_LENGTH);
/* Apply right ear response with delay. */
for(ALsizei i{0};i < NumChannels;++i)
+2 -2
View File
@@ -1031,11 +1031,11 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf
ALfloat scale = (ALfloat)(5000.0 / device->Frequency);
std::unique_ptr<FrontStablizer> stablizer{new FrontStablizer{}};
bandsplit_init(&stablizer->LFilter, scale);
stablizer->LFilter.init(scale);
stablizer->RFilter = stablizer->LFilter;
/* Initialize all-pass filters for all other channels. */
splitterap_init(&stablizer->APFilter[0], scale);
stablizer->APFilter[0].init(scale);
for(i = 1;i < (size_t)device->RealOut.NumChannels;i++)
stablizer->APFilter[i] = stablizer->APFilter[0];