zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

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:
Msrc/Misc/Part.cpp | 19++++++++++++++++---
Msrc/Misc/Part.h | 2++
Msrc/Tests/CMakeLists.txt | 3+++
Asrc/Tests/KitTest.h | 397+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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, &microtonal, &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; + } +};