diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index c1aba0f6..573bc458 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -66,7 +66,6 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, uint8_t value volumeEnvelope.reset(db2mag(Default::volumeRange.clamp(volumedB))); baseGain = region->getBaseGain(); - baseGain *= region->getCrossfadeGain(midiState.getCCArray()); if (triggerType != TriggerType::CC) baseGain *= region->getNoteGain(number, value); @@ -75,6 +74,9 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, uint8_t value gain *= normalizeCC(midiState.getCCValue(region->amplitudeCC->first)) * normalizePercents(region->amplitudeCC->second); amplitudeEnvelope.reset(Default::normalizedRange.clamp(gain)); + float crossfadeGain { region->getCrossfadeGain(midiState.getCCArray()) }; + crossfadeEnvelope.reset(Default::normalizedRange.clamp(crossfadeGain)); + basePan = normalizeNegativePercents(region->pan); auto pan { basePan }; if (region->panCC) @@ -202,6 +204,11 @@ void sfz::Voice::registerCC(int delay, int ccNumber, uint8_t ccValue) noexcept const float newWidth { baseWidth + normalizeCC(ccValue) * normalizeNegativePercents(region->widthCC->second) }; widthEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newWidth)); } + + if (region->crossfadeCCInRange.contains(ccNumber) || region->crossfadeCCOutRange.contains(ccNumber)) { + const float crossfadeGain = region->getCrossfadeGain(midiState.getCCArray()); + crossfadeEnvelope.registerEvent(delay, Default::normalizedRange.clamp(crossfadeGain)); + } } void sfz::Voice::registerPitchWheel(int delay, int pitch) noexcept @@ -284,6 +291,10 @@ void sfz::Voice::processMono(AudioSpan buffer) noexcept amplitudeEnvelope.getBlock(span1); applyGain(span1, leftBuffer); + // Crossfade envelope + crossfadeEnvelope.getBlock(span1); + applyGain(span1, leftBuffer); + // Volume envelope volumeEnvelope.getBlock(span1); applyGain(span1, leftBuffer); @@ -324,6 +335,10 @@ void sfz::Voice::processStereo(AudioSpan buffer) noexcept amplitudeEnvelope.getBlock(span1); buffer.applyGain(span1); + // Crossfade envelope + crossfadeEnvelope.getBlock(span1); + buffer.applyGain(span1); + // Volume envelope volumeEnvelope.getBlock(span1); buffer.applyGain(span1); diff --git a/src/sfizz/Voice.h b/src/sfizz/Voice.h index 42b0b8df..9c0bb35d 100644 --- a/src/sfizz/Voice.h +++ b/src/sfizz/Voice.h @@ -302,6 +302,7 @@ private: ADSREnvelope egEnvelope; LinearEnvelope amplitudeEnvelope; // linear events + LinearEnvelope crossfadeEnvelope; LinearEnvelope panEnvelope; LinearEnvelope positionEnvelope; LinearEnvelope widthEnvelope;