You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
4.7KB

  1. /**
  2. *
  3. */
  4. #include <stdio.h>
  5. #include <assert.h>
  6. #include "ButterworthFilterDesigner.h"
  7. #include "BiquadFilter.h"
  8. #include "BiquadFilter.h"
  9. #include "BiquadParams.h"
  10. #include "BiquadParams.h"
  11. #include "BiquadState.h"
  12. #include "BiquadState.h"
  13. template<typename T, int N>
  14. void testState_0()
  15. {
  16. BiquadState<T, N> p;
  17. for (int i = 0; i < N; ++i) {
  18. assert(p.z0(i) == 0);
  19. assert(p.z1(i) == 0);
  20. }
  21. p.z0(0) = 5;
  22. p.z1(0) = 6;
  23. assert(p.z0(0) == 5);
  24. assert(p.z1(0) == 6);
  25. if (N > 1) {
  26. p.z0(N - 1) = 55;
  27. p.z1(N - 1) = 66;
  28. assert(p.z0(N - 1) == 55);
  29. assert(p.z1(N - 1) == 66);
  30. }
  31. assert(p.z0(0) == 5);
  32. assert(p.z1(0) == 6);
  33. }
  34. template<typename T, int N>
  35. void testParam_0()
  36. {
  37. BiquadParams<T, N> p;
  38. for (int i = 0; i < N; ++i) {
  39. assert(p.A2(i) == 0);
  40. assert(p.A1(i) == 0);
  41. assert(p.B0(i) == 0);
  42. assert(p.B1(i) == 0);
  43. assert(p.B2(i) == 0);
  44. }
  45. p.A1(0) = 1;
  46. p.A2(0) = 2;
  47. p.B0(0) = 10;
  48. p.B1(0) = 11;
  49. p.B2(0) = 12;
  50. assert(p.A1(0) == 1);
  51. assert(p.A2(0) == 2);
  52. assert(p.B0(0) == 10);
  53. assert(p.B1(0) == 11);
  54. assert(p.B2(0) == 12);
  55. if (N > 1) {
  56. p.A1(N - 1) = 111;
  57. p.A2(N - 1) = 112;
  58. p.B0(N - 1) = 1110;
  59. p.B1(N - 1) = 1111;
  60. p.B2(N - 1) = 1112;
  61. assert(p.A1(N - 1) == 111);
  62. assert(p.A2(N - 1) == 112);
  63. assert(p.B0(N - 1) == 1110);
  64. assert(p.B1(N - 1) == 1111);
  65. assert(p.B2(N - 1) == 1112);
  66. }
  67. assert(p.A1(0) == 1);
  68. assert(p.A2(0) == 2);
  69. assert(p.B0(0) == 10);
  70. assert(p.B1(0) == 11);
  71. assert(p.B2(0) == 12);
  72. }
  73. template<typename T>
  74. static void test2()
  75. {
  76. BiquadParams<T, 2> p;
  77. ButterworthFilterDesigner<T>::designThreePoleLowpass(p, T(.1));
  78. BiquadState<T, 2> s;
  79. T d = BiquadFilter<T>::run(0, s, p);
  80. (void) d;
  81. }
  82. // test that filter designer does something (more than just generate zero
  83. template<typename T>
  84. void testBasicDesigner2()
  85. {
  86. BiquadParams<T, 1> p;
  87. ButterworthFilterDesigner<T>::designTwoPoleLowpass(p, T(.1));
  88. assert(p.A1(0) != 0);
  89. assert(p.A2(0) != 0);
  90. assert(p.B1(0) != 0);
  91. assert(p.B2(0) != 0);
  92. assert(p.B0(0) != 0);
  93. }
  94. // test that filter designer does something (more than just generate zero
  95. template<typename T>
  96. void testBasicDesigner3()
  97. {
  98. BiquadParams<T, 2> p;
  99. ButterworthFilterDesigner<T>::designThreePoleLowpass(p, T(.1));
  100. assert(p.A1(0) != 0);
  101. assert(p.A2(0) != 0);
  102. assert(p.B1(0) != 0);
  103. assert(p.B2(0) != 0);
  104. assert(p.B0(0) != 0);
  105. }
  106. // test that filter does something
  107. template<typename T>
  108. void testBasicFilter2()
  109. {
  110. BiquadParams<T, 1> params;
  111. BiquadState<T, 1> state;
  112. ButterworthFilterDesigner<T>::designTwoPoleLowpass(params, T(.1));
  113. T lastValue = -1;
  114. // the first five values of the step increase
  115. for (int i = 0; i < 100; ++i) {
  116. T temp = BiquadFilter<T>::run(1, state, params);
  117. if (i < 5) {
  118. // the first 5 are strictly increasing and below 1
  119. assert(temp < 1);
  120. assert(temp > lastValue);
  121. } else if (i < 10) {
  122. // the next are all overshoot
  123. assert(temp > 1 && temp < 1.05);
  124. } else if (i > 50) {
  125. //settled
  126. assert(temp > .999 && temp < 1.001);
  127. }
  128. lastValue = temp;
  129. }
  130. const T val = BiquadFilter<T>::run(1, state, params);
  131. (void) val;
  132. }
  133. // test that filter does something
  134. template<typename T>
  135. void testBasicFilter3()
  136. {
  137. BiquadParams<T, 2> params;
  138. BiquadState<T, 2> state;
  139. ButterworthFilterDesigner<T>::designThreePoleLowpass(params, T(.1));
  140. T lastValue = 1;
  141. //the first five values of the step decrease (to -1)
  142. for (int i = 0; i < 100; ++i) {
  143. T temp = BiquadFilter<T>::run(1, state, params);
  144. if (i < 6) {
  145. // the first 5 are strictly increasing and below 1
  146. assert(temp > -1);
  147. assert(temp < lastValue);
  148. } else if (i < 10) {
  149. // the next are all overshoot
  150. assert(temp < -1);
  151. assert(temp > -1.1);
  152. } else if (i > 400) {
  153. //settled
  154. assert(temp < -.999 && temp > -1.001);
  155. }
  156. lastValue = temp;
  157. }
  158. }
  159. void testBiquad()
  160. {
  161. testState_0<double, 1>();
  162. testState_0<float, 8>();
  163. testParam_0<double, 1>();
  164. testParam_0<float, 8>();
  165. test2<float>();
  166. test2<double>();
  167. testBasicDesigner2<double>();
  168. testBasicDesigner2<float>();
  169. testBasicDesigner3<double>();
  170. testBasicDesigner3<float>();
  171. testBasicFilter2<double>();
  172. testBasicFilter2<float>();
  173. testBasicFilter3<double>();
  174. testBasicFilter3<float>();
  175. // TODO: actually measure the freq resp
  176. }