Allow to set a multiplier on source, needed for LFO

This commit is contained in:
Jean Pierre Cimalando 2020-07-28 13:52:38 +02:00
parent 4703b939ab
commit 0b20932e12
6 changed files with 28 additions and 21 deletions

View file

@ -940,9 +940,9 @@ bool sfz::Region::processGenericCc(const Opcode& opcode, Range<float> 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<float> 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<float> range, con
assert(false);
break;
}
conn->first = ModKey(ModId::Controller, {}, p);
conn->source = ModKey(ModId::Controller, {}, p);
}
return true;

View file

@ -373,7 +373,11 @@ struct Region {
bool triggerOnNote { true };
// Modulation matrix connections
typedef std::pair<ModKey, ModKey> Connection;
struct Connection {
ModKey source;
ModKey target;
float sourceDepth = 1.0f;
};
std::vector<Connection> connections;
// Parent

View file

@ -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;
}

View file

@ -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];
}
}
}

View file

@ -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.

View file

@ -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_;
}