Fixes an issue that caused stuck notes.
Fixes an issue that caused a crash when using a loop.
This commit is contained in:
parent
4cafa3755d
commit
4055582671
3 changed files with 45 additions and 2 deletions
|
|
@ -101,7 +101,7 @@ void ADSREnvelope::getBlockInternal(absl::Span<Float> output) noexcept
|
||||||
if (releaseDelay > 0) {
|
if (releaseDelay > 0) {
|
||||||
// prevent computing the segment further than release point
|
// prevent computing the segment further than release point
|
||||||
size = std::min<size_t>(size, releaseDelay);
|
size = std::min<size_t>(size, releaseDelay);
|
||||||
} else if (releaseDelay == 0 && delay < 0) {
|
} else if (releaseDelay == 0 && delay <= 0) {
|
||||||
// release takes effect this frame
|
// release takes effect this frame
|
||||||
currentState = State::Release;
|
currentState = State::Release;
|
||||||
releaseDelay = -1;
|
releaseDelay = -1;
|
||||||
|
|
|
||||||
|
|
@ -1188,7 +1188,7 @@ void Voice::Impl::fillWithData(AudioSpan<float> buffer) noexcept
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
while (i < numSamples) {
|
while (i < numSamples) {
|
||||||
int wrappedIndex = (*indices)[i] - loop.size * blockRestarts;
|
int wrappedIndex = (*indices)[i] - loop.size * blockRestarts;
|
||||||
if (wrappedIndex > loop.end) {
|
while (wrappedIndex > loop.end) {
|
||||||
wrappedIndex -= loop.size;
|
wrappedIndex -= loop.size;
|
||||||
blockRestarts += 1;
|
blockRestarts += 1;
|
||||||
loop_.restarts += 1;
|
loop_.restarts += 1;
|
||||||
|
|
|
||||||
|
|
@ -2160,3 +2160,46 @@ TEST_CASE("[Synth] Reuse offed voices in the last case scenario for new notes")
|
||||||
REQUIRE( notes == std::vector<int> { i - 1, i } );
|
REQUIRE( notes == std::vector<int> { i - 1, i } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Synth] Note on and off at the maximum delay")
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
synth.setSampleRate(12800);
|
||||||
|
synth.setSamplesPerBlock(128);
|
||||||
|
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
|
||||||
|
synth.loadSfzString(fs::current_path() / "tests/TestFiles/noteonoff.sfz", R"(
|
||||||
|
<region> loop_start=4 loop_end=124 ampeg_release=0.5 sample=looped_flute.wav
|
||||||
|
)");
|
||||||
|
synth.setNumVoices(128);
|
||||||
|
synth.noteOn(127, 64, 64);
|
||||||
|
CHECK(synth.getNumActiveVoices() == 1);
|
||||||
|
synth.noteOff(127, 64, 0);
|
||||||
|
CHECK(synth.getNumActiveVoices() == 1);
|
||||||
|
// Render for a while
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
synth.renderBlock(buffer);
|
||||||
|
CHECK(synth.getNumActiveVoices() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Synth] Note on and off with delay")
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
synth.setSampleRate(12800);
|
||||||
|
synth.setSamplesPerBlock(128);
|
||||||
|
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
|
||||||
|
synth.loadSfzString(fs::current_path() / "tests/TestFiles/noteonoff.sfz", R"(
|
||||||
|
<region> loop_start=4 loop_end=124 ampeg_release=0.5 sample=looped_flute.wav
|
||||||
|
)");
|
||||||
|
synth.setNumVoices(128);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 127; ++i) {
|
||||||
|
synth.noteOn(i, i, 64);
|
||||||
|
synth.noteOff(i+1, i, 0);
|
||||||
|
}
|
||||||
|
CHECK(synth.getNumActiveVoices() == 127);
|
||||||
|
// Render for a while
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
synth.renderBlock(buffer);
|
||||||
|
CHECK(synth.getNumActiveVoices() == 0);
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue