Skip to content

Commit da27206

Browse files
committed
minor filter performance optimization
this only saves 0.1% CPU but this is probably the way i "should" do it
1 parent 63f2b85 commit da27206

File tree

2 files changed

+75
-17
lines changed

2 files changed

+75
-17
lines changed

source/Filter.cpp

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,50 @@ double StateVariableFilter::Process(double dt, double input, double cutoff, bool
4545
return highPass ? high : low;
4646
}
4747

48+
void MultiFilter::SetMode(FilterModes m)
49+
{
50+
if (currentMode != m)
51+
{
52+
previousMode = currentMode;
53+
currentMode = m;
54+
crossfading = true;
55+
currentModeMix = 0.0;
56+
}
57+
}
58+
4859
void MultiFilter::Process(double dt, double & l, double & r, double cutoff, bool highPass)
4960
{
50-
for (int i = 0; i < std::size(mix); i++)
51-
mix[i] += ((mode == i ? 1.0 : 0.0) - mix[i]) * 100.0 * dt;
61+
switch (crossfading)
62+
{
63+
case true:
64+
{
65+
currentModeMix += 100.0 * dt;
66+
if (currentModeMix >= 1.0)
67+
{
68+
auto current = currentMode;
69+
currentModeMix = 1.0;
70+
crossfading = false;
71+
filters[previousMode]->Reset();
72+
}
5273

53-
auto inL = l;
54-
auto inR = r;
55-
auto tempOutL = 0.0;
56-
auto tempOutR = 0.0;
57-
l = 0.0;
58-
r = 0.0;
74+
auto inL = l;
75+
auto inR = r;
76+
auto tempOutL = 0.0;
77+
auto tempOutR = 0.0;
78+
l = 0.0;
79+
r = 0.0;
5980

60-
for (int i = 0; i < std::size(filters); i++)
61-
{
62-
filters[i]->Process(dt, inL, inR, cutoff, tempOutL, tempOutR, highPass);
63-
l += tempOutL * mix[i];
64-
r += tempOutR * mix[i];
81+
filters[previousMode]->Process(dt, inL, inR, cutoff, tempOutL, tempOutR, highPass);
82+
l += tempOutL * (1.0 - currentModeMix);
83+
r += tempOutR * (1.0 - currentModeMix);
84+
filters[currentMode]->Process(dt, inL, inR, cutoff, tempOutL, tempOutR, highPass);
85+
l += tempOutL * currentModeMix;
86+
r += tempOutR * currentModeMix;
87+
88+
break;
89+
}
90+
case false:
91+
filters[currentMode]->Process(dt, l, r, cutoff, l, r, highPass);
92+
break;
6593
}
6694
}

source/Filter.h

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@ enum FilterModes
99
twoPole,
1010
fourPole,
1111
stateVariable,
12-
numFilterModes
12+
numFilterModes,
13+
noFilter
1314
};
1415

1516
class OnePoleFilter
1617
{
1718
public:
19+
void Reset()
20+
{
21+
a = 0.0;
22+
}
1823
double Process(double dt, double input, double cutoff, bool highPass = false);
1924

2025
private:
@@ -24,6 +29,11 @@ class OnePoleFilter
2429
class TwoPoleFilter
2530
{
2631
public:
32+
void Reset()
33+
{
34+
a = 0.0;
35+
b = 0.0;
36+
}
2737
double Process(double dt, double input, double cutoff, bool highPass = false);
2838

2939
private:
@@ -34,6 +44,13 @@ class TwoPoleFilter
3444
class FourPoleFilter
3545
{
3646
public:
47+
void Reset()
48+
{
49+
a = 0.0;
50+
b = 0.0;
51+
c = 0.0;
52+
d = 0.0;
53+
}
3754
double Process(double dt, double input, double cutoff, bool highPass = false);
3855

3956
private:
@@ -46,6 +63,11 @@ class FourPoleFilter
4663
class StateVariableFilter
4764
{
4865
public:
66+
void Reset()
67+
{
68+
band = 0.0;
69+
low = 0.0;
70+
}
4971
double Process(double dt, double input, double cutoff, bool highPass = false);
5072

5173
private:
@@ -57,13 +79,19 @@ class StateVariableFilter
5779
class DualFilterBase
5880
{
5981
public:
82+
virtual void Reset() {}
6083
virtual void Process(double dt, double inL, double inR, double cutoff, double &outL, double &outR, bool highPass = false) {}
6184
};
6285

6386
template<class T>
6487
class DualFilter : public DualFilterBase
6588
{
6689
public:
90+
void Reset()
91+
{
92+
left.Reset();
93+
right.Reset();
94+
}
6795
void Process(double dt, double inL, double inR, double cutoff, double &outL, double &outR, bool highPass = false)
6896
{
6997
outL = left.Process(dt, inL, cutoff, highPass);
@@ -78,16 +106,18 @@ class DualFilter : public DualFilterBase
78106
class MultiFilter
79107
{
80108
public:
81-
void SetMode(FilterModes m) { mode = m; }
109+
void SetMode(FilterModes m);
82110
void Process(double dt, double &l, double &r, double cutoff, bool highPass = false);
83111

84112
private:
85-
FilterModes mode = FilterModes::onePole;
86113
std::array<std::unique_ptr<DualFilterBase>, numFilterModes> filters = {
87114
std::unique_ptr<DualFilterBase>(new DualFilter<OnePoleFilter>()),
88115
std::unique_ptr<DualFilterBase>(new DualFilter<TwoPoleFilter>()),
89116
std::unique_ptr<DualFilterBase>(new DualFilter<FourPoleFilter>()),
90117
std::unique_ptr<DualFilterBase>(new DualFilter<StateVariableFilter>())
91118
};
92-
std::array<double, numFilterModes> mix = {0.0, 0.0, 0.0, 0.0};
119+
FilterModes currentMode = FilterModes::onePole;
120+
FilterModes previousMode = FilterModes::noFilter;
121+
bool crossfading = false;
122+
double currentModeMix = 1.0;
93123
};

0 commit comments

Comments
 (0)