|
- #include <assert.h>
-
- #include "asserts.h"
- #include "StateVariableFilter.h"
- #include "TestSignal.h"
-
- /**
- * Simple test - can we get output that looks kind of low pass
- */
- template <typename T>
- static void test1()
- {
- StateVariableFilterParams<T> params;
- StateVariableFilterState<T> state;
- params.setMode(StateVariableFilterParams<T>::Mode::LowPass);
- params.setFreq(T(.05)); // TODO: make an even fraction
- params.setQ(T(.7));
-
- T lastValue = -1;
- for (int i = 0; i < 5; ++i) {
- T output = StateVariableFilter<T>::run(1, state, params);
- assert(output > lastValue);
- lastValue = output;
- }
- }
-
-
- /**
- * Measure freq response at some points
- */
- template <typename T>
- static void testLowpass()
- {
- const T fc = T(.001);
- const T q = T(1.0 / std::sqrt(2)); // butterworth
- StateVariableFilterParams<T> params;
- StateVariableFilterState<T> state;
- params.setMode(StateVariableFilterParams<T>::Mode::LowPass);
- params.setFreq(fc); // TODO: make an even fraction
- params.setQ(q);
-
- double g = TestSignal<T>::measureGain(fc / 4, [&state, ¶ms](T input) {
- return StateVariableFilter<T>::run(input, state, params);
- });
- g = AudioMath::db(g);
- assert(AudioMath::closeTo(g, 0, .05));
-
- g = TestSignal<T>::measureGain(fc, [&state, ¶ms](T input) {
- return StateVariableFilter<T>::run(input, state, params);
- });
- g = AudioMath::db(g);
- assert(AudioMath::closeTo(g, -3, .05));
-
- double g2 = TestSignal<T>::measureGain(fc * 4, [&state, ¶ms](T input) {
- return StateVariableFilter<T>::run(input, state, params);
- });
- g2 = AudioMath::db(g2);
-
- double g3 = TestSignal<T>::measureGain(fc * 8, [&state, ¶ms](T input) {
- return StateVariableFilter<T>::run(input, state, params);
- });
- g3 = AudioMath::db(g3);
- assert(AudioMath::closeTo(g2 - g3, 12, 2));
- }
-
- /**
- * Verify that passband gain tracks Q
- */
- static void testBandpass()
- {
- const float fc = .01f;
- const float q = (1.0f / float(std::sqrt(2))); // butterworth
- StateVariableFilterParams<float> params;
- StateVariableFilterState<float> state;
- params.setMode(StateVariableFilterParams<float>::Mode::BandPass);
- params.setFreq(fc); // TODO: make an even fraction
- params.setQ(q);
-
- double g0 = TestSignal<float>::measureGain(fc, [&state, ¶ms](float input) {
- return StateVariableFilter<float>::run(input, state, params);
- });
- g0 = AudioMath::db(g0);
-
- for (int i = 2; i < 100; i *= 2) {
- const float q = float(i);
- params.setQ(q);
-
- double g = TestSignal<float>::measureGain(fc, [&state, ¶ms](float input) {
- return StateVariableFilter<float>::run(input, state, params);
- });
- g = AudioMath::db(g);
- // printf("q = %f, gain db = %f qdb=%f\n", q, g, AudioMath::db(q));
-
- assertClose(g, AudioMath::db(q), .5);
- }
- }
-
- template <typename T>
- static void testSetBandwidth()
- {
- StateVariableFilterParams<T> params;
- params.setNormalizedBandwidth(T(.1));
- assertEQ(params.getNormalizedBandwidth(), T(.1));
-
- params.setNormalizedBandwidth(T(.5));
- assertEQ(params.getNormalizedBandwidth(), T(.5));
-
- params.setQ(10);
- assertEQ(params.getNormalizedBandwidth(), T(.1))
- }
-
- template <typename T>
- static void test()
- {
- test1<T>();
- testLowpass<T>();
- testSetBandwidth<T>();
- }
-
- void testStateVariable()
- {
- test<float>();
- test<double>();
- testBandpass();
- }
|