diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 4e7a9f7d..53f5c944 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -178,17 +178,14 @@ void sfz::Synth::buildRegion(const std::vector& regionOpcodes) parseOpcodes(regionOpcodes); // Create the amplitude envelope - if (!lastRegion->flexAmpEG) { + if (!lastRegion->flexAmpEG) lastRegion->getOrCreateConnection( ModKey::createNXYZ(ModId::AmpEG, lastRegion->id), - ModKey::createNXYZ(ModId::Amplitude, lastRegion->id)).sourceDepth = 100.0f; - } - else { - ModKey source = ModKey::createNXYZ(ModId::Envelope, lastRegion->id, *lastRegion->flexAmpEG); - ModKey target = ModKey::createNXYZ(ModId::Amplitude, lastRegion->id); - if (!lastRegion->getConnection(source, target)) - lastRegion->getOrCreateConnection(source, target).sourceDepth = 100.0f; - } + ModKey::createNXYZ(ModId::MasterAmplitude, lastRegion->id)).sourceDepth = 1.0f; + else + lastRegion->getOrCreateConnection( + ModKey::createNXYZ(ModId::Envelope, lastRegion->id, *lastRegion->flexAmpEG), + ModKey::createNXYZ(ModId::MasterAmplitude, lastRegion->id)).sourceDepth = 1.0f; if (octaveOffset != 0 || noteOffset != 0) lastRegion->offsetAllKeys(octaveOffset * 12 + noteOffset); diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index ebed105b..ffb15f75 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -380,14 +380,16 @@ void sfz::Voice::amplitudeEnvelope(absl::Span modulationSpan) noexcept ModMatrix& mm = resources.modMatrix; + // Amplitude EG + absl::Span ampegOut(mm.getModulation(masterAmplitudeTarget), numSamples); + ASSERT(ampegOut.data()); + copy(ampegOut, modulationSpan); + // Amplitude envelope applyGain1(baseGain, modulationSpan); if (float* mod = mm.getModulation(amplitudeTarget)) { for (size_t i = 0; i < numSamples; ++i) - modulationSpan[i] = normalizePercents(mod[i]); - } - else { - ASSERTFALSE; + modulationSpan[i] *= normalizePercents(mod[i]); } // Volume envelope @@ -1050,6 +1052,7 @@ void sfz::Voice::resetSmoothers() noexcept void sfz::Voice::saveModulationTargets(const Region* region) noexcept { ModMatrix& mm = resources.modMatrix; + masterAmplitudeTarget = mm.findTarget(ModKey::createNXYZ(ModId::MasterAmplitude, region->getId())); amplitudeTarget = mm.findTarget(ModKey::createNXYZ(ModId::Amplitude, region->getId())); volumeTarget = mm.findTarget(ModKey::createNXYZ(ModId::Volume, region->getId())); panTarget = mm.findTarget(ModKey::createNXYZ(ModId::Pan, region->getId())); diff --git a/src/sfizz/Voice.h b/src/sfizz/Voice.h index 86b1c5ab..aa49297c 100644 --- a/src/sfizz/Voice.h +++ b/src/sfizz/Voice.h @@ -520,6 +520,7 @@ private: Smoother xfadeSmoother; void resetSmoothers() noexcept; + ModMatrix::TargetId masterAmplitudeTarget; ModMatrix::TargetId amplitudeTarget; ModMatrix::TargetId volumeTarget; ModMatrix::TargetId panTarget; diff --git a/src/sfizz/modulations/ModId.cpp b/src/sfizz/modulations/ModId.cpp index d21ba9e0..3d837ec5 100644 --- a/src/sfizz/modulations/ModId.cpp +++ b/src/sfizz/modulations/ModId.cpp @@ -38,6 +38,8 @@ int ModIds::flags(ModId id) noexcept return kModIsPerVoice; // targets + case ModId::MasterAmplitude: + return kModIsPerVoice|kModIsPercentMultiplicative; case ModId::Amplitude: return kModIsPerVoice|kModIsPercentMultiplicative; case ModId::Pan: diff --git a/src/sfizz/modulations/ModId.h b/src/sfizz/modulations/ModId.h index 3eb7022d..48d9b2d9 100644 --- a/src/sfizz/modulations/ModId.h +++ b/src/sfizz/modulations/ModId.h @@ -34,7 +34,8 @@ enum class ModId : int { //-------------------------------------------------------------------------- _TargetsStart = _SourcesEnd, - Amplitude = _TargetsStart, + MasterAmplitude = _TargetsStart, + Amplitude, Pan, Width, Position, diff --git a/src/sfizz/modulations/ModKey.cpp b/src/sfizz/modulations/ModKey.cpp index 2b9767d3..5fa48181 100644 --- a/src/sfizz/modulations/ModKey.cpp +++ b/src/sfizz/modulations/ModKey.cpp @@ -81,6 +81,8 @@ std::string ModKey::toString() const case ModId::FilEG: return absl::StrCat("FilterEG {", region_.number(), "}"); + case ModId::MasterAmplitude: + return absl::StrCat("MasterAmplitude {", region_.number(), "}"); case ModId::Amplitude: return absl::StrCat("Amplitude {", region_.number(), "}"); case ModId::Pan: