Merge pull request #760 from jpcima/things-oncc
More oncc targets for EG and LFO
This commit is contained in:
commit
f05921712c
7 changed files with 445 additions and 105 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
|
@ -15,7 +15,7 @@ env:
|
|||
|
||||
jobs:
|
||||
clang_tidy:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -804,7 +804,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
|||
if (parseEGOpcode(opcode, filterEG)) {
|
||||
getOrCreateConnection(
|
||||
ModKey::createNXYZ(ModId::FilEG, id),
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id));
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id, 0));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -832,7 +832,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
|||
if (parseLFOOpcode(opcode, filterLFO)) {
|
||||
getOrCreateConnection(
|
||||
ModKey::createNXYZ(ModId::FilLFO, id),
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id));
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id, 0));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -897,7 +897,7 @@ bool sfz::Region::parseLFOOpcode(const Opcode& opcode, LFODescription& lfo)
|
|||
else if (absl::StartsWith(opcode.name, "fillfo_")) {
|
||||
sourceKey = ModKey::createNXYZ(ModId::FilLFO, id);
|
||||
sourceDepthKey = ModKey::createNXYZ(ModId::FilLFODepth, id);
|
||||
targetKey = ModKey::createNXYZ(ModId::FilCutoff, id);
|
||||
targetKey = ModKey::createNXYZ(ModId::FilCutoff, id, 0);
|
||||
lfo.freqKey = ModKey::createNXYZ(ModId::FilLFOFrequency, id);
|
||||
depthSpec = Default::filLFODepth;
|
||||
depthModSpec = Default::filterCutoffMod;
|
||||
|
|
@ -1076,7 +1076,7 @@ bool sfz::Region::parseEGOpcode(const Opcode& opcode, EGDescription& eg)
|
|||
case hash("fileg_depth"):
|
||||
getOrCreateConnection(
|
||||
ModKey::createNXYZ(ModId::FilEG, id),
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id)).sourceDepth = opcode.read(Default::egDepth);
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id, 0)).sourceDepth = opcode.read(Default::egDepth);
|
||||
break;
|
||||
|
||||
case hash("pitcheg_veltodepth"): // also pitcheg_vel2depth
|
||||
|
|
@ -1087,7 +1087,7 @@ bool sfz::Region::parseEGOpcode(const Opcode& opcode, EGDescription& eg)
|
|||
case hash("fileg_veltodepth"): // also fileg_vel2depth
|
||||
getOrCreateConnection(
|
||||
ModKey::createNXYZ(ModId::FilEG, id),
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id)).velToDepth = opcode.read(Default::egVel2Depth);
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id, 0)).velToDepth = opcode.read(Default::egVel2Depth);
|
||||
break;
|
||||
|
||||
case_any_ccN("pitcheg_depth"):
|
||||
|
|
@ -1099,7 +1099,7 @@ bool sfz::Region::parseEGOpcode(const Opcode& opcode, EGDescription& eg)
|
|||
case_any_ccN("fileg_depth"):
|
||||
getOrCreateConnection(
|
||||
ModKey::createNXYZ(ModId::FilEG, id),
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id)).sourceDepthMod = ModKey::createNXYZ(ModId::FilEGDepth, id);
|
||||
ModKey::createNXYZ(ModId::FilCutoff, id, 0)).sourceDepthMod = ModKey::createNXYZ(ModId::FilEGDepth, id);
|
||||
processGenericCc(opcode, Default::filterCutoffMod, ModKey::createNXYZ(ModId::FilEGDepth, id));
|
||||
break;
|
||||
|
||||
|
|
@ -1161,15 +1161,30 @@ bool sfz::Region::parseLFOOpcodeV2(const Opcode& opcode)
|
|||
return nullptr;
|
||||
return &lfo.sub[subNumber1Based - 1];
|
||||
};
|
||||
auto LFO_EG_filter_EQ_target = [this, &opcode, lfoNumber](ModId sourceId, ModId targetId, const OpcodeSpec<float>& spec) -> bool {
|
||||
const unsigned index = opcode.parameters.size() == 2 ? opcode.parameters.back() - 1 : 0;
|
||||
if (!extendIfNecessary(filters, index + 1, Default::numFilters))
|
||||
return false;
|
||||
const ModKey source = ModKey::createNXYZ(sourceId, id, lfoNumber);
|
||||
const ModKey target = ModKey::createNXYZ(targetId, id, index);
|
||||
auto LFO_target = [this, &opcode, lfoNumber](const ModKey& target, const OpcodeSpec<float>& spec) -> bool {
|
||||
const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber);
|
||||
getOrCreateConnection(source, target).sourceDepth = opcode.read(spec);
|
||||
return true;
|
||||
};
|
||||
auto LFO_target_cc = [this, &opcode, lfoNumber](const ModKey& target, const OpcodeSpec<float>& spec) -> bool {
|
||||
const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber);
|
||||
const ModKey depth = ModKey::getSourceDepthKey(source, target);
|
||||
ASSERT(depth);
|
||||
Connection& conn = getOrCreateConnection(source, target);
|
||||
conn.sourceDepthMod = depth;
|
||||
processGenericCc(opcode, spec, depth);
|
||||
return true;
|
||||
};
|
||||
auto ensureFilter = [this, &opcode]() {
|
||||
ASSERT(opcode.parameters.size() >= 2);
|
||||
const unsigned index = opcode.parameters[1] - 1;
|
||||
return extendIfNecessary(filters, index + 1, Default::numFilters);
|
||||
};
|
||||
auto ensureEQ = [this, &opcode]() {
|
||||
ASSERT(opcode.parameters.size() >= 2);
|
||||
const unsigned index = opcode.parameters[1] - 1;
|
||||
return extendIfNecessary(equalizers, index + 1, Default::numEQs);
|
||||
};
|
||||
|
||||
//
|
||||
switch (opcode.lettersOnlyHash) {
|
||||
|
|
@ -1252,71 +1267,100 @@ bool sfz::Region::parseLFOOpcodeV2(const Opcode& opcode)
|
|||
|
||||
// Modulation: LFO (targets)
|
||||
case hash("lfo&_amplitude"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Amplitude, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::amplitudeMod);
|
||||
}
|
||||
LFO_target(ModKey::createNXYZ(ModId::Amplitude, id), Default::amplitudeMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_amplitude"):
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::Amplitude, id), Default::amplitudeMod);
|
||||
break;
|
||||
case hash("lfo&_pan"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Pan, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::panMod);
|
||||
}
|
||||
LFO_target(ModKey::createNXYZ(ModId::Pan, id), Default::panMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_pan"):
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::Pan, id), Default::panMod);
|
||||
break;
|
||||
case hash("lfo&_width"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Width, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::widthMod);
|
||||
}
|
||||
LFO_target(ModKey::createNXYZ(ModId::Width, id), Default::widthMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_width"):
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::Width, id), Default::widthMod);
|
||||
break;
|
||||
case hash("lfo&_position"): // sfizz extension
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Position, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::positionMod);
|
||||
}
|
||||
LFO_target(ModKey::createNXYZ(ModId::Position, id), Default::positionMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_position"): // sfizz extension
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::Position, id), Default::positionMod);
|
||||
break;
|
||||
case hash("lfo&_pitch"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Pitch, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::pitchMod);
|
||||
}
|
||||
LFO_target(ModKey::createNXYZ(ModId::Pitch, id), Default::pitchMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_pitch"):
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::Pitch, id), Default::pitchMod);
|
||||
break;
|
||||
case hash("lfo&_volume"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Volume, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::volumeMod);
|
||||
}
|
||||
LFO_target(ModKey::createNXYZ(ModId::Volume, id), Default::volumeMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_volume"):
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::Volume, id), Default::volumeMod);
|
||||
break;
|
||||
|
||||
case hash("lfo&_cutoff&"):
|
||||
LFO_EG_filter_EQ_target(ModId::LFO, ModId::FilCutoff, Default::filterCutoffMod);
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
LFO_target(ModKey::createNXYZ(ModId::FilCutoff, id, opcode.parameters[1] - 1), Default::filterCutoffMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_cutoff&"):
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::FilCutoff, id, opcode.parameters[1] - 1), Default::filterCutoffMod);
|
||||
break;
|
||||
case hash("lfo&_resonance&"):
|
||||
LFO_EG_filter_EQ_target(ModId::LFO, ModId::FilResonance, Default::filterResonanceMod);
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
LFO_target(ModKey::createNXYZ(ModId::FilResonance, id, opcode.parameters[1] - 1), Default::filterResonanceMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_resonance&"):
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::FilResonance, id, opcode.parameters[1] - 1), Default::filterResonanceMod);
|
||||
break;
|
||||
case hash("lfo&_fil&gain"):
|
||||
LFO_EG_filter_EQ_target(ModId::LFO, ModId::FilGain, Default::filterGainMod);
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
LFO_target(ModKey::createNXYZ(ModId::FilGain, id, opcode.parameters[1] - 1), Default::filterGainMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_fil&gain"):
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::FilGain, id, opcode.parameters[1] - 1), Default::filterGainMod);
|
||||
break;
|
||||
case hash("lfo&_eq&gain"):
|
||||
LFO_EG_filter_EQ_target(ModId::LFO, ModId::EqGain, Default::eqGainMod);
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
LFO_target(ModKey::createNXYZ(ModId::EqGain, id, opcode.parameters[1] - 1), Default::eqGainMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_eq&gain"):
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::EqGain, id, opcode.parameters[1] - 1), Default::eqGainMod);
|
||||
break;
|
||||
case hash("lfo&_eq&freq"):
|
||||
LFO_EG_filter_EQ_target(ModId::LFO, ModId::EqFrequency, Default::eqFrequencyMod);
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
LFO_target(ModKey::createNXYZ(ModId::EqFrequency, id, opcode.parameters[1] - 1), Default::eqFrequencyMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_eq&freq"):
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::EqFrequency, id, opcode.parameters[1] - 1), Default::eqFrequencyMod);
|
||||
break;
|
||||
case hash("lfo&_eq&bw"):
|
||||
LFO_EG_filter_EQ_target(ModId::LFO, ModId::EqBandwidth, Default::eqBandwidthMod);
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
LFO_target(ModKey::createNXYZ(ModId::EqBandwidth, id, opcode.parameters[1] - 1), Default::eqBandwidthMod);
|
||||
break;
|
||||
case_any_ccN("lfo&_eq&bw"):
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
LFO_target_cc(ModKey::createNXYZ(ModId::EqBandwidth, id, opcode.parameters[1] - 1), Default::eqBandwidthMod);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1344,15 +1388,30 @@ bool sfz::Region::parseEGOpcodeV2(const Opcode& opcode)
|
|||
return nullptr;
|
||||
return &eg.points[pointNumber];
|
||||
};
|
||||
auto LFO_EG_filter_EQ_target = [this, &opcode, egNumber](ModId sourceId, ModId targetId, const OpcodeSpec<float>& spec) -> bool {
|
||||
const unsigned index = opcode.parameters.size() == 2 ? opcode.parameters.back() - 1 : 0;
|
||||
if (!extendIfNecessary(filters, index + 1, Default::numFilters))
|
||||
return false;
|
||||
const ModKey source = ModKey::createNXYZ(sourceId, id, egNumber);
|
||||
const ModKey target = ModKey::createNXYZ(targetId, id, index);
|
||||
auto EG_target = [this, &opcode, egNumber](const ModKey& target, const OpcodeSpec<float>& spec) -> bool {
|
||||
const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber);
|
||||
getOrCreateConnection(source, target).sourceDepth = opcode.read(spec);
|
||||
return true;
|
||||
};
|
||||
auto EG_target_cc = [this, &opcode, egNumber](const ModKey& target, const OpcodeSpec<float>& spec) -> bool {
|
||||
const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber);
|
||||
const ModKey depth = ModKey::getSourceDepthKey(source, target);
|
||||
ASSERT(depth);
|
||||
Connection& conn = getOrCreateConnection(source, target);
|
||||
conn.sourceDepthMod = depth;
|
||||
processGenericCc(opcode, spec, depth);
|
||||
return true;
|
||||
};
|
||||
auto ensureFilter = [this, &opcode]() {
|
||||
ASSERT(opcode.parameters.size() >= 2);
|
||||
const unsigned index = opcode.parameters[1] - 1;
|
||||
return extendIfNecessary(filters, index + 1, Default::numFilters);
|
||||
};
|
||||
auto ensureEQ = [this, &opcode]() {
|
||||
ASSERT(opcode.parameters.size() >= 2);
|
||||
const unsigned index = opcode.parameters[1] - 1;
|
||||
return extendIfNecessary(equalizers, index + 1, Default::numEQs);
|
||||
};
|
||||
|
||||
//
|
||||
switch (opcode.lettersOnlyHash) {
|
||||
|
|
@ -1385,70 +1444,100 @@ bool sfz::Region::parseEGOpcodeV2(const Opcode& opcode)
|
|||
|
||||
// Modulation: Flex EG (targets)
|
||||
case hash("eg&_amplitude"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Amplitude, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::amplitudeMod);
|
||||
}
|
||||
EG_target(ModKey::createNXYZ(ModId::Amplitude, id), Default::amplitudeMod);
|
||||
break;
|
||||
case_any_ccN("eg&_amplitude"):
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::Amplitude, id), Default::amplitudeMod);
|
||||
break;
|
||||
case hash("eg&_pan"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Pan, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::panMod);
|
||||
}
|
||||
EG_target(ModKey::createNXYZ(ModId::Pan, id), Default::panMod);
|
||||
break;
|
||||
case_any_ccN("eg&_pan"):
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::Pan, id), Default::panMod);
|
||||
break;
|
||||
case hash("eg&_width"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Width, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::widthMod);
|
||||
}
|
||||
EG_target(ModKey::createNXYZ(ModId::Width, id), Default::widthMod);
|
||||
break;
|
||||
case_any_ccN("eg&_width"):
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::Width, id), Default::widthMod);
|
||||
break;
|
||||
case hash("eg&_position"): // sfizz extension
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Position, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::positionMod);
|
||||
}
|
||||
EG_target(ModKey::createNXYZ(ModId::Position, id), Default::positionMod);
|
||||
break;
|
||||
case_any_ccN("eg&_position"): // sfizz extension
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::Position, id), Default::positionMod);
|
||||
break;
|
||||
case hash("eg&_pitch"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Pitch, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::pitchMod);
|
||||
}
|
||||
EG_target(ModKey::createNXYZ(ModId::Pitch, id), Default::pitchMod);
|
||||
break;
|
||||
case_any_ccN("eg&_pitch"):
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::Pitch, id), Default::pitchMod);
|
||||
break;
|
||||
case hash("eg&_volume"):
|
||||
{
|
||||
const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber);
|
||||
const ModKey target = ModKey::createNXYZ(ModId::Volume, id);
|
||||
getOrCreateConnection(source, target).sourceDepth =
|
||||
opcode.read(Default::volumeMod);
|
||||
}
|
||||
EG_target(ModKey::createNXYZ(ModId::Volume, id), Default::volumeMod);
|
||||
break;
|
||||
case_any_ccN("eg&_volume"):
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::Volume, id), Default::volumeMod);
|
||||
break;
|
||||
case hash("eg&_cutoff&"):
|
||||
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::FilCutoff, Default::filterCutoffMod);
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
EG_target(ModKey::createNXYZ(ModId::FilCutoff, id, opcode.parameters[1] - 1), Default::filterCutoffMod);
|
||||
break;
|
||||
case_any_ccN("eg&_cutoff&"):
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::FilCutoff, id, opcode.parameters[1] - 1), Default::filterCutoffMod);
|
||||
break;
|
||||
case hash("eg&_resonance&"):
|
||||
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::FilResonance, Default::filterResonanceMod);
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
EG_target(ModKey::createNXYZ(ModId::FilResonance, id, opcode.parameters[1] - 1), Default::filterResonanceMod);
|
||||
break;
|
||||
case_any_ccN("eg&_resonance&"):
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::FilResonance, id, opcode.parameters[1] - 1), Default::filterResonanceMod);
|
||||
break;
|
||||
case hash("eg&_fil&gain"):
|
||||
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::FilGain, Default::filterGainMod);
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
EG_target(ModKey::createNXYZ(ModId::FilGain, id, opcode.parameters[1] - 1), Default::filterGainMod);
|
||||
break;
|
||||
case_any_ccN("eg&_fil&gain"):
|
||||
if (!ensureFilter())
|
||||
return false;
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::FilGain, id, opcode.parameters[1] - 1), Default::filterGainMod);
|
||||
break;
|
||||
case hash("eg&_eq&gain"):
|
||||
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::EqGain, Default::eqGainMod);
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
EG_target(ModKey::createNXYZ(ModId::EqGain, id, opcode.parameters[1] - 1), Default::eqGainMod);
|
||||
break;
|
||||
case_any_ccN("eg&_eq&gain"):
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::EqGain, id, opcode.parameters[1] - 1), Default::eqGainMod);
|
||||
break;
|
||||
case hash("eg&_eq&freq"):
|
||||
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::EqFrequency, Default::eqFrequencyMod);
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
EG_target(ModKey::createNXYZ(ModId::EqFrequency, id, opcode.parameters[1] - 1), Default::eqFrequencyMod);
|
||||
break;
|
||||
case_any_ccN("eg&_eq&freq"):
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::EqFrequency, id, opcode.parameters[1] - 1), Default::eqFrequencyMod);
|
||||
break;
|
||||
case hash("eg&_eq&bw"):
|
||||
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::EqBandwidth, Default::eqBandwidthMod);
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
EG_target(ModKey::createNXYZ(ModId::EqBandwidth, id, opcode.parameters[1] - 1), Default::eqBandwidthMod);
|
||||
break;
|
||||
case_any_ccN("eg&_eq&bw"):
|
||||
if (!ensureEQ())
|
||||
return false;
|
||||
EG_target_cc(ModKey::createNXYZ(ModId::EqBandwidth, id, opcode.parameters[1] - 1), Default::eqBandwidthMod);
|
||||
break;
|
||||
|
||||
case hash("eg&_ampeg"):
|
||||
|
|
|
|||
|
|
@ -100,6 +100,54 @@ int ModIds::flags(ModId id) noexcept
|
|||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOPhase:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOAmplitudeDepth:
|
||||
return kModIsPerVoice|kModIsMultiplicative;
|
||||
case ModId::LFOPanDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOWidthDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOPositionDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOPitchDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOVolumeDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOFilCutoffDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOFilResonanceDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOFilGainDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOEqGainDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOEqFrequencyDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::LFOEqBandwidthDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGAmplitudeDepth:
|
||||
return kModIsPerVoice|kModIsMultiplicative;
|
||||
case ModId::EGPanDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGWidthDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGPositionDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGPitchDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGVolumeDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGFilCutoffDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGFilResonanceDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGFilGainDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGEqGainDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGEqFrequencyDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
case ModId::EGEqBandwidthDepth:
|
||||
return kModIsPerVoice|kModIsAdditive;
|
||||
|
||||
// unknown
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -64,6 +64,30 @@ enum class ModId : int {
|
|||
LFOFrequency,
|
||||
LFOBeats,
|
||||
LFOPhase,
|
||||
LFOAmplitudeDepth,
|
||||
LFOPanDepth,
|
||||
LFOWidthDepth,
|
||||
LFOPositionDepth,
|
||||
LFOPitchDepth,
|
||||
LFOVolumeDepth,
|
||||
LFOFilCutoffDepth,
|
||||
LFOFilResonanceDepth,
|
||||
LFOFilGainDepth,
|
||||
LFOEqGainDepth,
|
||||
LFOEqFrequencyDepth,
|
||||
LFOEqBandwidthDepth,
|
||||
EGAmplitudeDepth,
|
||||
EGPanDepth,
|
||||
EGWidthDepth,
|
||||
EGPositionDepth,
|
||||
EGPitchDepth,
|
||||
EGVolumeDepth,
|
||||
EGFilCutoffDepth,
|
||||
EGFilResonanceDepth,
|
||||
EGFilGainDepth,
|
||||
EGEqGainDepth,
|
||||
EGEqFrequencyDepth,
|
||||
EGEqBandwidthDepth,
|
||||
|
||||
_TargetsEnd,
|
||||
// [/targets] --------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -170,11 +170,179 @@ std::string ModKey::toString() const
|
|||
return absl::StrCat("LFOBeats {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::LFOPhase:
|
||||
return absl::StrCat("LFOPhase {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::LFOAmplitudeDepth:
|
||||
return absl::StrCat("LFOAmplitudeDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::LFOPanDepth:
|
||||
return absl::StrCat("LFOPanDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::LFOWidthDepth:
|
||||
return absl::StrCat("LFOWidthDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::LFOPositionDepth:
|
||||
return absl::StrCat("LFOPositionDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::LFOPitchDepth:
|
||||
return absl::StrCat("LFOPitchDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::LFOVolumeDepth:
|
||||
return absl::StrCat("LFOVolumeDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::LFOFilCutoffDepth:
|
||||
return absl::StrCat("LFOFilCutoffDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::LFOFilResonanceDepth:
|
||||
return absl::StrCat("LFOFilResonanceDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::LFOFilGainDepth:
|
||||
return absl::StrCat("LFOFilGainDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::LFOEqGainDepth:
|
||||
return absl::StrCat("LFOEqGainDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::LFOEqFrequencyDepth:
|
||||
return absl::StrCat("LFOEqFrequencyDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::LFOEqBandwidthDepth:
|
||||
return absl::StrCat("LFOEqBandwidthDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::EGAmplitudeDepth:
|
||||
return absl::StrCat("EGAmplitudeDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::EGPanDepth:
|
||||
return absl::StrCat("EGPanDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::EGWidthDepth:
|
||||
return absl::StrCat("EGWidthDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::EGPositionDepth:
|
||||
return absl::StrCat("EGPositionDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::EGPitchDepth:
|
||||
return absl::StrCat("EGPitchDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::EGVolumeDepth:
|
||||
return absl::StrCat("EGVolumeDepth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||
case ModId::EGFilCutoffDepth:
|
||||
return absl::StrCat("EGFilCutoffDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::EGFilResonanceDepth:
|
||||
return absl::StrCat("EGFilResonanceDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::EGFilGainDepth:
|
||||
return absl::StrCat("EGFilGainDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::EGEqGainDepth:
|
||||
return absl::StrCat("EGEqGainDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::EGEqFrequencyDepth:
|
||||
return absl::StrCat("EGEqFrequencyDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
case ModId::EGEqBandwidthDepth:
|
||||
return absl::StrCat("EGEqBandwidthDepth {", region_.number(), ", N=", 1 + params_.N, ", X=", 1 + params_.X, "}");
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
ModKey ModKey::getSourceDepthKey(ModKey source, ModKey target)
|
||||
{
|
||||
const NumericId<Region> region = source.region();
|
||||
const ModKey::Parameters& tp = target.parameters();
|
||||
|
||||
switch (source.id()) {
|
||||
case ModId::AmpLFO:
|
||||
switch (target.id()) {
|
||||
case ModId::Volume:
|
||||
return ModKey::createNXYZ(ModId::AmpLFODepth, region);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ModId::PitchLFO:
|
||||
switch (target.id()) {
|
||||
case ModId::Pitch:
|
||||
return ModKey::createNXYZ(ModId::PitchLFODepth, region);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ModId::FilLFO:
|
||||
switch (target.id()) {
|
||||
case ModId::FilCutoff:
|
||||
return ModKey::createNXYZ(ModId::FilLFODepth, region);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ModId::PitchEG:
|
||||
switch (target.id()) {
|
||||
case ModId::Pitch:
|
||||
return ModKey::createNXYZ(ModId::PitchEGDepth, region);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ModId::FilEG:
|
||||
switch (target.id()) {
|
||||
case ModId::FilCutoff:
|
||||
return ModKey::createNXYZ(ModId::FilEGDepth, region);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ModId::LFO:
|
||||
switch (target.id()) {
|
||||
case ModId::Amplitude:
|
||||
return ModKey::createNXYZ(ModId::LFOAmplitudeDepth, region, tp.N);
|
||||
case ModId::Pan:
|
||||
return ModKey::createNXYZ(ModId::LFOPanDepth, region, tp.N);
|
||||
case ModId::Width:
|
||||
return ModKey::createNXYZ(ModId::LFOWidthDepth, region, tp.N);
|
||||
case ModId::Position:
|
||||
return ModKey::createNXYZ(ModId::LFOPositionDepth, region, tp.N);
|
||||
case ModId::Pitch:
|
||||
return ModKey::createNXYZ(ModId::LFOPitchDepth, region, tp.N);
|
||||
case ModId::Volume:
|
||||
return ModKey::createNXYZ(ModId::LFOVolumeDepth, region, tp.N);
|
||||
case ModId::FilCutoff:
|
||||
return ModKey::createNXYZ(ModId::LFOFilCutoffDepth, region, tp.N, tp.X);
|
||||
case ModId::FilResonance:
|
||||
return ModKey::createNXYZ(ModId::LFOFilResonanceDepth, region, tp.N, tp.X);
|
||||
case ModId::FilGain:
|
||||
return ModKey::createNXYZ(ModId::LFOFilGainDepth, region, tp.N, tp.X);
|
||||
case ModId::EqGain:
|
||||
return ModKey::createNXYZ(ModId::LFOEqGainDepth, region, tp.N, tp.X);
|
||||
case ModId::EqFrequency:
|
||||
return ModKey::createNXYZ(ModId::LFOEqFrequencyDepth, region, tp.N, tp.X);
|
||||
case ModId::EqBandwidth:
|
||||
return ModKey::createNXYZ(ModId::LFOEqBandwidthDepth, region, tp.N, tp.X);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ModId::Envelope:
|
||||
switch (target.id()) {
|
||||
case ModId::Amplitude:
|
||||
return ModKey::createNXYZ(ModId::EGAmplitudeDepth, region, tp.N);
|
||||
case ModId::Pan:
|
||||
return ModKey::createNXYZ(ModId::EGPanDepth, region, tp.N);
|
||||
case ModId::Width:
|
||||
return ModKey::createNXYZ(ModId::EGWidthDepth, region, tp.N);
|
||||
case ModId::Position:
|
||||
return ModKey::createNXYZ(ModId::EGPositionDepth, region, tp.N);
|
||||
case ModId::Pitch:
|
||||
return ModKey::createNXYZ(ModId::EGPitchDepth, region, tp.N);
|
||||
case ModId::Volume:
|
||||
return ModKey::createNXYZ(ModId::EGVolumeDepth, region, tp.N);
|
||||
case ModId::FilCutoff:
|
||||
return ModKey::createNXYZ(ModId::EGFilCutoffDepth, region, tp.N, tp.X);
|
||||
case ModId::FilResonance:
|
||||
return ModKey::createNXYZ(ModId::EGFilResonanceDepth, region, tp.N, tp.X);
|
||||
case ModId::FilGain:
|
||||
return ModKey::createNXYZ(ModId::EGFilGainDepth, region, tp.N, tp.X);
|
||||
case ModId::EqGain:
|
||||
return ModKey::createNXYZ(ModId::EGEqGainDepth, region, tp.N, tp.X);
|
||||
case ModId::EqFrequency:
|
||||
return ModKey::createNXYZ(ModId::EGEqFrequencyDepth, region, tp.N, tp.X);
|
||||
case ModId::EqBandwidth:
|
||||
return ModKey::createNXYZ(ModId::EGEqBandwidthDepth, region, tp.N, tp.X);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace sfz
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ public:
|
|||
bool isTarget() const noexcept;
|
||||
std::string toString() const;
|
||||
|
||||
/**
|
||||
* @brief Obtain the modulation key of the source depth, in the connection
|
||||
* between source and target, if such a key exists.
|
||||
*/
|
||||
static ModKey getSourceDepthKey(ModKey source, ModKey target);
|
||||
|
||||
struct RawParameters {
|
||||
union {
|
||||
//! Parameters if this key identifies a CC source
|
||||
|
|
|
|||
|
|
@ -423,7 +423,12 @@ float* ModMatrix::getModulation(TargetId targetId)
|
|||
for (uint32_t i = 0; i < numFrames; ++i)
|
||||
buffer[i] = sourceDepth * sourceBuffer[i];
|
||||
}
|
||||
else if (targetFlags & kModIsMultiplicative) {
|
||||
for (uint32_t i = 0; i < numFrames; ++i)
|
||||
buffer[i] = (sourceDepth * sourceDepthMod[i]) * sourceBuffer[i];
|
||||
}
|
||||
else {
|
||||
ASSERT(targetFlags & kModIsAdditive);
|
||||
for (uint32_t i = 0; i < numFrames; ++i)
|
||||
buffer[i] = (sourceDepth + sourceDepthMod[i]) * sourceBuffer[i];
|
||||
}
|
||||
|
|
@ -435,7 +440,7 @@ float* ModMatrix::getModulation(TargetId targetId)
|
|||
multiplyMul1<float>(sourceDepth, sourceBuffer, buffer);
|
||||
else {
|
||||
for (uint32_t i = 0; i < numFrames; ++i)
|
||||
buffer[i] *= (sourceDepth + sourceDepthMod[i]) * sourceBuffer[i];
|
||||
buffer[i] *= (sourceDepth * sourceDepthMod[i]) * sourceBuffer[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue