Skip to content

Commit

Permalink
Fix an error for gated-due-to-sustain in pinao-mode (#20)
Browse files Browse the repository at this point in the history
A particular retrigger parttern would ignore the re-gate
and think the gate was still due to sustain. On a regate,
reset the sustain gate to false.

Addresses baconpaul/six-sines#88
  • Loading branch information
baconpaul authored Jan 6, 2025
1 parent 1fc76c3 commit c95cf4e
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 4 deletions.
4 changes: 4 additions & 0 deletions include/sst/voicemanager/voicemanager_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,12 @@ bool VoiceManager<Cfg, Responder, MonoResponder>::processNoteOnEvent(int16_t por
{
responder.retriggerVoiceWithNewNoteID(vi.activeVoiceCookie, noteid, velocity);
vi.gated = true;
// We are not gated because of sustain; we are gated because we are gated.
// If we release we will turn gatedDueToSustain back on
vi.gatedDueToSustain = false;
vi.voiceCounter = ++details.mostRecentVoiceCounter;
vi.transactionId = details.mostRecentTransactionID;

didAnyRetrigger = true;
}
}
Expand Down
140 changes: 136 additions & 4 deletions tests/piano_mode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,143 @@ TEST_CASE("Poly Multi Key Non Piano Mode")
REQUIRE_VOICE_COUNTS(3, 3);
}
}
/*

TEST_CASE("Piano Mode Sustain Pedal")
{
SECTION("Multile notes, no retrig, sustain") { REQUIRE_INCOMPLETE_TEST; }
SECTION("Single notes, no retrig, sustain")
{
TestPlayer<32> tp;
auto &vm = tp.voiceManager;
REQUIRE_NO_VOICES;

vm.dialect = TestPlayer<32>::voiceManager_t::MIDI1Dialect::MIDI1;
vm.repeatedKeyMode = TestPlayer<32>::voiceManager_t::RepeatedKeyMode::PIANO;

vm.processNoteOnEvent(0, 0, 60, -1, 0.8, 0.0);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(1, 1);
vm.updateSustainPedal(0, 0, 120);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(1, 1);
vm.processNoteOffEvent(0, 0, 60, -1, 0.4);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(40);
REQUIRE_VOICE_COUNTS(1, 1);

vm.updateSustainPedal(0, 0, 0);
REQUIRE_VOICE_COUNTS(1, 0);
tp.processFor(20);

REQUIRE_NO_VOICES;
}

SECTION("Multiple notes, no retrig, sustain")
{
TestPlayer<32> tp;
auto &vm = tp.voiceManager;
REQUIRE_NO_VOICES;

vm.dialect = TestPlayer<32>::voiceManager_t::MIDI1Dialect::MIDI1;
vm.repeatedKeyMode = TestPlayer<32>::voiceManager_t::RepeatedKeyMode::PIANO;

vm.processNoteOnEvent(0, 0, 60, -1, 0.8, 0.0);
vm.processNoteOnEvent(0, 0, 64, -1, 0.8, 0.0);
REQUIRE_VOICE_COUNTS(2, 2);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(2, 2);
vm.updateSustainPedal(0, 0, 120);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(2, 2);
vm.processNoteOffEvent(0, 0, 60, -1, 0.4);
REQUIRE_VOICE_COUNTS(2, 2);
tp.processFor(40);
REQUIRE_VOICE_COUNTS(2, 2);

vm.updateSustainPedal(0, 0, 0);
REQUIRE_VOICE_COUNTS(2, 1);
tp.processFor(20);
REQUIRE_VOICE_COUNTS(1, 1);

vm.processNoteOffEvent(0, 0, 64, -1, 0.4);
REQUIRE_VOICE_COUNTS(1, 0);

tp.processFor(20);
REQUIRE_NO_VOICES;
}

SECTION("Retrigger a note under sustain and release during sustain")
{
TestPlayer<32> tp;
auto &vm = tp.voiceManager;
REQUIRE_NO_VOICES;

vm.dialect = TestPlayer<32>::voiceManager_t::MIDI1Dialect::MIDI1;
vm.repeatedKeyMode = TestPlayer<32>::voiceManager_t::RepeatedKeyMode::PIANO;

vm.processNoteOnEvent(0, 0, 60, -1, 0.8, 0.0);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(1, 1);
vm.updateSustainPedal(0, 0, 120);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(1, 1);
vm.processNoteOffEvent(0, 0, 60, -1, 0.4);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(40);
REQUIRE_VOICE_COUNTS(1, 1);

INFO("About to retrigger");
vm.processNoteOnEvent(0, 0, 60, -1, 0.8, 0.0);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(40);

vm.processNoteOffEvent(0, 0, 60, -1, 0.8);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(40);

vm.updateSustainPedal(0, 0, 0);
REQUIRE_VOICE_COUNTS(1, 0);
tp.processFor(20);
REQUIRE_VOICE_COUNTS(0, 0);

tp.processFor(20);
REQUIRE_NO_VOICES;
}

SECTION("Retrigger a note under sustain and release outside sustain")
{
TestPlayer<32> tp;
auto &vm = tp.voiceManager;
REQUIRE_NO_VOICES;

vm.dialect = TestPlayer<32>::voiceManager_t::MIDI1Dialect::MIDI1;
vm.repeatedKeyMode = TestPlayer<32>::voiceManager_t::RepeatedKeyMode::PIANO;

vm.processNoteOnEvent(0, 0, 60, -1, 0.8, 0.0);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(1, 1);
vm.updateSustainPedal(0, 0, 120);
tp.processFor(10);
REQUIRE_VOICE_COUNTS(1, 1);
vm.processNoteOffEvent(0, 0, 60, -1, 0.4);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(40);
REQUIRE_VOICE_COUNTS(1, 1);

INFO("About to retrigger");
vm.processNoteOnEvent(0, 0, 60, -1, 0.8, 0.0);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(40);

SECTION("Retrigger a note under sustain") { REQUIRE_INCOMPLETE_TEST; }
vm.updateSustainPedal(0, 0, 0);
REQUIRE_VOICE_COUNTS(1, 1);
tp.processFor(10);
vm.processNoteOffEvent(0, 0, 60, -1, 0.8);
REQUIRE_VOICE_COUNTS(1, 0);

tp.processFor(20);
REQUIRE_NO_VOICES;
}
}
*/

0 comments on commit c95cf4e

Please sign in to comment.