commit d8121bf92692e4eaa51104eb03b6bb38baa7fa20
parent 8f12820e12149d95795531ad4163ec4ca938d5d0
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Fri, 19 Jun 2015 16:38:49 -0400
Tests: Codify Kit Allocation Behavior
Diffstat:
4 files changed, 418 insertions(+), 3 deletions(-)
diff --git a/src/Misc/Part.cpp b/src/Misc/Part.cpp
@@ -73,7 +73,8 @@ static const Ports partPorts = {
rToggle(Pnoteon, "If the channel accepts note on events"),
//TODO FIXME Change to 0=OFF 1=MULTI 2=SINGLE
rParamI(Pkitmode, "Kit mode enable"),
- rToggle(Pdrummode, "Drum mode enable"),
+ rToggle(Pdrummode, "Drum mode enable\n"
+ "When drum mode is enabled all keys are mapped to 12tET and legato is disabled"),
rToggle(Ppolymode, "Polyphoney mode"),
rToggle(Plegatomode, "Legato enable"),
rParamZyn(info.Ptype, "Class of Instrument"),
@@ -362,6 +363,16 @@ Part::~Part()
}
}
+void assert_kit_sanity(const Part::Kit *kits)
+{
+ for(int i=0; i<NUM_KIT_ITEMS; ++i) {
+ //an enabled kit must have a corresponding parameter object
+ assert(!kits[i].Padenabled || kits[i].adpars);
+ assert(!kits[i].Ppadenabled || kits[i].padpars);
+ assert(!kits[i].Psubenabled || kits[i].subpars);
+ }
+}
+
/*
* Note On Messages
*/
@@ -380,6 +391,8 @@ void Part::NoteOn(unsigned char note,
if(!Pnoteon || !inRange(note, Pminkey, Pmaxkey))
return;
+ assert_kit_sanity(kit);
+
// MonoMem stuff:
if(!Ppolymode) { // If Poly is off
monomemPush(note); // Add note to the list.
@@ -401,7 +414,7 @@ void Part::NoteOn(unsigned char note,
}
if(Plegatomode && !Pdrummode) {
- if(Ppolymode != 0) {
+ if(Ppolymode) {
fprintf(
stderr,
"ZynAddSubFX WARNING: Poly and Legato modes are both On, that should not happen ! ... Disabling Legato mode ! - (Part.cpp::NoteOn(..))\n");
@@ -410,7 +423,7 @@ void Part::NoteOn(unsigned char note,
else {
// Legato mode is on and applicable.
legatomodevalid = true;
- if((not ismonofirstnote) && (lastlegatomodevalid)) {
+ if(!ismonofirstnote && lastlegatomodevalid) {
// At least one other key is held or sustained, and the
// previous note was played while in valid legato mode.
doinglegato = true; // So we'll do a legato note.
diff --git a/src/Misc/Part.h b/src/Misc/Part.h
@@ -115,6 +115,8 @@ class Part
unsigned char Pveloffs; //velocity offset
bool Pnoteon; //if the part receives NoteOn messages
int Pkitmode; //if the kitmode is enabled
+
+ //XXX consider deprecating drum mode
bool Pdrummode; //if all keys are mapped and the system is 12tET (used for drums)
bool Ppolymode; //Part mode - 0=monophonic , 1=polyphonic
diff --git a/src/Tests/CMakeLists.txt b/src/Tests/CMakeLists.txt
@@ -18,6 +18,8 @@ CXXTEST_ADD_TEST(UnisonTest UnisonTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/UnisonTes
#CXXTEST_ADD_TEST(RtAllocTest RtAllocTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/RtAllocTest.h)
CXXTEST_ADD_TEST(AllocatorTest AllocatorTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/AllocatorTest.h)
+CXXTEST_ADD_TEST(KitTest KitTest.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/KitTest.h)
#Extra libraries added to make test and full compilation use the same library
#links for quirky compilers
@@ -42,6 +44,7 @@ target_link_libraries(MiddlewareTest zynaddsubfx_core zynaddsubfx_nio
target_link_libraries(UnisonTest ${test_lib})
#target_link_libraries(RtAllocTest ${test_lib})
target_link_libraries(AllocatorTest ${test_lib})
+target_link_libraries(KitTest ${test_lib})
#Testbed app
add_executable(ins-test InstrumentStats.cpp)
diff --git a/src/Tests/KitTest.h b/src/Tests/KitTest.h
@@ -0,0 +1,397 @@
+#include <cxxtest/TestSuite.h>
+#include <cmath>
+#include <cstring>
+#include <cstdlib>
+#include <iostream>
+#include "../Misc/Allocator.h"
+#include "../DSP/FFTwrapper.h"
+#include "../Misc/Microtonal.h"
+#define private public
+#define protected public
+#include "../Synth/SynthNote.h"
+#include "../Misc/Part.h"
+#include "../globals.h"
+SYNTH_T *synth;
+extern float *denormalkillbuf;
+
+using namespace std;
+
+class KitTest:public CxxTest::TestSuite
+{
+ private:
+ Allocator alloc;
+ FFTwrapper fft;
+ Microtonal microtonal;
+ Part *part;
+ float *outL, *outR;
+ public:
+ KitTest()
+ :fft(512)
+ {}
+ void setUp() {
+ synth = new SYNTH_T;
+ denormalkillbuf = new float[synth->buffersize];
+ outL = new float[synth->buffersize];
+ outR = new float[synth->buffersize];
+ memset(denormalkillbuf, 0, synth->bufferbytes);
+ memset(outL, 0, synth->bufferbytes);
+ memset(outR, 0, synth->bufferbytes);
+
+
+ part = new Part(alloc, *synth, µtonal, &fft);
+ }
+
+ //Enumerate cases of:
+ //Legato = {disabled,enabled}
+ //Mono = {diabled, enabled}
+ //Kit = {off, normal, single}
+ //ignore legato=enabled, mono=enabled
+
+ //No Kit
+ void testNoKitNoLegatoNoMono() {
+ part->NoteOn(64, 127, 0);
+ part->NoteOn(65, 127, 0);
+
+ TS_ASSERT_EQUALS(part->partnote[0].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[0].note, 64);
+ TS_ASSERT_EQUALS(part->partnote[0].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+
+ TS_ASSERT_EQUALS(part->partnote[1].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[1].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[1].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+
+ TS_ASSERT_EQUALS(part->partnote[2].status, Part::KEY_OFF);
+ TS_ASSERT_EQUALS(part->partnote[2].note, -1);
+ }
+
+ void testNoKitYesLegatoNoMono() {
+ part->Ppolymode = false;
+ part->Plegatomode = true;
+ part->NoteOn(64, 127, 0);
+ part->NoteOn(65, 127, 0);
+ TS_ASSERT_EQUALS(part->partnote[0].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[0].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[0].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].adnote->legato.silent, false);
+
+
+ TS_ASSERT_EQUALS(part->partnote[1].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[1].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[1].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].adnote->legato.silent, true);
+
+
+ TS_ASSERT_EQUALS(part->partnote[2].status, Part::KEY_OFF);
+ TS_ASSERT_EQUALS(part->partnote[2].note, -1);
+ }
+
+ void testNoKitNoLegatoYesMono() {
+ part->Ppolymode = false;
+ part->Plegatomode = false;
+ part->NoteOn(64, 127, 0);
+ part->NoteOn(65, 127, 0);
+ TS_ASSERT_EQUALS(part->partnote[0].status, Part::KEY_RELEASED);
+ TS_ASSERT_EQUALS(part->partnote[0].note, 64);
+ TS_ASSERT_EQUALS(part->partnote[0].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].adnote->legato.silent, false);
+
+
+ TS_ASSERT_EQUALS(part->partnote[1].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[1].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[1].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].adnote->legato.silent, false);
+
+
+ TS_ASSERT_EQUALS(part->partnote[2].status, Part::KEY_OFF);
+ TS_ASSERT_EQUALS(part->partnote[2].note, -1);
+ }
+
+ //Normal Kit
+ //Three patches that overlap give an overlapping response
+ void testYesKitNoLegatoNoMono() {
+ part->setkititemstatus(1, true);
+ part->setkititemstatus(2, true);
+ part->kit[1].Padenabled = true;
+ part->kit[2].Padenabled = true;
+ part->kit[2].Pmaxkey = 32;
+ part->Pkitmode = 1;
+ part->NoteOn(64, 127, 0);
+ part->NoteOn(65, 127, 0);
+
+ TS_ASSERT_EQUALS(part->partnote[0].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[0].note, 64);
+ TS_ASSERT_EQUALS(part->partnote[0].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+
+ TS_ASSERT_EQUALS(part->partnote[1].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[1].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[1].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+
+ TS_ASSERT_EQUALS(part->partnote[2].status, Part::KEY_OFF);
+ TS_ASSERT_EQUALS(part->partnote[2].note, -1);
+ }
+
+ void testYesKitYesLegatoNoMono() {
+ part->setkititemstatus(1, true);
+ part->setkititemstatus(2, true);
+ part->kit[1].Padenabled = true;
+ part->kit[2].Padenabled = true;
+ part->kit[2].Pmaxkey = 32;
+ part->Pkitmode = 1;
+ part->Ppolymode = false;
+ part->Plegatomode = true;
+ part->NoteOn(64, 127, 0);
+ part->NoteOn(65, 127, 0);
+ TS_ASSERT_EQUALS(part->partnote[0].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[0].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[0].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].adnote->legato.silent, false);
+
+
+ TS_ASSERT_EQUALS(part->partnote[1].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[1].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[1].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].adnote->legato.silent, true);
+
+
+ TS_ASSERT_EQUALS(part->partnote[2].status, Part::KEY_OFF);
+ TS_ASSERT_EQUALS(part->partnote[2].note, -1);
+ }
+
+ void testYesKitNoLegatoYesMono() {
+ part->setkititemstatus(1, true);
+ part->setkititemstatus(2, true);
+ part->kit[1].Padenabled = true;
+ part->kit[2].Padenabled = true;
+ part->kit[2].Pmaxkey = 32;
+ part->Pkitmode = 1;
+ part->Ppolymode = false;
+ part->Plegatomode = false;
+ part->NoteOn(64, 127, 0);
+ part->NoteOn(65, 127, 0);
+ TS_ASSERT_EQUALS(part->partnote[0].status, Part::KEY_RELEASED);
+ TS_ASSERT_EQUALS(part->partnote[0].note, 64);
+ TS_ASSERT_EQUALS(part->partnote[0].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].adnote->legato.silent, false);
+
+
+ TS_ASSERT_EQUALS(part->partnote[1].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[1].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[1].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].adnote->legato.silent, false);
+
+
+ TS_ASSERT_EQUALS(part->partnote[2].status, Part::KEY_OFF);
+ TS_ASSERT_EQUALS(part->partnote[2].note, -1);
+ }
+
+ //Single Kit
+ void testSingleKitNoLegatoNoMono() {
+ part->setkititemstatus(1, true);
+ part->setkititemstatus(2, true);
+ part->kit[1].Padenabled = true;
+ part->kit[2].Padenabled = true;
+ part->kit[2].Pmaxkey = 32;
+ part->Pkitmode = 2;
+ part->NoteOn(64, 127, 0);
+ part->NoteOn(65, 127, 0);
+
+ TS_ASSERT_EQUALS(part->partnote[0].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[0].note, 64);
+ TS_ASSERT_EQUALS(part->partnote[0].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+
+ TS_ASSERT_EQUALS(part->partnote[1].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[1].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[1].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+
+ TS_ASSERT_EQUALS(part->partnote[2].status, Part::KEY_OFF);
+ TS_ASSERT_EQUALS(part->partnote[2].note, -1);
+ }
+
+ void testSingleKitYesLegatoNoMono() {
+ part->setkititemstatus(1, true);
+ part->setkititemstatus(2, true);
+ part->kit[1].Padenabled = true;
+ part->kit[2].Padenabled = true;
+ part->kit[2].Pmaxkey = 32;
+ part->Pkitmode = 2;
+ part->Ppolymode = false;
+ part->Plegatomode = true;
+ part->NoteOn(64, 127, 0);
+ part->NoteOn(65, 127, 0);
+ TS_ASSERT_EQUALS(part->partnote[0].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[0].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[0].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].adnote->legato.silent, false);
+
+
+ TS_ASSERT_EQUALS(part->partnote[1].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[1].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[1].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].adnote->legato.silent, true);
+
+
+ TS_ASSERT_EQUALS(part->partnote[2].status, Part::KEY_OFF);
+ TS_ASSERT_EQUALS(part->partnote[2].note, -1);
+ }
+
+ void testSingleKitNoLegatoYesMono() {
+ part->setkititemstatus(1, true);
+ part->setkititemstatus(2, true);
+ part->kit[1].Padenabled = true;
+ part->kit[2].Padenabled = true;
+ part->kit[2].Pmaxkey = 32;
+ part->Pkitmode = 2;
+ part->Ppolymode = false;
+ part->Plegatomode = false;
+ part->NoteOn(64, 127, 0);
+ part->NoteOn(65, 127, 0);
+ TS_ASSERT_EQUALS(part->partnote[0].status, Part::KEY_RELEASED);
+ TS_ASSERT_EQUALS(part->partnote[0].note, 64);
+ TS_ASSERT_EQUALS(part->partnote[0].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[0].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[0].kititem[0].adnote->legato.silent, false);
+
+
+ TS_ASSERT_EQUALS(part->partnote[1].status, Part::KEY_PLAYING);
+ TS_ASSERT_EQUALS(part->partnote[1].note, 65);
+ TS_ASSERT_EQUALS(part->partnote[1].time, 0);
+ TS_ASSERT_DIFFERS(part->partnote[1].kititem[0].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[1].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].adnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[2].subnote, nullptr);
+ TS_ASSERT_EQUALS(part->partnote[1].kititem[0].adnote->legato.silent, false);
+
+
+ TS_ASSERT_EQUALS(part->partnote[2].status, Part::KEY_OFF);
+ TS_ASSERT_EQUALS(part->partnote[2].note, -1);
+ }
+
+ void tearDown() {
+ delete part;
+ delete[] denormalkillbuf;
+ delete[] outL;
+ delete[] outR;
+ delete synth;
+ }
+};