WIP
This commit is contained in:
parent
df07f3ac82
commit
0a065a392c
2 changed files with 105 additions and 0 deletions
|
|
@ -202,6 +202,8 @@ struct Voice::Impl
|
|||
|
||||
State state_ { State::idle };
|
||||
bool noteIsOff_ { false };
|
||||
enum class SostenutoState { Up, Sustaining, PreviouslyDown };
|
||||
SostenutoState sostenutoState_ { SostenutoState::Up };
|
||||
|
||||
TriggerEvent triggerEvent_;
|
||||
absl::optional<int> triggerDelay_;
|
||||
|
|
@ -459,6 +461,13 @@ bool Voice::startVoice(Region* region, int delay, const TriggerEvent& event) noe
|
|||
impl.resources_.modMatrix.initVoice(impl.id_, region->getId(), impl.initialDelay_);
|
||||
impl.saveModulationTargets(region);
|
||||
|
||||
if (region->checkSostenuto) {
|
||||
const bool sostenutoPressed =
|
||||
impl.resources_.midiState.getCCValue(region->sostenutoCC) >= region->sostenutoThreshold;
|
||||
impl.sostenutoState_ =
|
||||
sostenutoPressed ? Impl::SostenutoState::PreviouslyDown : Impl::SostenutoState::Up;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -546,6 +555,10 @@ void Voice::registerNoteOff(int delay, int noteNumber, float velocity) noexcept
|
|||
if (!impl.region_->checkSustain
|
||||
|| impl.resources_.midiState.getCCValue(impl.region_->sustainCC) < impl.region_->sustainThreshold)
|
||||
release(delay);
|
||||
|
||||
if (!impl.region_->checkSostenuto
|
||||
|| impl.sostenutoState_ != Impl::SostenutoState::Sustaining)
|
||||
release(delay);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -564,6 +577,19 @@ void Voice::registerCC(int delay, int ccNumber, float ccValue) noexcept
|
|||
&& ccNumber == impl.region_->sustainCC
|
||||
&& ccValue < impl.region_->sustainThreshold)
|
||||
release(delay);
|
||||
|
||||
if (impl.region_->checkSostenuto
|
||||
&& ccNumber == impl.region_->sostenutoCC) {
|
||||
if (ccValue < impl.region_->sostenutoThreshold) {
|
||||
impl.sostenutoState_ = Impl::SostenutoState::Up;
|
||||
} else {
|
||||
if (impl.sostenutoState_ == Impl::SostenutoState::Up)
|
||||
impl.sostenutoState_ = Impl::SostenutoState::Sustaining;
|
||||
}
|
||||
|
||||
if (impl.sostenutoState_ != Impl::SostenutoState::Sustaining && impl.noteIsOff_)
|
||||
release(delay);
|
||||
}
|
||||
}
|
||||
|
||||
void Voice::registerPitchWheel(int delay, float pitch) noexcept
|
||||
|
|
@ -1512,6 +1538,7 @@ void Voice::reset() noexcept
|
|||
impl.count_ = 1;
|
||||
impl.floatPositionOffset_ = 0.0f;
|
||||
impl.noteIsOff_ = false;
|
||||
impl.sostenutoState_ = Impl::SostenutoState::Up;
|
||||
|
||||
impl.resetLoopInformation();
|
||||
|
||||
|
|
|
|||
|
|
@ -818,6 +818,35 @@ TEST_CASE("[Synth] Release (Different sustain CC)")
|
|||
REQUIRE( synth.getNumActiveVoices() == 2 );
|
||||
}
|
||||
|
||||
TEST_CASE("[Synth] Release key (Different sostenuto CC)")
|
||||
{
|
||||
sfz::Synth synth;
|
||||
synth.loadSfzString(fs::current_path() / "tests/TestFiles/release.sfz", R"(
|
||||
<global> sostenuto_cc=54
|
||||
<region> key=62 sample=*sine trigger=release_key
|
||||
)");
|
||||
synth.noteOn(0, 62, 85);
|
||||
synth.cc(0, 54, 127);
|
||||
synth.noteOff(0, 62, 85);
|
||||
REQUIRE( synth.getNumActiveVoices() == 1 );
|
||||
}
|
||||
|
||||
TEST_CASE("[Synth] Release (Different sostenuto CC)")
|
||||
{
|
||||
sfz::Synth synth;
|
||||
synth.loadSfzString(fs::current_path() / "tests/TestFiles/release.sfz", R"(
|
||||
<global>sostenuto_cc=54
|
||||
<region> key=62 sample=*silence
|
||||
<region> key=62 sample=*sine trigger=release
|
||||
)");
|
||||
synth.noteOn(0, 62, 85);
|
||||
synth.cc(0, 54, 127);
|
||||
synth.noteOff(0, 62, 85);
|
||||
REQUIRE( synth.getNumActiveVoices() == 1 );
|
||||
synth.cc(0, 54, 0);
|
||||
REQUIRE( synth.getNumActiveVoices() == 2 );
|
||||
}
|
||||
|
||||
TEST_CASE("[Synth] Sustain threshold default")
|
||||
{
|
||||
sfz::Synth synth;
|
||||
|
|
@ -852,6 +881,55 @@ TEST_CASE("[Synth] Sustain threshold")
|
|||
REQUIRE( synth.getNumActiveVoices() == 5 );
|
||||
}
|
||||
|
||||
TEST_CASE("[Synth] Sostenuto")
|
||||
{
|
||||
sfz::Synth synth;
|
||||
synth.loadSfzString(fs::current_path() / "tests/TestFiles/sostenuto.sfz", R"(
|
||||
<region> sample=*sine
|
||||
)");
|
||||
|
||||
SECTION("1 note")
|
||||
{
|
||||
synth.noteOn(0, 62, 85);
|
||||
synth.cc(1, 66, 1);
|
||||
synth.noteOff(2, 62, 85);
|
||||
REQUIRE( synth.getNumActiveVoices() == 1 );
|
||||
synth.cc(3, 66, 0);
|
||||
REQUIRE( synth.getNumActiveVoices() == 0 );
|
||||
}
|
||||
|
||||
SECTION("2 notes")
|
||||
{
|
||||
synth.noteOn(0, 62, 85);
|
||||
synth.noteOn(0, 64, 85);
|
||||
synth.cc(1, 66, 1);
|
||||
synth.noteOff(2, 62, 85);
|
||||
synth.noteOff(2, 64, 85);
|
||||
REQUIRE( synth.getNumActiveVoices() == 2 );
|
||||
synth.cc(3, 66, 0);
|
||||
REQUIRE( synth.getNumActiveVoices() == 0 );
|
||||
}
|
||||
|
||||
SECTION("1 note but after the pedal is depressed")
|
||||
{
|
||||
synth.cc(0, 66, 1);
|
||||
synth.noteOn(1, 62, 85);
|
||||
synth.noteOff(2, 62, 85);
|
||||
REQUIRE( synth.getNumActiveVoices() == 0 );
|
||||
}
|
||||
|
||||
SECTION("2 notes, 1 after the pedal is depressed")
|
||||
{
|
||||
synth.noteOn(0, 62, 85);
|
||||
synth.cc(1, 66, 1);
|
||||
synth.noteOn(2, 64, 85);
|
||||
synth.noteOff(3, 62, 85);
|
||||
synth.noteOff(3, 64, 85);
|
||||
REQUIRE( synth.getNumActiveVoices() == 1 );
|
||||
REQUIRE( getActiveVoices(synth)[0]->getTriggerEvent().number == 62 );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[Synth] Release (Multiple notes, release_key ignores the pedal)")
|
||||
{
|
||||
sfz::Synth synth;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue