diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 685d7587..25d38f40 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -940,9 +940,9 @@ bool sfz::Region::processGenericCc(const Opcode& opcode, Range range, con auto it = std::find_if(connections.begin(), connections.end(), [ccNumber, &target](const Connection& x) -> bool { - return x.first.id() == ModId::Controller && - x.first.parameters().cc == ccNumber && - x.second == target; + return x.source.id() == ModId::Controller && + x.source.parameters().cc == ccNumber && + x.target == target; }); Connection *conn; @@ -951,12 +951,12 @@ bool sfz::Region::processGenericCc(const Opcode& opcode, Range range, con else { connections.emplace_back(); conn = &connections.back(); - conn->first = ModKey::createCC(ccNumber, 0, 0, 0, 0); - conn->second = target; + conn->source = ModKey::createCC(ccNumber, 0, 0, 0, 0); + conn->target = target; } // - ModKey::Parameters p = conn->first.parameters(); + ModKey::Parameters p = conn->source.parameters(); switch (opcode.category) { case kOpcodeOnCcN: setValueFromOpcode(opcode, p.value, range); @@ -977,7 +977,7 @@ bool sfz::Region::processGenericCc(const Opcode& opcode, Range range, con assert(false); break; } - conn->first = ModKey(ModId::Controller, {}, p); + conn->source = ModKey(ModId::Controller, {}, p); } return true; diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index 0426d6d7..f226a331 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -373,7 +373,11 @@ struct Region { bool triggerOnNote { true }; // Modulation matrix connections - typedef std::pair Connection; + struct Connection { + ModKey source; + ModKey target; + float sourceDepth = 1.0f; + }; std::vector connections; // Parent diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 61fb532d..08d5f5e5 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -1357,7 +1357,7 @@ void sfz::Synth::setupModMatrix() for (const Region::Connection& conn : region->connections) { ModGenerator* gen = nullptr; - switch (conn.first.id()) { + switch (conn.source.id()) { case ModId::Controller: gen = genController.get(); break; @@ -1370,8 +1370,8 @@ void sfz::Synth::setupModMatrix() if (!gen) continue; - ModMatrix::SourceId source = mm.registerSource(conn.first, *gen); - ModMatrix::TargetId target = mm.registerTarget(conn.second); + ModMatrix::SourceId source = mm.registerSource(conn.source, *gen); + ModMatrix::TargetId target = mm.registerTarget(conn.target); ASSERT(source); if (!source) { @@ -1385,7 +1385,7 @@ void sfz::Synth::setupModMatrix() continue; } - if (!mm.connect(source, target)) { + if (!mm.connect(source, target, conn.sourceDepth)) { DBG("[sfizz] Failed to connect modulation source and target"); ASSERTFALSE; } diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index c4893fd0..ef68215e 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -34,7 +34,7 @@ struct ModMatrix::Impl { }; struct ConnectionData { - // nothing + float sourceDepth_ {}; }; struct Target { @@ -176,7 +176,7 @@ ModMatrix::TargetId ModMatrix::findTarget(const ModKey& key) return TargetId(it->second); } -bool ModMatrix::connect(SourceId sourceId, TargetId targetId) +bool ModMatrix::connect(SourceId sourceId, TargetId targetId, float sourceDepth) { Impl& impl = *impl_; unsigned sourceIndex = sourceId.number(); @@ -186,7 +186,8 @@ bool ModMatrix::connect(SourceId sourceId, TargetId targetId) return false; Impl::Target& target = impl.targets_[targetIndex]; - /*Impl::ConnectionData& conn =*/ target.connectedSources[sourceIndex]; + Impl::ConnectionData& conn = target.connectedSources[sourceIndex]; + conn.sourceDepth_ = sourceDepth; return true; } @@ -317,6 +318,7 @@ float* ModMatrix::getModulation(TargetId targetId) // then add or multiply, depending on target flags while (sourcesPos != sourcesEnd) { Impl::Source &source = impl.sources_[sourcesPos->first]; + const float sourceDepth = sourcesPos->second.sourceDepth_; const int sourceFlags = source.key.flags(); // only accept per-voice sources of the same region @@ -334,16 +336,16 @@ float* ModMatrix::getModulation(TargetId targetId) source.gen->generate(source.key, impl.voiceId_, temp); if (targetFlags & kModIsMultiplicative) { for (uint32_t i = 0; i < numFrames; ++i) - buffer[i] *= temp[i]; + buffer[i] *= sourceDepth * temp[i]; } else if (targetFlags & kModIsPercentMultiplicative) { for (uint32_t i = 0; i < numFrames; ++i) - buffer[i] *= 0.01f * temp[i]; + buffer[i] *= (0.01f * sourceDepth) * temp[i]; } else { ASSERT(targetFlags & kModIsAdditive); for (uint32_t i = 0; i < numFrames; ++i) - buffer[i] += temp[i]; + buffer[i] += sourceDepth * temp[i]; } } } diff --git a/src/sfizz/modulations/ModMatrix.h b/src/sfizz/modulations/ModMatrix.h index 4622f4b1..f9338d68 100644 --- a/src/sfizz/modulations/ModMatrix.h +++ b/src/sfizz/modulations/ModMatrix.h @@ -90,9 +90,10 @@ public: * * @param sourceId source of the connection * @param targetId target of the connection + * @param sourceDepth amount which multiplies the source output * @return true if the connection was successfully made, otherwise false */ - bool connect(SourceId sourceId, TargetId targetId); + bool connect(SourceId sourceId, TargetId targetId, float sourceDepth); /** * @brief Reinitialize modulation sources overall. diff --git a/tests/RegionTHelpers.cpp b/tests/RegionTHelpers.cpp index d55f05ad..a47b56ed 100644 --- a/tests/RegionTHelpers.cpp +++ b/tests/RegionTHelpers.cpp @@ -27,7 +27,7 @@ sfz::ModKey::Parameters RegionCCView::at(int cc) const { for (const sfz::Region::Connection& conn : region_.connections) { if (match(conn)) { - const sfz::ModKey::Parameters p = conn.first.parameters(); + const sfz::ModKey::Parameters p = conn.source.parameters(); if (p.cc == cc) return p; } @@ -37,5 +37,5 @@ sfz::ModKey::Parameters RegionCCView::at(int cc) const bool RegionCCView::match(const sfz::Region::Connection& conn) const { - return conn.first.id() == sfz::ModId::Controller && conn.second == target_; + return conn.source.id() == sfz::ModId::Controller && conn.target == target_; }