Skip to content

Commit

Permalink
Some more tests and lgo messages (#14)
Browse files Browse the repository at this point in the history
In debugging a short-circuit vm problem, which I thought was
the underlying vm problem, I added some more tests and logs which
are useful, so merge those.
  • Loading branch information
baconpaul authored Nov 6, 2024
1 parent 5bd3ab5 commit 6794214
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 40 deletions.
9 changes: 5 additions & 4 deletions include/sst/voicemanager/voicemanager_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

namespace sst::voicemanager
{

static constexpr bool vmLog{false};
#define VML(...) \
{ \
Expand Down Expand Up @@ -558,6 +557,7 @@ bool VoiceManager<Cfg, Responder, MonoResponder>::processNoteOnEvent(int16_t por

for (int i = 0; i < voicesToBeLaunched; ++i)
{
details.voiceInitInstructionsBuffer[i] = {};
const auto &vbb = details.voiceBeginWorkingBuffer[i];
auto polyGroup = vbb.polyphonyGroup;
assert(details.playMode.find(polyGroup) != details.playMode.end());
Expand Down Expand Up @@ -691,9 +691,10 @@ bool VoiceManager<Cfg, Responder, MonoResponder>::processNoteOnEvent(int16_t por
details.keyStateByPort[vi.port][vi.channel][vi.key][vi.polyGroup] = {vi.transactionId,
velocity};

VML("- New Voice assigned with " << details.mostRecentVoiceCounter
<< " at pckn=" << port << "/" << channel << "/" << key
<< "/" << noteid << " pg=" << vi.polyGroup);
VML("- New Voice assigned from "
<< voicesLeft - 1 << " with " << details.mostRecentVoiceCounter
<< " at pckn=" << port << "/" << channel << "/" << key << "/" << noteid
<< " pg=" << vi.polyGroup << " avc=" << vi.activeVoiceCookie);

assert(details.usedVoices.find(vi.polyGroup) != details.usedVoices.end());
++details.usedVoices.at(vi.polyGroup);
Expand Down
179 changes: 143 additions & 36 deletions tests/mono_playback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,50 +367,126 @@ TEST_CASE("Mono Mode - Sustain Pedal")

TEST_CASE("Mono Mode - Two Layers, One Poly")
{
auto tp = TestPlayer<32, true>();
typedef TestPlayer<32, true>::voiceManager_t vm_t;
auto &vm = tp.voiceManager;
SECTION("Case one")
{
auto tp = TestPlayer<32, true>();
typedef TestPlayer<32, true>::voiceManager_t vm_t;
auto &vm = tp.voiceManager;

INFO("Put EVEN and ODD keys in different groups, even poly odd mono");
tp.polyGroupForKey = [](auto k) { return (k % 2 == 0 ? 19884 : 8675309); };
vm.setPlaymode(19884, vm_t::PlayMode::POLY_VOICES);
vm.setPlaymode(8675309, vm_t::PlayMode::MONO_NOTES,
(uint64_t)vm_t::MonoPlayModeFeatures::NATURAL_MONO);
INFO("Put EVEN and ODD keys in different groups, even poly odd mono");
tp.polyGroupForKey = [](auto k) { return (k % 2 == 0 ? 19884 : 8675309); };
vm.setPlaymode(19884, vm_t::PlayMode::POLY_VOICES);
vm.setPlaymode(8675309, vm_t::PlayMode::MONO_NOTES,
(uint64_t)vm_t::MonoPlayModeFeatures::NATURAL_MONO);

INFO("Play three poly voices");
for (int k = 60; k < 65; k += 2)
{
vm.processNoteOnEvent(0, 0, k, -1, 0.8, 0.0);
INFO("Play three poly voices");
for (int k = 60; k < 65; k += 2)
{
vm.processNoteOnEvent(0, 0, k, -1, 0.8, 0.0);
}
REQUIRE_VOICE_COUNTS(3, 3);

INFO("Play note 61 for an extra voice");
vm.processNoteOnEvent(0, 0, 61, -1, 0.8, 0.0);
tp.processFor(1);
REQUIRE_VOICE_COUNTS(4, 4);
REQUIRE_VOICE_MATCH(1, v.key() == 61);

INFO("Mono move that to 63");
vm.processNoteOnEvent(0, 0, 63, -1, 0.8, 0.0);
tp.processFor(1);
REQUIRE_VOICE_COUNTS(4, 4);
REQUIRE_VOICE_MATCH(1, v.key() == 63);

INFO("Release a poly voice");
vm.processNoteOffEvent(0, 0, 62, -1, 0.8);
tp.processFor(1);
REQUIRE_VOICE_COUNTS(4, 3); // remember that poly voice is in release mode

INFO("Release the 63 to go back to 61");
vm.processNoteOffEvent(0, 0, 63, -1, 0.8);
tp.processFor(1);
REQUIRE_VOICE_COUNTS(4, 3); // remember that poly voice is in release mode
tp.processFor(10);
REQUIRE_VOICE_COUNTS(3, 3); // and that poly voice is no longer released

INFO("Release the 61 and you get a release mono voice");
vm.processNoteOffEvent(0, 0, 61, -1, 0.8);
tp.processFor(1);
REQUIRE_VOICE_COUNTS(3, 2);
REQUIRE_VOICE_MATCH(1, v.key() == 61);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(2, 2);
REQUIRE_VOICE_MATCH(0, v.key() == 61);
}
REQUIRE_VOICE_COUNTS(3, 3);

INFO("Play note 61 for an extra voice");
vm.processNoteOnEvent(0, 0, 61, -1, 0.8, 0.0);
REQUIRE_VOICE_COUNTS(4, 4);
REQUIRE_VOICE_MATCH(1, v.key() == 61);
SECTION("Retrigger during release - base case")
{
auto tp = TwoGroupsEveryKey<32, true>();
typedef TwoGroupsEveryKey<32, true>::voiceManager_t vm_t;
auto &vm = tp.voiceManager;

INFO("Mono move that to 63");
vm.processNoteOnEvent(0, 0, 63, -1, 0.8, 0.0);
REQUIRE_VOICE_COUNTS(4, 4);
REQUIRE_VOICE_MATCH(1, v.key() == 63);
vm.setPlaymode(2112, vm_t::PlayMode::POLY_VOICES);
vm.setPlaymode(90125, vm_t::PlayMode::MONO_NOTES,
(uint64_t)vm_t::MonoPlayModeFeatures::NATURAL_MONO);

INFO("Release a poly voice");
vm.processNoteOffEvent(0, 0, 62, -1, 0.8);
REQUIRE_VOICE_COUNTS(4, 3); // remember that poly voice is in release mode
INFO("Play three poly voices overlapped with one mono");
for (int k = 60; k < 65; k += 2)
{
vm.processNoteOnEvent(0, 0, k, -1, 0.8, 0.0);
}
REQUIRE_VOICE_COUNTS(4, 4);

INFO("Release the 63 to go back to 61");
vm.processNoteOffEvent(0, 0, 63, -1, 0.8);
REQUIRE_VOICE_COUNTS(4, 3); // remember that poly voice is in release mode
tp.processFor(10);
REQUIRE_VOICE_COUNTS(3, 3); // and that poly voice is no longer released
tp.processFor(2);
INFO("Now release everything");
for (int k = 60; k < 65; k += 2)
{
vm.processNoteOffEvent(0, 0, k, -1, 0.8);
}
REQUIRE_VOICE_COUNTS(4, 0);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(0, 0);
}

INFO("Release the 61 and you get a release mono voice");
vm.processNoteOffEvent(0, 0, 61, -1, 0.8);
REQUIRE_VOICE_COUNTS(3, 2);
REQUIRE_VOICE_MATCH(1, v.key() == 61);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(2, 2);
REQUIRE_VOICE_MATCH(0, v.key() == 61);
SECTION("Retrigger in Release - Test Case")
{
auto tp = TwoGroupsEveryKey<32, true>();
typedef TwoGroupsEveryKey<32, true>::voiceManager_t vm_t;
auto &vm = tp.voiceManager;
vm.setPlaymode(2112, vm_t::PlayMode::POLY_VOICES);
vm.setPlaymode(90125, vm_t::PlayMode::MONO_NOTES,
(uint64_t)vm_t::MonoPlayModeFeatures::NATURAL_MONO);

INFO("Now do it again but retrigger during release");
for (int k = 60; k < 65; k += 2)
{
vm.processNoteOnEvent(0, 0, k, -1, 0.8, 0.0);
}
REQUIRE_VOICE_COUNTS(4, 4);

tp.processFor(2);
INFO("Now release everything");
for (int k = 60; k < 65; k += 2)
{
vm.processNoteOffEvent(0, 0, k, -1, 0.8);
}
REQUIRE_VOICE_COUNTS(4, 0);
tp.processFor(1);
REQUIRE_VOICE_COUNTS(4, 0);

INFO("Now retrigger two notes - the ringing mono moves and we add a poly");
vm.processNoteOnEvent(0, 0, 55, -1, 0.8, 0.0);
REQUIRE_VOICE_COUNTS(5, 2);
tp.processFor(1);

vm.processNoteOnEvent(0, 0, 54, -1, 0.8, 0.0);
INFO("This should add 2 poly gated voices and one mono since we are in piano mode");
REQUIRE_VOICE_COUNTS(6, 3);

INFO("Let the ungated ring out");
tp.processFor(10);
REQUIRE_VOICE_COUNTS(3, 3);
}
}

TEST_CASE("Mono terminates a non-gated release voice")
Expand Down Expand Up @@ -497,3 +573,34 @@ TEST_CASE("Mono Mode - Poly and Mono on same key with multi-voice start")
REQUIRE_VOICE_MATCH(2, v.key() == 60);
REQUIRE_VOICE_MATCH(1, v.key() == 62);
}

TEST_CASE("Mono Mode - Layerd Retrigger Miss")
{
auto tp = TwoGroupsEveryKey<32, true>();
typedef TwoGroupsEveryKey<32, true>::voiceManager_t vm_t;
auto &vm = tp.voiceManager;

vm.setPlaymode(2112, vm_t::PlayMode::MONO_NOTES,
(uint64_t)vm_t::MonoPlayModeFeatures::NATURAL_MONO);

vm.processNoteOnEvent(0, 0, 58, -1, 0.8, 0);
tp.processFor(1);
REQUIRE_KEY_COUNT(2, 58);
vm.processNoteOnEvent(0, 0, 60, -1, 0.8, 0);
tp.processFor(1);
REQUIRE_KEY_COUNT(1, 58);
REQUIRE_KEY_COUNT(2, 60);
vm.processNoteOffEvent(0, 0, 60, -1, 0.8);
tp.processFor(1);
REQUIRE_KEY_COUNT(2, 58);
REQUIRE_KEY_COUNT(1, 60);
// Ring out the poly release
tp.processFor(10);
REQUIRE_KEY_COUNT(2, 58);
REQUIRE_KEY_COUNT(0, 60);

vm.processNoteOnEvent(0, 0, 60, -1, 0.8, 0);
tp.processFor(1);
REQUIRE_KEY_COUNT(1, 58);
REQUIRE_KEY_COUNT(2, 60);
}
2 changes: 2 additions & 0 deletions tests/test_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ struct TwoGroupsEveryKey : TestPlayer<voiceCount, doLog>
REQUIRE(tp.activeVoicesMatching([](auto &v) { return __VA_ARGS__; }) == ct)

#define REQUIRE_VOICE_MATCH_FN(ct, ...) REQUIRE(tp.activeVoicesMatching(__VA_ARGS__) == ct)
#define REQUIRE_KEY_COUNT(ct, keyNumber) \
REQUIRE(tp.activeVoicesMatching([](const auto &v) { return v.key() == keyNumber; }) == ct)

// #define REQUIRE_INCOMPLETE_TEST REQUIRE(false)
#define REQUIRE_INCOMPLETE_TEST INFO("This test is currently incomplete");
Expand Down

0 comments on commit 6794214

Please sign in to comment.