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.

313 lines
7.1KB

  1. #include "FFTCrossFader.h"
  2. #include "ColoredNoise.h"
  3. #include "asserts.h"
  4. #include <vector>
  5. class Tester
  6. {
  7. public:
  8. Tester(int crossFadeSize, int frameSize) :
  9. f(crossFadeSize)
  10. {
  11. for (int i = 0; i < 3; ++i) {
  12. std::shared_ptr<NoiseMessage> p = std::make_shared<NoiseMessage>(frameSize);
  13. messages.push_back(p);
  14. }
  15. }
  16. FFTCrossFader f;
  17. std::vector< std::shared_ptr<NoiseMessage> > messages;
  18. };
  19. // accepting data on empty should not return on
  20. static void test0()
  21. {
  22. Tester test(4, 10);
  23. assertEQ(test.messages[0]->dataBuffer->get(0), 0);
  24. assertEQ(test.messages[0]->dataBuffer->get(9), 0);
  25. NoiseMessage* t = test.f.acceptData(test.messages[0].get());
  26. assertEQ(t, 0);
  27. }
  28. //empty should return 0
  29. static void test1()
  30. {
  31. Tester test(4, 10);
  32. for (int i = 0; i < 20; ++i) {
  33. float x = 5;
  34. test.f.step(&x);
  35. assertEQ(x, 0);
  36. }
  37. }
  38. // one buff, should play it
  39. static void test2()
  40. {
  41. Tester test(4, 10);
  42. for (int i = 0; i < 10; ++i) {
  43. test.messages[0]->dataBuffer->set(i, float(i));
  44. }
  45. NoiseMessage* t = test.f.acceptData(test.messages[0].get());
  46. assertEQ(t, 0);
  47. // pluy buffer once
  48. for (int i = 0; i < 10; ++i) {
  49. float x = 5;
  50. test.f.step(&x);
  51. assertEQ(x, i);
  52. }
  53. //play it again.
  54. for (int i = 0; i < 10; ++i) {
  55. float x = 5;
  56. test.f.step(&x);
  57. assertEQ(x, i);
  58. }
  59. }
  60. // two buff, should crossfade
  61. static void test3(bool testBuff0)
  62. {
  63. Tester test(4, 10);
  64. // fill the buff to test with data, other one with zeros
  65. for (int i = 0; i < 10; ++i) {
  66. test.messages[0]->dataBuffer->set(i, testBuff0 ? 9.f : 0.f);
  67. test.messages[1]->dataBuffer->set(i, testBuff0 ? 0.f : 18.f);
  68. }
  69. // put both in, to cross fade
  70. NoiseMessage* t = test.f.acceptData(test.messages[0].get());
  71. assertEQ(t, 0);
  72. t = test.f.acceptData(test.messages[1].get());
  73. assertEQ(t, 0);
  74. int emptyCount = 0;
  75. // play buffer once
  76. // buffer 0 full of 9, so should see fade 9..0
  77. float expected0[] = {9, 6, 3, 0, 0, 0, 0, 0, 0, 0};
  78. // buffer 0 all zero, 1 all 18, so should see 0..18
  79. float expected1[] = {0, 6, 12, 18, 18, 18, 18, 18, 18, 18};
  80. for (int i = 0; i < 10; ++i) {
  81. float x = 5;
  82. t = test.f.step(&x);
  83. if (t) {
  84. ++emptyCount;
  85. }
  86. const float expected = testBuff0 ? expected0[i] : expected1[i];
  87. assertEQ(x, expected);
  88. }
  89. //play it again.
  90. for (int i = 0; i < 10; ++i) {
  91. float x = 5;
  92. // test.f.step(&x);
  93. t = test.f.step(&x);
  94. if (t) {
  95. ++emptyCount;
  96. }
  97. const float expectedTail = testBuff0 ? 0.f : 18.f;
  98. assertEQ(x, expectedTail);
  99. }
  100. assertEQ(emptyCount, 1);
  101. }
  102. // two buff, should crossfade. odd size crossfade
  103. static void test7(bool testBuff0)
  104. {
  105. Tester test(5, 10);
  106. // fill the buff to test with data, other one with zeros
  107. for (int i = 0; i < 10; ++i) {
  108. test.messages[0]->dataBuffer->set(i, testBuff0 ? 12.f : 0.f);
  109. test.messages[1]->dataBuffer->set(i, testBuff0 ? 0.f : 24.f);
  110. }
  111. // put both in, to cross fade
  112. NoiseMessage* t = test.f.acceptData(test.messages[0].get());
  113. assertEQ(t, 0);
  114. t = test.f.acceptData(test.messages[1].get());
  115. assertEQ(t, 0);
  116. int emptyCount = 0;
  117. // play buffer once
  118. float expected0[] = {12, 9, 6, 3, 0, 0, 0, 0, 0, 0};
  119. float expected1[] = {0, 6, 12, 18, 24, 24, 24, 24, 24, 24};
  120. for (int i = 0; i < 10; ++i) {
  121. float x = 5;
  122. t = test.f.step(&x);
  123. if (t) {
  124. ++emptyCount;
  125. }
  126. const float expected = testBuff0 ? expected0[i] : expected1[i];
  127. assertEQ(x, expected);
  128. }
  129. //play it again.
  130. for (int i = 0; i < 10; ++i) {
  131. float x = 5;
  132. // test.f.step(&x);
  133. t = test.f.step(&x);
  134. if (t) {
  135. ++emptyCount;
  136. }
  137. const float expectedTail = testBuff0 ? 0.f : 24.f;
  138. assertEQ(x, expectedTail);
  139. }
  140. assertEQ(emptyCount, 1);
  141. }
  142. // extra buffer rejected
  143. static void test4()
  144. {
  145. Tester test(4, 10);
  146. NoiseMessage* t = test.f.acceptData(test.messages[0].get());
  147. assertEQ(t, 0);
  148. t = test.f.acceptData(test.messages[1].get());
  149. assertEQ(t, 0);
  150. t = test.f.acceptData(test.messages[2].get());
  151. assertNE(t, 0);
  152. }
  153. // test wrap-around case
  154. static void test5()
  155. {
  156. // fade of 4, buffer of 8
  157. Tester test(4, 8);
  158. // fill the buff to test with data, other one with zeros
  159. for (int i = 0; i < 8; ++i) {
  160. test.messages[0]->dataBuffer->set(i, 0.f);
  161. test.messages[1]->dataBuffer->set(i, float(i));
  162. }
  163. // put zero 0
  164. NoiseMessage* t = test.f.acceptData(test.messages[0].get());
  165. float x;
  166. // clock 6
  167. for (int i = 0; i < 6; ++i) {
  168. x = 5;
  169. t = test.f.step(&x);
  170. assertEQ(x, 0); // 0
  171. assertEQ(t, 0);
  172. }
  173. // now start crossfade
  174. t = test.f.acceptData(test.messages[1].get());
  175. assertEQ(t, 0);
  176. // sample #6. start fade
  177. t = test.f.step(&x);
  178. assertEQ(x, 0); // 0
  179. assertEQ(t, 0);
  180. // sample #7. fade #2
  181. t = test.f.step(&x);
  182. assertClose(x, .3333333f, .0001); // 0
  183. assertEQ(t, 0);
  184. // sample#8, fade #3
  185. t = test.f.step(&x);
  186. assertClose(x, 1.3333333f, .0001); // 0
  187. assertEQ(t, 0);
  188. // sample#8, fade #4 (last), buff 0 (?) gets returned
  189. t = test.f.step(&x);
  190. assertClose(x, 3.f, .0001); // 0
  191. assertNE(t, 0);
  192. // done fading
  193. t = test.f.step(&x);
  194. assertClose(x, 4.f, .0001); // 0
  195. assertEQ(t, 0);
  196. t = test.f.step(&x);
  197. assertClose(x, 5.f, .0001); // 0
  198. assertEQ(t, 0);
  199. t = test.f.step(&x);
  200. assertClose(x, 6.f, .0001); // 0
  201. assertEQ(t, 0);
  202. t = test.f.step(&x);
  203. assertClose(x, 7.f, .0001); // 0
  204. assertEQ(t, 0);
  205. t = test.f.step(&x);
  206. assertClose(x, 0.f, .0001); // 0
  207. assertEQ(t, 0);
  208. }
  209. // test makeup gain
  210. static void test6(bool makeup)
  211. {
  212. // fade of 5, buffer of 8
  213. Tester test(5, 8);
  214. test.f.enableMakeupGain(makeup);
  215. // fill the buffers with 1
  216. for (int i = 0; i < 8; ++i) {
  217. test.messages[0]->dataBuffer->set(i, 1.f);
  218. test.messages[1]->dataBuffer->set(i, 1.f);
  219. }
  220. // put messages
  221. test.f.acceptData(test.messages[0].get());
  222. test.f.acceptData(test.messages[1].get());
  223. float x;
  224. for (int i = 0; i < 5; ++i) {
  225. x = 5;
  226. test.f.step(&x);
  227. float expected = 1;
  228. if (makeup) switch (i) {
  229. case 0:
  230. case 4:
  231. expected = 1;
  232. break;
  233. case 2:
  234. expected = std::sqrt(2.f);
  235. break;
  236. case 1:
  237. case 3:
  238. expected = (1.f + std::sqrt(2.f)) / 2.f;
  239. break;
  240. default: assert(false);
  241. }
  242. assertClose(x, expected, .0001);
  243. }
  244. }
  245. void testFFTCrossFader()
  246. {
  247. assertEQ(FFTDataReal::_count, 0);
  248. test0();
  249. test1();
  250. test2();
  251. test3(true);
  252. test3(false);
  253. test7(true);
  254. test7(false);
  255. test4();
  256. test5();
  257. test6(false);
  258. test6(true);
  259. assertEQ(FFTDataReal::_count, 0);
  260. }