Correct the sostenuto/sustain logic
Only release if the received CC is one of the above AND if the region is not a one-shot
This commit is contained in:
parent
b3ff1469ed
commit
7f02c413c1
2 changed files with 59 additions and 7 deletions
|
|
@ -614,32 +614,38 @@ void Voice::registerCC(int delay, int ccNumber, float ccValue) noexcept
|
||||||
if (impl.region_ == nullptr)
|
if (impl.region_ == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const Region& region = *impl.region_;
|
||||||
|
|
||||||
if (impl.state_ != State::playing)
|
if (impl.state_ != State::playing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (impl.region_->checkSustain && (ccNumber == impl.region_->sostenutoCC)) {
|
if (ccNumber != region.sustainCC && ccNumber != region.sostenutoCC)
|
||||||
if (ccValue < impl.region_->sostenutoThreshold) {
|
return;
|
||||||
|
|
||||||
|
if (region.checkSustain && (ccNumber == region.sostenutoCC)) {
|
||||||
|
if (ccValue < region.sostenutoThreshold) {
|
||||||
impl.sostenutoState_ = Impl::SostenutoState::Up;
|
impl.sostenutoState_ = Impl::SostenutoState::Up;
|
||||||
} else if (impl.sostenutoState_ == Impl::SostenutoState::Up) {
|
} else if (impl.sostenutoState_ == Impl::SostenutoState::Up) {
|
||||||
impl.sostenutoState_ = Impl::SostenutoState::Sustaining;
|
impl.sostenutoState_ = Impl::SostenutoState::Sustaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (impl.region_->checkSostenuto && (ccNumber == impl.region_->sustainCC)) {
|
if (region.checkSostenuto && (ccNumber == region.sustainCC)) {
|
||||||
if (ccValue < impl.region_->sustainThreshold) {
|
if (ccValue < region.sustainThreshold) {
|
||||||
impl.sustainState_ = Impl::SustainState::Up;
|
impl.sustainState_ = Impl::SustainState::Up;
|
||||||
} else {
|
} else {
|
||||||
impl.sustainState_ = Impl::SustainState::Sustaining;
|
impl.sustainState_ = Impl::SustainState::Sustaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool sustainPedalReleaseCondition = !impl.region_->checkSustain
|
const bool sustainPedalReleaseCondition = !region.checkSustain
|
||||||
|| (impl.sustainState_ != Impl::SustainState::Sustaining);
|
|| (impl.sustainState_ != Impl::SustainState::Sustaining);
|
||||||
|
|
||||||
const bool sostenutoPedalReleaseCondition = !impl.region_->checkSostenuto
|
const bool sostenutoPedalReleaseCondition = !region.checkSostenuto
|
||||||
|| (impl.sostenutoState_ != Impl::SostenutoState::Sustaining);
|
|| (impl.sostenutoState_ != Impl::SostenutoState::Sustaining);
|
||||||
|
|
||||||
if (impl.noteIsOff_ && sostenutoPedalReleaseCondition && sustainPedalReleaseCondition)
|
if (impl.noteIsOff_ && region.loopMode != LoopMode::one_shot
|
||||||
|
&& sostenutoPedalReleaseCondition && sustainPedalReleaseCondition)
|
||||||
release(delay);
|
release(delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -926,6 +926,52 @@ TEST_CASE("[Synth] Release (sustain + sostenuto)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Synth] One shot regions with sustain + sostenuto")
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
|
||||||
|
synth.loadSfzString(fs::current_path() / "tests/TestFiles/one_shot_sustain.sfz", R"(
|
||||||
|
<region> key=60 sample=kick.wav loop_mode=one_shot
|
||||||
|
)");
|
||||||
|
SECTION("Sustain")
|
||||||
|
{
|
||||||
|
synth.noteOn(0, 60, 85);
|
||||||
|
synth.cc(1, 64, 127);
|
||||||
|
synth.noteOff(2, 60, 85);
|
||||||
|
synth.renderBlock(buffer);
|
||||||
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
|
synth.cc(1, 64, 0);
|
||||||
|
synth.renderBlock(buffer);
|
||||||
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
|
}
|
||||||
|
SECTION("Sostenuto")
|
||||||
|
{
|
||||||
|
synth.noteOn(0, 60, 85);
|
||||||
|
synth.cc(1, 66, 127);
|
||||||
|
synth.noteOff(2, 60, 85);
|
||||||
|
synth.renderBlock(buffer);
|
||||||
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
|
synth.cc(1, 66, 0);
|
||||||
|
synth.renderBlock(buffer);
|
||||||
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
|
}
|
||||||
|
SECTION("Sostenuto up first")
|
||||||
|
{
|
||||||
|
synth.noteOn(0, 60, 85);
|
||||||
|
synth.cc(1, 66, 127);
|
||||||
|
synth.cc(1, 64, 127);
|
||||||
|
synth.noteOff(2, 60, 85);
|
||||||
|
synth.renderBlock(buffer);
|
||||||
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
|
synth.cc(3, 66, 0);
|
||||||
|
synth.renderBlock(buffer);
|
||||||
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
|
synth.cc(4, 64, 0);
|
||||||
|
synth.renderBlock(buffer);
|
||||||
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("[Synth] Sustain threshold default")
|
TEST_CASE("[Synth] Sustain threshold default")
|
||||||
{
|
{
|
||||||
sfz::Synth synth;
|
sfz::Synth synth;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue