Further separate the crossfades and initialize them properly

This commit is contained in:
Paul Ferrand 2020-07-05 17:40:03 +02:00
parent 4ee4bbe9c1
commit 18d4240e58
2 changed files with 29 additions and 7 deletions

View file

@ -107,6 +107,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
if (triggerType != TriggerType::CC) if (triggerType != TriggerType::CC)
baseGain *= region->getNoteGain(number, value); baseGain *= region->getNoteGain(number, value);
gainSmoother.reset(); gainSmoother.reset();
resetCrossfades();
// Check that we can handle the number of filters; filters should be cleared here // Check that we can handle the number of filters; filters should be cleared here
ASSERT((filters.capacity() - filters.size()) >= region->filters.size()); ASSERT((filters.capacity() - filters.size()) >= region->filters.size());
@ -310,15 +311,37 @@ void sfz::Voice::renderBlock(AudioSpan<float> buffer) noexcept
#endif #endif
} }
void sfz::Voice::resetCrossfades() noexcept
{
float xfadeValue { 1.0f };
const auto xfCurve = region->crossfadeCCCurve;
for (const auto& mod : region->crossfadeCCInRange) {
const auto value = resources.midiState.getCCValue(mod.cc);
xfadeValue *= crossfadeIn(mod.data, value, xfCurve);
}
for (const auto& mod : region->crossfadeCCOutRange) {
const auto value = resources.midiState.getCCValue(mod.cc);
xfadeValue *= crossfadeOut(mod.data, value, xfCurve);
}
xfadeSmoother.reset(xfadeValue);
}
void sfz::Voice::applyCrossfades(absl::Span<float> modulationSpan) noexcept void sfz::Voice::applyCrossfades(absl::Span<float> modulationSpan) noexcept
{ {
const auto numSamples = modulationSpan.size(); const auto numSamples = modulationSpan.size();
const auto xfCurve = region->crossfadeCCCurve; const auto xfCurve = region->crossfadeCCCurve;
auto tempSpan = resources.bufferPool.getBuffer(numSamples); auto tempSpan = resources.bufferPool.getBuffer(numSamples);
if (!tempSpan) auto xfadeSpan = resources.bufferPool.getBuffer(numSamples);
if (!tempSpan || !xfadeSpan)
return; return;
fill<float>(*xfadeSpan, 1.0f);
bool smoothOutput = false; bool smoothOutput = false;
for (const auto& mod : region->crossfadeCCInRange) { for (const auto& mod : region->crossfadeCCInRange) {
const auto events = resources.midiState.getCCEvents(mod.cc); const auto events = resources.midiState.getCCEvents(mod.cc);
@ -326,7 +349,7 @@ void sfz::Voice::applyCrossfades(absl::Span<float> modulationSpan) noexcept
linearEnvelope(events, *tempSpan, [&](float x) { linearEnvelope(events, *tempSpan, [&](float x) {
return crossfadeIn(mod.data, x, xfCurve); return crossfadeIn(mod.data, x, xfCurve);
}); });
applyGain<float>(*tempSpan, modulationSpan); applyGain<float>(*tempSpan, *xfadeSpan);
} }
for (const auto& mod : region->crossfadeCCOutRange) { for (const auto& mod : region->crossfadeCCOutRange) {
@ -335,13 +358,11 @@ void sfz::Voice::applyCrossfades(absl::Span<float> modulationSpan) noexcept
linearEnvelope(events, *tempSpan, [&](float x) { linearEnvelope(events, *tempSpan, [&](float x) {
return crossfadeOut(mod.data, x, xfCurve); return crossfadeOut(mod.data, x, xfCurve);
}); });
applyGain<float>(*tempSpan, modulationSpan); applyGain<float>(*tempSpan, *xfadeSpan);
} }
if (smoothOutput) { xfadeSmoother.process(*xfadeSpan, *xfadeSpan);
xfadeSmoother.reset(modulationSpan.front()); applyGain<float>(*xfadeSpan, modulationSpan);
xfadeSmoother.process(modulationSpan, modulationSpan);
}
} }

View file

@ -347,6 +347,7 @@ private:
* @param modulationSpan * @param modulationSpan
*/ */
void applyCrossfades(absl::Span<float> modulationSpan) noexcept; void applyCrossfades(absl::Span<float> modulationSpan) noexcept;
void resetCrossfades() noexcept;
/** /**
* @brief Amplitude stage for a mono source * @brief Amplitude stage for a mono source