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.

384 lines
10KB

  1. #include <assert.h>
  2. #include "asserts.h"
  3. #include "EV3.h"
  4. #include "MinBLEPVCO.h"
  5. #include "TestComposite.h"
  6. static float sampleTime = 1.0f / 44100.0f;
  7. class TestMB
  8. {
  9. public:
  10. //static void setAllWaveforms(MinBLEPVCO* vco);
  11. // static void test1();
  12. static void testSync2();
  13. static void testSync3();
  14. static void setPitch(EV3<TestComposite>& ev3);
  15. };
  16. #if 0
  17. // puts non-zero in all the waveforms
  18. void TestMB::setAllWaveforms(MinBLEPVCO* vco)
  19. {
  20. // float * wave = vco->_getWaveforms();
  21. for (int i = 0; i < (int)MinBLEPVCO::Waveform::END; ++i) {
  22. vco->waveformOutputs[i] = 1;
  23. }
  24. }
  25. #endif
  26. #if 0
  27. void TestMB::test1()
  28. {
  29. MinBLEPVCO vco;
  30. setAllWaveforms(&vco);
  31. assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Saw), 0);
  32. assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Sin), 0);
  33. assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Square), 0);
  34. assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Tri), 0);
  35. assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Even), 0);
  36. vco.zeroOutputsExcept(MinBLEPVCO::Waveform::Saw);
  37. assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Saw), 0);
  38. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Sin), 0);
  39. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Square), 0);
  40. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Tri), 0);
  41. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Even), 0);
  42. // special case for even and sin
  43. setAllWaveforms(&vco);
  44. vco.zeroOutputsExcept(MinBLEPVCO::Waveform::Even);
  45. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Saw), 0);
  46. assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Sin), 0);
  47. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Square), 0);
  48. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Tri), 0);
  49. assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Even), 0);
  50. setAllWaveforms(&vco);
  51. vco.zeroOutputsExcept(MinBLEPVCO::Waveform::Square);
  52. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Saw), 0);
  53. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Sin), 0);
  54. assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Square), 0);
  55. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Tri), 0);
  56. assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Even), 0);
  57. }
  58. static void test0()
  59. {
  60. MinBLEPVCO vco;
  61. // Don't enable any waveforms
  62. // vco.setSampleTime(sampleTime);
  63. vco.setNormalizedFreq(1000 * sampleTime);
  64. vco.step();
  65. // should get nothing out.
  66. assert(vco.getWaveform(MinBLEPVCO::Waveform::Sin) == 0);
  67. assert(vco.getWaveform(MinBLEPVCO::Waveform::Square) == 0);
  68. assert(vco.getWaveform(MinBLEPVCO::Waveform::Saw) == 0);
  69. assert(vco.getWaveform(MinBLEPVCO::Waveform::Tri) == 0);
  70. assert(vco.getWaveform(MinBLEPVCO::Waveform::Even) == 0);
  71. }
  72. #endif
  73. static void testSaw1()
  74. {
  75. MinBLEPVCO vco;
  76. vco.setNormalizedFreq(1000 * sampleTime, sampleTime);
  77. vco.setWaveform(MinBLEPVCO::Waveform::Saw);
  78. vco.step();
  79. // should get saw out.
  80. // assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Sin), 0);
  81. // assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Square), 0);
  82. // assertNE(vco.getWaveform(MinBLEPVCO::Waveform::Saw), 0);
  83. // assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Tri), 0);
  84. // assertEQ(vco.getWaveform(MinBLEPVCO::Waveform::Even), 0);
  85. assertNE(vco.getOutput(), 0);
  86. }
  87. static void testSync1()
  88. {
  89. MinBLEPVCO vco;
  90. vco.setNormalizedFreq(1000 * sampleTime, sampleTime);
  91. vco.setWaveform(MinBLEPVCO::Waveform::Saw);
  92. float lastOut = -1000;
  93. vco.step();
  94. // first make sure it's going up.
  95. for (int i = 0; i < 10; ++i) {
  96. vco.step();
  97. const float x = vco.getOutput();
  98. assertGT(x, lastOut);
  99. lastOut = x;
  100. }
  101. vco.onMasterSync(10); // set a reset to VCO
  102. vco.step();
  103. const float x = vco.getOutput();
  104. assertLT(x, lastOut);
  105. }
  106. void TestMB::setPitch(EV3<TestComposite>& ev3)
  107. {
  108. ev3.params[EV3<TestComposite>::OCTAVE1_PARAM].value = 2;
  109. ev3.params[EV3<TestComposite>::OCTAVE2_PARAM].value = 3;
  110. ev3.params[EV3<TestComposite>::OCTAVE3_PARAM].value = 3;
  111. // raise 2,3 by an oct and a semitone
  112. ev3.params[EV3<TestComposite>::SEMI1_PARAM].value = 0;
  113. ev3.params[EV3<TestComposite>::SEMI2_PARAM].value = 1;
  114. ev3.params[EV3<TestComposite>::SEMI3_PARAM].value = 1;
  115. ev3.vcos[0].setWaveform(MinBLEPVCO::Waveform::Saw);
  116. ev3.vcos[1].setWaveform(MinBLEPVCO::Waveform::Saw);
  117. ev3.vcos[2].setWaveform(MinBLEPVCO::Waveform::Saw);
  118. ev3.params[EV3<TestComposite>::SYNC2_PARAM].value = 1;
  119. ev3.vcos[0].name = "VCO1";
  120. ev3.vcos[1].name = "VCO2";
  121. ev3.vcos[2].name = "VCO3";
  122. }
  123. void TestMB::testSync2()
  124. {
  125. printf("***** testSync2*****\n");
  126. EV3<TestComposite> ev3;
  127. setPitch(ev3);
  128. ev3.step();
  129. const float f0 = ev3._freq[0];
  130. const float f1 = ev3._freq[1];
  131. assertClose(f0, 2093.02, .005);
  132. assertClose(f1, 4434.95, .005);
  133. float last0 = -10;
  134. float last1 = -10;
  135. for (int i = 0; i < 100; ++i) {
  136. ev3.step();
  137. //printf("phase==%.2f phase1==%.2f ", ev3.vcos[0].phase, ev3.vcos[1].phase);
  138. float x = ev3._out[0];
  139. // assert(x > last0);
  140. //printf("%d delta0=%.2f",i, x - last0);
  141. last0 = x;
  142. x = ev3._out[1];
  143. // assert(x > last1);
  144. printf(" delta1=%.2f", x - last1);
  145. printf(" 0=%.2f 1=%.2f\n", last0, last1);
  146. fflush(stdout);
  147. last1 = x;
  148. }
  149. // TODO: test the sync on/off
  150. }
  151. void TestMB::testSync3()
  152. {
  153. EV3<TestComposite> ev3;
  154. setPitch(ev3);
  155. ev3.step();
  156. const float f0 = ev3._freq[0];
  157. const float f1 = ev3._freq[1];
  158. assertClose(f0, 2093.02, .01);
  159. assertClose(f1, 4434.95, .01);
  160. float last0 = -10;
  161. float last1 = -10;
  162. for (int i = 0; i < 100; ++i) {
  163. // printf("-------- sample %d -----------\n", i);
  164. ev3.step();
  165. }
  166. // TODO: test the sync on/off
  167. }
  168. // TODO: what is this??
  169. static void testBlepx(float crossing, float jump)
  170. {
  171. printf("BLEP crossing = %.2f, jump =%.2f\n", crossing, jump);
  172. SqBlep syncMinBLEP;
  173. syncMinBLEP.jump(-.5, -2);
  174. syncMinBLEP.jump(crossing, jump);
  175. for (int i = 0; i < 32; ++i) {
  176. //float saw = -1.0 + 2.0*phase;
  177. float x = syncMinBLEP.shift();
  178. printf("blep[%d] = %.2f\n", i, x);
  179. }
  180. }
  181. static void testEnums()
  182. {
  183. assertEQ((int) EV3<TestComposite>::Waves::SIN, (int) MinBLEPVCO::Waveform::Sin);
  184. assertEQ((int) EV3<TestComposite>::Waves::TRI, (int) MinBLEPVCO::Waveform::Tri);
  185. assertEQ((int) EV3<TestComposite>::Waves::SAW, (int) MinBLEPVCO::Waveform::Saw);
  186. assertEQ((int) EV3<TestComposite>::Waves::SQUARE, (int) MinBLEPVCO::Waveform::Square);
  187. assertEQ((int) EV3<TestComposite>::Waves::EVEN, (int) MinBLEPVCO::Waveform::Even);
  188. }
  189. static void testOutput(MinBLEPVCO::Waveform wf, bool expectFlat)
  190. {
  191. MinBLEPVCO osc;
  192. osc.setWaveform(wf);
  193. osc.setNormalizedFreq(.1f, 1.0f / 44100); // high freq
  194. bool hasChanged = false;
  195. float last = -100;
  196. for (int i = 0; i < 100; ++i) {
  197. osc.step();
  198. float x = osc.getOutput();
  199. if (!expectFlat) assertNE(x, last);
  200. if (last != x) hasChanged = true;
  201. last = x;
  202. }
  203. assert(hasChanged);
  204. }
  205. static void testOutputs()
  206. {
  207. testOutput(MinBLEPVCO::Waveform::Saw, false);
  208. testOutput(MinBLEPVCO::Waveform::Square, true);
  209. testOutput(MinBLEPVCO::Waveform::Sin, false);
  210. testOutput(MinBLEPVCO::Waveform::Tri, false);
  211. testOutput(MinBLEPVCO::Waveform::Even, false);
  212. }
  213. static void testBlep()
  214. {
  215. testBlepx(-.5, -2);
  216. testBlepx(-.5, 1);
  217. testBlepx(-.9f, .2f);
  218. }
  219. static void testZero()
  220. {
  221. MinBLEPVCO osc;
  222. osc.setWaveform(MinBLEPVCO::Waveform::Saw);
  223. osc.setNormalizedFreq(.1f, 1.0f / 44100); // high freq
  224. osc.step();
  225. osc.setWaveform(MinBLEPVCO::Waveform::END);
  226. osc.step();
  227. float x = osc.getOutput();
  228. assertEQ(x, 0);
  229. }
  230. static void testSyncOut(MinBLEPVCO::Waveform wf)
  231. {
  232. MinBLEPVCO osc;
  233. int callbackCount = 0;
  234. osc.setWaveform(wf);
  235. osc.setNormalizedFreq(.1f, 1.0f / 44100); // high freq
  236. osc.setSyncCallback([&callbackCount](float p) {
  237. assert(p <= 0 && p >= -1);
  238. callbackCount++;
  239. });
  240. for (int i = 0; i < 15; ++i) {
  241. osc.step();
  242. }
  243. assertEQ(callbackCount, 1);
  244. // assertGE(callbackCount, 1); // TODO: why does square do 3??
  245. }
  246. static void testSyncOut()
  247. {
  248. testSyncOut(MinBLEPVCO::Waveform::Saw);
  249. testSyncOut(MinBLEPVCO::Waveform::Square);
  250. testSyncOut(MinBLEPVCO::Waveform::Sin);
  251. testSyncOut(MinBLEPVCO::Waveform::Tri);
  252. testSyncOut(MinBLEPVCO::Waveform::Even);
  253. }
  254. static void testSyncIn(MinBLEPVCO::Waveform wf)
  255. {
  256. MinBLEPVCO osc;
  257. osc.setWaveform(wf);
  258. osc.setNormalizedFreq(.1f, 1.0f / 44100); // high freq
  259. for (int i = 0; i < 4; ++i) {
  260. osc.step();
  261. }
  262. osc.step();
  263. float x = osc.getOutput();
  264. osc.onMasterSync(0);
  265. osc.step(); // this one catches the callback
  266. osc.step(); // this one generates new sample (TODO: is this extra required?)
  267. float y = osc.getOutput();
  268. assert(!AudioMath::closeTo(x, y, .1));
  269. // TODO: pick freq that will make this more robust
  270. }
  271. static void testSyncIn()
  272. {
  273. testSyncIn(MinBLEPVCO::Waveform::Saw);
  274. testSyncIn(MinBLEPVCO::Waveform::Sin);
  275. testSyncIn(MinBLEPVCO::Waveform::Tri);
  276. testSyncIn(MinBLEPVCO::Waveform::Square);
  277. testSyncIn(MinBLEPVCO::Waveform::Even);
  278. }
  279. static void testNormal()
  280. {
  281. EV3<TestComposite> ev3;
  282. ev3.params[EV3<TestComposite>::MIX1_PARAM].value = 0;
  283. ev3.params[EV3<TestComposite>::MIX2_PARAM].value = 0;
  284. ev3.params[EV3<TestComposite>::MIX3_PARAM].value = 0;
  285. for (int i = 0; i < 4; ++i) ev3.step();
  286. assert(!ev3.isLoweringVolume());
  287. ev3.params[EV3<TestComposite>::MIX1_PARAM].value = 1;
  288. ev3.params[EV3<TestComposite>::MIX2_PARAM].value = 1;
  289. ev3.params[EV3<TestComposite>::MIX3_PARAM].value = 1;
  290. for (int i = 0; i < 4; ++i) ev3.step();
  291. assert(ev3.isLoweringVolume());
  292. }
  293. void testMinBLEPVCO()
  294. {
  295. // A lot of these tests are from old API
  296. // TestMB::test1();
  297. // printf("fix the minb tests\n");
  298. // test0();
  299. testSaw1();
  300. //testSync1();
  301. // this one doesn't work, either.
  302. //TestMB::testSync2();
  303. TestMB::testSync3();
  304. // testBlep();
  305. testEnums();
  306. testOutputs();
  307. testZero();
  308. testSyncOut();
  309. testSyncIn();
  310. testNormal();
  311. }