Add python3 to github action test deps
[zynaddsubfx-code.git] / src / Tests / KitTest.h
blob084fc55f1ebf2aa7deed70d37d98b5a3e0929af1
1 /*
2 ZynAddSubFX - a software synthesizer
4 KitTest.h - Test For Note Allocation Under Kits
5 Copyright (C) 2016 Mark McCurry
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 #include <cxxtest/TestSuite.h>
13 #include <cmath>
14 #include <cstring>
15 #include <cstdlib>
16 #include <iostream>
17 #include "../Misc/Time.h"
18 #include "../Misc/Allocator.h"
19 #include "../DSP/FFTwrapper.h"
20 #include "../Misc/Microtonal.h"
21 #define private public
22 #define protected public
23 #include "../Synth/SynthNote.h"
24 #include "../Misc/Part.h"
25 #include "../globals.h"
27 using namespace std;
28 using namespace zyn;
30 SYNTH_T *synth;
31 int dummy=0;
33 #define SUSTAIN_BIT 0x04
34 enum PrivateNoteStatus {
35 KEY_OFF = 0x00,
36 KEY_PLAYING = 0x01,
37 KEY_RELEASED_AND_SUSTAINED = 0x02,
38 KEY_RELEASED = 0x03
42 class KitTest:public CxxTest::TestSuite
44 private:
45 Alloc alloc;
46 FFTwrapper fft;
47 Microtonal microtonal;
48 Part *part;
49 AbsTime *time;
50 float *outL, *outR;
51 public:
52 KitTest()
53 :fft(512), microtonal(dummy)
55 void setUp() {
56 synth = new SYNTH_T;
57 time = new AbsTime(*synth);
58 outL = new float[synth->buffersize];
59 outR = new float[synth->buffersize];
60 memset(outL, 0, synth->bufferbytes);
61 memset(outR, 0, synth->bufferbytes);
64 part = new Part(alloc, *synth, *time, dummy, dummy, &microtonal, &fft);
67 //Standard poly mode with sustain
68 void testSustainCase1() {
69 //enable sustain
70 part->ctl.setsustain(127);
72 part->NoteOn(64, 127, 0);
73 part->NoteOn(64, 127, 0);
74 part->NoteOff(64);
76 //first note has moved to release state
77 //second note has moved to sustain state
79 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
80 (NotePool::NoteDescriptor{
81 .age=0,
82 .note=64,
83 .sendto=0,
84 .size=1,
85 .status=KEY_RELEASED|SUSTAIN_BIT,
86 .legatoMirror=false}));
88 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
89 (NotePool::NoteDescriptor{
90 .age=0,
91 .note=64,
92 .sendto=0,
93 .size=1,
94 .status=KEY_RELEASED_AND_SUSTAINED,
95 .legatoMirror=false}));
97 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
98 (NotePool::NoteDescriptor{
99 .age=0,
100 .note=0,
101 .sendto=0,
102 .size=0,
103 .status=0,
104 .legatoMirror=false}));
107 void testSustainCase2() {
108 //enable sustain
109 part->ctl.setsustain(127);
111 part->NoteOn(64, 127, 0);
112 part->NoteOff(64);
113 part->NoteOn(64, 127, 0);
115 //first note has moved to release state
116 //second note has stayed in playing state
118 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
119 (NotePool::NoteDescriptor{
120 .age=0,
121 .note=64,
122 .sendto=0,
123 .size=1,
124 .status=KEY_RELEASED|SUSTAIN_BIT,
125 .legatoMirror=false}));
127 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
128 (NotePool::NoteDescriptor{
129 .age=0,
130 .note=64,
131 .sendto=0,
132 .size=1,
133 .status=KEY_PLAYING,
134 .legatoMirror=false}));
136 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
137 (NotePool::NoteDescriptor{
138 .age=0,
139 .note=0,
140 .sendto=0,
141 .size=0,
142 .status=0,
143 .legatoMirror=false}));
146 void testMonoSustain() {
147 //enable sustain
148 part->ctl.setsustain(127);
149 part->Ppolymode = false;
151 part->NoteOn(64, 127, 0);
152 part->NoteOff(64);
153 part->NoteOn(65, 127, 0);
155 part->notePool.dump();
157 //first note has moved to release state
158 //second note has stayed in playing state
160 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
161 (NotePool::NoteDescriptor{
162 .age=0,
163 .note=64,
164 .sendto=0,
165 .size=1,
166 .status=KEY_RELEASED,
167 .legatoMirror=false}));
169 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
170 (NotePool::NoteDescriptor{
171 .age=0,
172 .note=65,
173 .sendto=0,
174 .size=1,
175 .status=KEY_PLAYING,
176 .legatoMirror=false}));
178 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
179 (NotePool::NoteDescriptor{
180 .age=0,
181 .note=0,
182 .sendto=0,
183 .size=0,
184 .status=0,
185 .legatoMirror=false}));
188 //Enumerate cases of:
189 //Legato = {disabled,enabled}
190 //Mono = {disabled, enabled}
191 //Kit = {off, normal, single}
192 //ignore legato=enabled, mono=enabled
194 //No Kit
195 void testNoKitNoLegatoNoMono() {
196 part->NoteOn(64, 127, 0);
197 part->NoteOn(65, 127, 0);
199 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
200 (NotePool::NoteDescriptor{
201 .age=0,
202 .note=64,
203 .sendto=0,
204 .size=1,
205 .status=KEY_PLAYING,
206 .legatoMirror=false}));
208 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
209 (NotePool::NoteDescriptor{
210 .age=0,
211 .note=65,
212 .sendto=0,
213 .size=1,
214 .status=KEY_PLAYING,
215 .legatoMirror=false}));
217 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
218 (NotePool::NoteDescriptor{
219 .age=0,
220 .note=0,
221 .sendto=0,
222 .size=0,
223 .status=0,
224 .legatoMirror=false}));
227 void testNoKitYesLegatoNoMono() {
228 part->Ppolymode = false;
229 part->Plegatomode = true;
230 part->NoteOn(64, 127, 0);
231 part->NoteOn(65, 127, 0);
233 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
234 (NotePool::NoteDescriptor{
235 .age=0,
236 .note=65,
237 .sendto=0,
238 .size=1,
239 .status=KEY_PLAYING,
240 .legatoMirror=false}));
242 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
243 (NotePool::NoteDescriptor{
244 .age=0,
245 .note=65,
246 .sendto=0,
247 .size=1,
248 .status=KEY_PLAYING,
249 .legatoMirror=false}));
251 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
252 (NotePool::NoteDescriptor{
253 .age=0,
254 .note=0,
255 .sendto=0,
256 .size=0,
257 .status=0,
258 .legatoMirror=false}));
260 TS_ASSERT_DIFFERS(part->notePool.sdesc[0].note, nullptr);
261 TS_ASSERT_EQUALS(part->notePool.sdesc[0].note->legato.silent, false);
262 TS_ASSERT_EQUALS(part->notePool.sdesc[0].type, 0)
263 TS_ASSERT_EQUALS(part->notePool.sdesc[0].kit, 0)
265 TS_ASSERT_DIFFERS(part->notePool.sdesc[1].note, nullptr);
266 if(part->notePool.sdesc[1].note)
267 TS_ASSERT_EQUALS(part->notePool.sdesc[1].note->legato.silent, true);
268 TS_ASSERT_EQUALS(part->notePool.sdesc[1].type, 0)
269 TS_ASSERT_EQUALS(part->notePool.sdesc[1].kit, 0)
272 void testNoKitNoLegatoYesMono() {
273 part->Ppolymode = false;
274 part->Plegatomode = false;
275 part->NoteOn(64, 127, 0);
276 part->NoteOn(65, 127, 0);
279 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
280 (NotePool::NoteDescriptor{
281 .age=0,
282 .note=64,
283 .sendto=0,
284 .size=1,
285 .status=KEY_RELEASED,
286 .legatoMirror=false}));
288 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
289 (NotePool::NoteDescriptor{
290 .age=0,
291 .note=65,
292 .sendto=0,
293 .size=1,
294 .status=KEY_PLAYING,
295 .legatoMirror=false}));
297 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
298 (NotePool::NoteDescriptor{
299 .age=0,
300 .note=0,
301 .sendto=0,
302 .size=0,
303 .status=0,
304 .legatoMirror=false}));
306 TS_ASSERT_DIFFERS(part->notePool.sdesc[0].note, nullptr);
307 TS_ASSERT_EQUALS(part->notePool.sdesc[0].note->legato.silent, false);
308 TS_ASSERT_EQUALS(part->notePool.sdesc[0].type, 0)
309 TS_ASSERT_EQUALS(part->notePool.sdesc[0].kit, 0)
311 TS_ASSERT_DIFFERS(part->notePool.sdesc[1].note, nullptr);
312 TS_ASSERT_EQUALS(part->notePool.sdesc[1].note->legato.silent, false);
313 TS_ASSERT_EQUALS(part->notePool.sdesc[1].type, 0)
314 TS_ASSERT_EQUALS(part->notePool.sdesc[1].kit, 0)
317 //Normal Kit
318 //Three patches that overlap give an overlapping response
319 void testYesKitNoLegatoNoMono() {
320 part->setkititemstatus(1, true);
321 part->setkititemstatus(2, true);
322 part->kit[1].Padenabled = true;
323 part->kit[2].Padenabled = true;
324 part->kit[2].Pmaxkey = 32;
325 part->Pkitmode = 1;
326 part->NoteOn(64, 127, 0);
327 part->NoteOn(65, 127, 0);
329 part->notePool.dump();
331 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
332 (NotePool::NoteDescriptor{
333 .age=0,
334 .note=64,
335 .sendto=0,
336 .size=2,
337 .status=KEY_PLAYING,
338 .legatoMirror=false}));
340 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
341 (NotePool::NoteDescriptor{
342 .age=0,
343 .note=65,
344 .sendto=0,
345 .size=2,
346 .status=KEY_PLAYING,
347 .legatoMirror=false}));
349 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
350 (NotePool::NoteDescriptor{
351 .age=0,
352 .note=0,
353 .sendto=0,
354 .size=0,
355 .status=0,
356 .legatoMirror=false}));
358 TS_ASSERT_DIFFERS(part->notePool.sdesc[0].note, nullptr);
359 TS_ASSERT_EQUALS(part->notePool.sdesc[0].note->legato.silent, false);
360 TS_ASSERT_EQUALS(part->notePool.sdesc[0].type, 0)
361 TS_ASSERT_EQUALS(part->notePool.sdesc[0].kit, 0)
363 TS_ASSERT_DIFFERS(part->notePool.sdesc[1].note, nullptr);
364 TS_ASSERT_EQUALS(part->notePool.sdesc[1].note->legato.silent, false);
365 TS_ASSERT_EQUALS(part->notePool.sdesc[1].type, 0)
366 TS_ASSERT_EQUALS(part->notePool.sdesc[1].kit, 1)
368 TS_ASSERT_DIFFERS(part->notePool.sdesc[2].note, nullptr);
369 TS_ASSERT_EQUALS(part->notePool.sdesc[2].note->legato.silent, false);
370 TS_ASSERT_EQUALS(part->notePool.sdesc[2].type, 0)
371 TS_ASSERT_EQUALS(part->notePool.sdesc[2].kit, 0)
373 TS_ASSERT_DIFFERS(part->notePool.sdesc[3].note, nullptr);
374 TS_ASSERT_EQUALS(part->notePool.sdesc[3].note->legato.silent, false);
375 TS_ASSERT_EQUALS(part->notePool.sdesc[3].type, 0)
376 TS_ASSERT_EQUALS(part->notePool.sdesc[3].kit, 1)
378 TS_ASSERT_EQUALS(part->notePool.sdesc[4].note, nullptr);
379 TS_ASSERT_EQUALS(part->notePool.sdesc[4].type, 0)
380 TS_ASSERT_EQUALS(part->notePool.sdesc[4].kit, 0)
383 void testYesKitYesLegatoNoMono() {
384 part->setkititemstatus(1, true);
385 part->setkititemstatus(2, true);
386 part->kit[1].Padenabled = true;
387 part->kit[2].Padenabled = true;
388 part->kit[2].Pmaxkey = 32;
389 part->Pkitmode = 1;
390 part->Ppolymode = false;
391 part->Plegatomode = true;
392 part->NoteOn(64, 127, 0);
393 part->NoteOn(65, 127, 0);
395 part->notePool.dump();
397 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
398 (NotePool::NoteDescriptor{
399 .age=0,
400 .note=65,
401 .sendto=0,
402 .size=2,
403 .status=KEY_PLAYING,
404 .legatoMirror=false}));
406 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
407 (NotePool::NoteDescriptor{
408 .age=0,
409 .note=65,
410 .sendto=0,
411 .size=2,
412 .status=KEY_PLAYING,
413 .legatoMirror=false}));
415 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
416 (NotePool::NoteDescriptor{
417 .age=0,
418 .note=0,
419 .sendto=0,
420 .size=0,
421 .status=0,
422 .legatoMirror=false}));
424 TS_ASSERT_DIFFERS(part->notePool.sdesc[0].note, nullptr);
425 TS_ASSERT_EQUALS(part->notePool.sdesc[0].note->legato.silent, false);
426 TS_ASSERT_EQUALS(part->notePool.sdesc[0].type, 0)
427 TS_ASSERT_EQUALS(part->notePool.sdesc[0].kit, 0)
429 TS_ASSERT_DIFFERS(part->notePool.sdesc[1].note, nullptr);
430 TS_ASSERT_EQUALS(part->notePool.sdesc[1].note->legato.silent, false);
431 TS_ASSERT_EQUALS(part->notePool.sdesc[1].type, 0)
432 TS_ASSERT_EQUALS(part->notePool.sdesc[1].kit, 1)
434 TS_ASSERT_DIFFERS(part->notePool.sdesc[2].note, nullptr);
435 TS_ASSERT_EQUALS(part->notePool.sdesc[2].note->legato.silent, true);
436 TS_ASSERT_EQUALS(part->notePool.sdesc[2].type, 0)
437 TS_ASSERT_EQUALS(part->notePool.sdesc[2].kit, 0)
439 TS_ASSERT_DIFFERS(part->notePool.sdesc[3].note, nullptr);
440 TS_ASSERT_EQUALS(part->notePool.sdesc[3].note->legato.silent, true);
441 TS_ASSERT_EQUALS(part->notePool.sdesc[3].type, 0)
442 TS_ASSERT_EQUALS(part->notePool.sdesc[3].kit, 1)
444 TS_ASSERT_EQUALS(part->notePool.sdesc[4].note, nullptr);
445 TS_ASSERT_EQUALS(part->notePool.sdesc[4].type, 0)
446 TS_ASSERT_EQUALS(part->notePool.sdesc[4].kit, 0)
449 void testYesKitNoLegatoYesMono() {
450 part->setkititemstatus(1, true);
451 part->setkititemstatus(2, true);
452 part->kit[1].Padenabled = true;
453 part->kit[2].Padenabled = true;
454 part->kit[2].Pmaxkey = 32;
455 part->Pkitmode = 1;
456 part->Ppolymode = false;
457 part->Plegatomode = false;
458 part->NoteOn(64, 127, 0);
459 part->NoteOn(65, 127, 0);
461 part->notePool.dump();
463 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
464 (NotePool::NoteDescriptor{
465 .age=0,
466 .note=64,
467 .sendto=0,
468 .size=2,
469 .status=KEY_RELEASED,
470 .legatoMirror=false}));
472 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
473 (NotePool::NoteDescriptor{
474 .age=0,
475 .note=65,
476 .sendto=0,
477 .size=2,
478 .status=KEY_PLAYING,
479 .legatoMirror=false}));
481 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
482 (NotePool::NoteDescriptor{
483 .age=0,
484 .note=0,
485 .sendto=0,
486 .size=0,
487 .status=0,
488 .legatoMirror=false}));
490 TS_ASSERT_DIFFERS(part->notePool.sdesc[0].note, nullptr);
491 TS_ASSERT_EQUALS(part->notePool.sdesc[0].note->legato.silent, false);
492 TS_ASSERT_EQUALS(part->notePool.sdesc[0].type, 0)
493 TS_ASSERT_EQUALS(part->notePool.sdesc[0].kit, 0)
495 TS_ASSERT_DIFFERS(part->notePool.sdesc[1].note, nullptr);
496 TS_ASSERT_EQUALS(part->notePool.sdesc[1].note->legato.silent, false);
497 TS_ASSERT_EQUALS(part->notePool.sdesc[1].type, 0)
498 TS_ASSERT_EQUALS(part->notePool.sdesc[1].kit, 1)
500 TS_ASSERT_DIFFERS(part->notePool.sdesc[2].note, nullptr);
501 TS_ASSERT_EQUALS(part->notePool.sdesc[2].note->legato.silent, false);
502 TS_ASSERT_EQUALS(part->notePool.sdesc[2].type, 0)
503 TS_ASSERT_EQUALS(part->notePool.sdesc[2].kit, 0)
505 TS_ASSERT_DIFFERS(part->notePool.sdesc[3].note, nullptr);
506 TS_ASSERT_EQUALS(part->notePool.sdesc[3].note->legato.silent, false);
507 TS_ASSERT_EQUALS(part->notePool.sdesc[3].type, 0)
508 TS_ASSERT_EQUALS(part->notePool.sdesc[3].kit, 1)
510 TS_ASSERT_EQUALS(part->notePool.sdesc[4].note, nullptr);
511 TS_ASSERT_EQUALS(part->notePool.sdesc[4].type, 0)
512 TS_ASSERT_EQUALS(part->notePool.sdesc[4].kit, 0)
515 //Single Kit
516 void testSingleKitNoLegatoNoMono() {
517 part->setkititemstatus(1, true);
518 part->setkititemstatus(2, true);
519 part->kit[1].Padenabled = true;
520 part->kit[2].Padenabled = true;
521 part->kit[2].Pmaxkey = 32;
522 part->Pkitmode = 2;
523 part->NoteOn(64, 127, 0);
524 part->NoteOn(65, 127, 0);
526 part->notePool.dump();
528 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
529 (NotePool::NoteDescriptor{
530 .age=0,
531 .note=64,
532 .sendto=0,
533 .size=1,
534 .status=KEY_PLAYING,
535 .legatoMirror=false}));
537 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
538 (NotePool::NoteDescriptor{
539 .age=0,
540 .note=65,
541 .sendto=0,
542 .size=1,
543 .status=KEY_PLAYING,
544 .legatoMirror=false}));
546 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
547 (NotePool::NoteDescriptor{
548 .age=0,
549 .note=0,
550 .sendto=0,
551 .size=0,
552 .status=0,
553 .legatoMirror=false}));
555 TS_ASSERT_DIFFERS(part->notePool.sdesc[0].note, nullptr);
556 TS_ASSERT_EQUALS(part->notePool.sdesc[0].note->legato.silent, false);
557 TS_ASSERT_EQUALS(part->notePool.sdesc[0].type, 0)
558 TS_ASSERT_EQUALS(part->notePool.sdesc[0].kit, 0)
560 TS_ASSERT_DIFFERS(part->notePool.sdesc[1].note, nullptr);
561 TS_ASSERT_EQUALS(part->notePool.sdesc[1].note->legato.silent, false);
562 TS_ASSERT_EQUALS(part->notePool.sdesc[1].type, 0)
563 TS_ASSERT_EQUALS(part->notePool.sdesc[1].kit, 0)
565 TS_ASSERT_EQUALS(part->notePool.sdesc[2].note, nullptr);
566 TS_ASSERT_EQUALS(part->notePool.sdesc[2].type, 0)
567 TS_ASSERT_EQUALS(part->notePool.sdesc[2].kit, 0)
570 void testSingleKitYesLegatoNoMono() {
571 part->setkititemstatus(1, true);
572 part->setkititemstatus(2, true);
573 part->kit[1].Padenabled = true;
574 part->kit[2].Padenabled = true;
575 part->kit[2].Pmaxkey = 32;
576 part->Pkitmode = 2;
577 part->Ppolymode = false;
578 part->Plegatomode = true;
579 part->NoteOn(64, 127, 0);
580 part->NoteOn(65, 127, 0);
582 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
583 (NotePool::NoteDescriptor{
584 .age=0,
585 .note=65,
586 .sendto=0,
587 .size=1,
588 .status=KEY_PLAYING,
589 .legatoMirror=false}));
591 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
592 (NotePool::NoteDescriptor{
593 .age=0,
594 .note=65,
595 .sendto=0,
596 .size=1,
597 .status=KEY_PLAYING,
598 .legatoMirror=false}));
600 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
601 (NotePool::NoteDescriptor{
602 .age=0,
603 .note=0,
604 .sendto=0,
605 .size=0,
606 .status=0,
607 .legatoMirror=false}));
609 TS_ASSERT_DIFFERS(part->notePool.sdesc[0].note, nullptr);
610 TS_ASSERT_EQUALS(part->notePool.sdesc[0].note->legato.silent, false);
611 TS_ASSERT_EQUALS(part->notePool.sdesc[0].type, 0)
612 TS_ASSERT_EQUALS(part->notePool.sdesc[0].kit, 0)
614 TS_ASSERT_DIFFERS(part->notePool.sdesc[1].note, nullptr);
615 if(part->notePool.sdesc[1].note)
616 TS_ASSERT_EQUALS(part->notePool.sdesc[1].note->legato.silent, true);
617 TS_ASSERT_EQUALS(part->notePool.sdesc[1].type, 0)
618 TS_ASSERT_EQUALS(part->notePool.sdesc[1].kit, 0)
621 void testSingleKitNoLegatoYesMono() {
622 part->setkititemstatus(1, true);
623 part->setkititemstatus(2, true);
624 part->kit[1].Padenabled = true;
625 part->kit[2].Padenabled = true;
626 part->kit[2].Pmaxkey = 32;
627 part->Pkitmode = 2;
628 part->Ppolymode = false;
629 part->Plegatomode = false;
630 part->NoteOn(64, 127, 0);
631 part->NoteOn(65, 127, 0);
635 TS_ASSERT_EQUALS(part->notePool.ndesc[0],
636 (NotePool::NoteDescriptor{
637 .age=0,
638 .note=64,
639 .sendto=0,
640 .size=1,
641 .status=KEY_RELEASED,
642 .legatoMirror=false}));
644 TS_ASSERT_EQUALS(part->notePool.ndesc[1],
645 (NotePool::NoteDescriptor{
646 .age=0,
647 .note=65,
648 .sendto=0,
649 .size=1,
650 .status=KEY_PLAYING,
651 .legatoMirror=false}));
653 TS_ASSERT_EQUALS(part->notePool.ndesc[2],
654 (NotePool::NoteDescriptor{
655 .age=0,
656 .note=0,
657 .sendto=0,
658 .size=0,
659 .status=0,
660 .legatoMirror=false}));
662 TS_ASSERT_DIFFERS(part->notePool.sdesc[0].note, nullptr);
663 TS_ASSERT_EQUALS(part->notePool.sdesc[0].note->legato.silent, false);
664 TS_ASSERT_EQUALS(part->notePool.sdesc[0].type, 0)
665 TS_ASSERT_EQUALS(part->notePool.sdesc[0].kit, 0)
667 TS_ASSERT_DIFFERS(part->notePool.sdesc[1].note, nullptr);
668 TS_ASSERT_EQUALS(part->notePool.sdesc[1].note->legato.silent, false);
669 TS_ASSERT_EQUALS(part->notePool.sdesc[1].type, 0)
670 TS_ASSERT_EQUALS(part->notePool.sdesc[1].kit, 0)
673 void testKeyLimit(void)
675 auto &pool = part->notePool;
676 //Verify that without a key limit, several notes can be run
677 part->NoteOn(64, 127, 0);
678 part->NoteOn(65, 127, 0);
679 part->NoteOn(66, 127, 0);
680 part->NoteOn(67, 127, 0);
681 part->NoteOn(68, 127, 0);
683 //Verify that notes are spawned as expected
684 TS_ASSERT_EQUALS(pool.usedNoteDesc(), 5);
685 TS_ASSERT_EQUALS(pool.usedSynthDesc(), 5);
687 //Reset the part
688 part->monomemClear();
689 pool.killAllNotes();
691 //Verify that notes are despawned
692 TS_ASSERT_EQUALS(pool.usedNoteDesc(), 0);
693 TS_ASSERT_EQUALS(pool.usedSynthDesc(), 0);
695 //Enable keylimit
696 part->setkeylimit(3);
698 //Replay notes
699 part->NoteOn(64, 127, 0);
700 part->NoteOn(65, 127, 0);
701 part->NoteOn(66, 127, 0);
702 part->NoteOn(67, 127, 0);
703 part->NoteOn(68, 127, 0);
705 //Verify that notes are spawned as expected with limit
706 TS_ASSERT_EQUALS(pool.getRunningNotes(), 3);//2 entombed
707 TS_ASSERT_EQUALS(pool.usedNoteDesc(), 5);
708 TS_ASSERT_EQUALS(pool.usedSynthDesc(), 5);
710 //Reset the part
711 part->monomemClear();
712 pool.killAllNotes();
714 //Verify that notes are despawned
715 TS_ASSERT_EQUALS(pool.usedNoteDesc(), 0);
716 TS_ASSERT_EQUALS(pool.usedSynthDesc(), 0);
718 //Now to test note stealing
720 //Replay notes
721 part->NoteOn(64, 127, 0);
722 part->NoteOn(65, 127, 0);
723 part->NoteOn(66, 127, 0);
725 //Verify that note pool is full
726 TS_ASSERT_EQUALS(pool.usedNoteDesc(), 3);
727 TS_ASSERT_EQUALS(pool.usedSynthDesc(), 3);
729 //Age the notes
730 pool.ndesc[1].age = 50;
731 pool.ndesc[2].age = 500;
733 printf("-------------------------------------\n");
735 //Inject two more notes which should steal the note
736 //descriptors for #66 and #65
737 part->NoteOn(67, 127, 0);
738 pool.cleanup();
739 TS_ASSERT_EQUALS(pool.ndesc[0].note, 64);
740 TS_ASSERT_EQUALS(pool.ndesc[1].note, 65);
741 TS_ASSERT_EQUALS(pool.ndesc[2].note, 66);
742 TS_ASSERT_EQUALS(pool.ndesc[2].status, KEY_RELEASED);
743 TS_ASSERT_EQUALS(pool.ndesc[3].note, 67);
745 part->NoteOn(68, 127, 0);
747 //Verify that note pool is still full and entombed
748 TS_ASSERT_EQUALS(pool.usedNoteDesc(), 5);
749 TS_ASSERT_EQUALS(pool.usedSynthDesc(), 5);
751 //Check that the result is {64, 68, 67}
752 TS_ASSERT_EQUALS(pool.ndesc[0].note, 64);
753 TS_ASSERT_EQUALS(pool.ndesc[1].note, 65);
754 TS_ASSERT_EQUALS(pool.ndesc[1].status, KEY_RELEASED);
755 TS_ASSERT_EQUALS(pool.ndesc[2].note, 66);
756 TS_ASSERT_EQUALS(pool.ndesc[2].status, KEY_RELEASED);
757 TS_ASSERT_EQUALS(pool.ndesc[3].note, 67);
758 TS_ASSERT_EQUALS(pool.ndesc[4].note, 68);
761 void tearDown() {
762 delete part;
763 delete[] outL;
764 delete[] outR;
765 delete time;
766 delete synth;