EG and LFO sources for the filters and EQs
This commit is contained in:
parent
fd8b00b9a1
commit
83cd4b6317
5 changed files with 1325 additions and 898 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -85,6 +85,7 @@ end_region_oncc:
|
||||||
egV1 = "ampeg"|"fileg"|"pitcheg";
|
egV1 = "ampeg"|"fileg"|"pitcheg";
|
||||||
eqV1 = "eq" number;
|
eqV1 = "eq" number;
|
||||||
lfoV2 = "lfo" number;
|
lfoV2 = "lfo" number;
|
||||||
|
egV2 = "eg" number;
|
||||||
|
|
||||||
(lfoV1) "_" ("depth"|"freq"|"fade") "cc" (number) END {
|
(lfoV1) "_" ("depth"|"freq"|"fade") "cc" (number) END {
|
||||||
opcode = absl::StrCat(group(1), "_", group(2), "_oncc", group(3));
|
opcode = absl::StrCat(group(1), "_", group(2), "_oncc", group(3));
|
||||||
|
|
@ -102,7 +103,14 @@ end_region_oncc:
|
||||||
opcode = absl::StrCat(group(1), "_", group(2), "1");
|
opcode = absl::StrCat(group(1), "_", group(2), "1");
|
||||||
goto end_region;
|
goto end_region;
|
||||||
}
|
}
|
||||||
|
(lfoV2) "_" ("cutoff"|"resonance") ("_" any)? END {
|
||||||
|
opcode = absl::StrCat(group(1), "_", group(2), "1", group(3));
|
||||||
|
goto end_region;
|
||||||
|
}
|
||||||
|
(egV2) "_" ("cutoff"|"resonance") ("_" any)? END {
|
||||||
|
opcode = absl::StrCat(group(1), "_", group(2), "1", group(3));
|
||||||
|
goto end_region;
|
||||||
|
}
|
||||||
"loop" ("mode"|"start"|"end") END {
|
"loop" ("mode"|"start"|"end") END {
|
||||||
opcode = absl::StrCat("loop_", group(1));
|
opcode = absl::StrCat("loop_", group(1));
|
||||||
goto end_region;
|
goto end_region;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,23 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
case hash(x "_stepcc&"): \
|
case hash(x "_stepcc&"): \
|
||||||
case hash(x "_smoothcc&")
|
case hash(x "_smoothcc&")
|
||||||
|
|
||||||
|
#define LFO_EG_filter_EQ_target(sourceKey, targetKey, range) \
|
||||||
|
{ \
|
||||||
|
const auto number = opcode.parameters.front(); \
|
||||||
|
if (number == 0) \
|
||||||
|
return false; \
|
||||||
|
\
|
||||||
|
const auto index = opcode.parameters.size() == 2 ? opcode.parameters.back() - 1 : 0; \
|
||||||
|
if (!extendIfNecessary(filters, index + 1, Default::numFilters)) \
|
||||||
|
return false; \
|
||||||
|
\
|
||||||
|
if (auto value = readOpcode(opcode.value, range)) { \
|
||||||
|
const ModKey source = ModKey::createNXYZ(sourceKey, id, number - 1); \
|
||||||
|
const ModKey target = ModKey::createNXYZ(targetKey, id, index); \
|
||||||
|
getOrCreateConnection(source, target).sourceDepth = *value; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
// Sound source: sample playback
|
// Sound source: sample playback
|
||||||
case hash("sample"):
|
case hash("sample"):
|
||||||
{
|
{
|
||||||
|
|
@ -1016,6 +1033,24 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case hash("lfo&_cutoff&"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::LFO, ModId::FilCutoff, Default::filterCutoffModRange);
|
||||||
|
break;
|
||||||
|
case hash("lfo&_resonance&"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::LFO, ModId::FilResonance, Default::filterResonanceModRange);
|
||||||
|
break;
|
||||||
|
case hash("lfo&_fil&_gain"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::LFO, ModId::FilGain, Default::filterGainModRange);
|
||||||
|
break;
|
||||||
|
case hash("lfo&_eq&gain"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::LFO, ModId::EqGain, Default::eqGainModRange);
|
||||||
|
break;
|
||||||
|
case hash("lfo&_eq&freq"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::LFO, ModId::EqFrequency, Default::eqFrequencyModRange);
|
||||||
|
break;
|
||||||
|
case hash("lfo&_eq&bw"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::LFO, ModId::EqBandwidth, Default::eqBandwidthModRange);
|
||||||
|
break;
|
||||||
|
|
||||||
// Modulation: Flex EG (targets)
|
// Modulation: Flex EG (targets)
|
||||||
case hash("eg&_amplitude"):
|
case hash("eg&_amplitude"):
|
||||||
|
|
@ -1090,6 +1125,24 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case hash("eg&_cutoff&"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::FilCutoff, Default::filterCutoffModRange);
|
||||||
|
break;
|
||||||
|
case hash("eg&_resonance&"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::FilResonance, Default::filterResonanceModRange);
|
||||||
|
break;
|
||||||
|
case hash("eg&_fil&_gain"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::FilGain, Default::filterGainModRange);
|
||||||
|
break;
|
||||||
|
case hash("eg&_eq&gain"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::EqGain, Default::eqGainModRange);
|
||||||
|
break;
|
||||||
|
case hash("eg&_eq&freq"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::EqFrequency, Default::eqFrequencyModRange);
|
||||||
|
break;
|
||||||
|
case hash("eg&_eq&bw"):
|
||||||
|
LFO_EG_filter_EQ_target(ModId::Envelope, ModId::EqBandwidth, Default::eqBandwidthModRange);
|
||||||
|
break;
|
||||||
|
|
||||||
// Amplitude Envelope
|
// Amplitude Envelope
|
||||||
case hash("ampeg_attack"):
|
case hash("ampeg_attack"):
|
||||||
|
|
@ -1292,6 +1345,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#undef case_any_ccN
|
#undef case_any_ccN
|
||||||
|
#undef LFO_EG_filter_EQ_target
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -88,17 +88,17 @@ std::string ModKey::toString() const
|
||||||
case ModId::Volume:
|
case ModId::Volume:
|
||||||
return absl::StrCat("Volume {", region_.number(), "}");
|
return absl::StrCat("Volume {", region_.number(), "}");
|
||||||
case ModId::FilGain:
|
case ModId::FilGain:
|
||||||
return absl::StrCat("FilterGain {", region_.number(), ", N=", params_.N, "}");
|
return absl::StrCat("FilterGain {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||||
case ModId::FilCutoff:
|
case ModId::FilCutoff:
|
||||||
return absl::StrCat("FilterCutoff {", region_.number(), ", N=", params_.N, "}");
|
return absl::StrCat("FilterCutoff {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||||
case ModId::FilResonance:
|
case ModId::FilResonance:
|
||||||
return absl::StrCat("FilterResonance {", region_.number(), ", N=", params_.N, "}");
|
return absl::StrCat("FilterResonance {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||||
case ModId::EqGain:
|
case ModId::EqGain:
|
||||||
return absl::StrCat("EqGain {", region_.number(), ", N=", params_.N, "}");
|
return absl::StrCat("EqGain {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||||
case ModId::EqFrequency:
|
case ModId::EqFrequency:
|
||||||
return absl::StrCat("EqFrequency {", region_.number(), ", N=", params_.N, "}");
|
return absl::StrCat("EqFrequency {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||||
case ModId::EqBandwidth:
|
case ModId::EqBandwidth:
|
||||||
return absl::StrCat("EqBandwidth {", region_.number(), ", N=", params_.N, "}");
|
return absl::StrCat("EqBandwidth {", region_.number(), ", N=", 1 + params_.N, "}");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
|
|
|
||||||
|
|
@ -112,9 +112,9 @@ TEST_CASE("[Modulations] Filter CC connections")
|
||||||
|
|
||||||
const std::string graph = synth.getResources().modMatrix.toDotGraph();
|
const std::string graph = synth.getResources().modMatrix.toDotGraph();
|
||||||
REQUIRE(graph == createReferenceGraph({
|
REQUIRE(graph == createReferenceGraph({
|
||||||
R"("Controller 1 {curve=0, smooth=10, value=2, step=0}" -> "FilterResonance {0, N=2}")",
|
R"("Controller 1 {curve=0, smooth=10, value=2, step=0}" -> "FilterResonance {0, N=3}")",
|
||||||
R"("Controller 2 {curve=2, smooth=0, value=100, step=0}" -> "FilterCutoff {0, N=1}")",
|
R"("Controller 2 {curve=2, smooth=0, value=100, step=0}" -> "FilterCutoff {0, N=2}")",
|
||||||
R"("Controller 3 {curve=0, smooth=0, value=5, step=0.5}" -> "FilterGain {0, N=0}")",
|
R"("Controller 3 {curve=0, smooth=0, value=5, step=0.5}" -> "FilterGain {0, N=1}")",
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,8 +130,104 @@ TEST_CASE("[Modulations] EQ CC connections")
|
||||||
|
|
||||||
const std::string graph = synth.getResources().modMatrix.toDotGraph();
|
const std::string graph = synth.getResources().modMatrix.toDotGraph();
|
||||||
REQUIRE(graph == createReferenceGraph({
|
REQUIRE(graph == createReferenceGraph({
|
||||||
R"("Controller 1 {curve=0, smooth=10, value=2, step=0}" -> "EqBandwidth {0, N=2}")",
|
R"("Controller 1 {curve=0, smooth=10, value=2, step=0}" -> "EqBandwidth {0, N=3}")",
|
||||||
R"("Controller 2 {curve=0, smooth=0, value=5, step=0.5}" -> "EqGain {0, N=0}")",
|
R"("Controller 2 {curve=0, smooth=0, value=5, step=0.5}" -> "EqGain {0, N=1}")",
|
||||||
R"("Controller 3 {curve=3, smooth=0, value=300, step=0}" -> "EqFrequency {0, N=1}")",
|
R"("Controller 3 {curve=3, smooth=0, value=300, step=0}" -> "EqFrequency {0, N=2}")",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Modulations] LFO Filter connections")
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
synth.loadSfzString("/modulation.sfz", R"(
|
||||||
|
<region> sample=*sine
|
||||||
|
lfo1_freq=0.1 lfo1_cutoff1=1
|
||||||
|
lfo2_freq=1 lfo2_cutoff=2
|
||||||
|
lfo3_freq=2 lfo3_resonance=3
|
||||||
|
lfo4_freq=0.5 lfo4_resonance1=4
|
||||||
|
lfo5_freq=0.5 lfo5_resonance2=5
|
||||||
|
lfo6_freq=3 lfo6_fil1_gain=-1
|
||||||
|
)");
|
||||||
|
|
||||||
|
const std::string graph = synth.getResources().modMatrix.toDotGraph();
|
||||||
|
REQUIRE(graph == createReferenceGraph({
|
||||||
|
R"("LFO 1 {0}" -> "FilterCutoff {0, N=1}")",
|
||||||
|
R"("LFO 2 {0}" -> "FilterCutoff {0, N=1}")",
|
||||||
|
R"("LFO 3 {0}" -> "FilterResonance {0, N=1}")",
|
||||||
|
R"("LFO 4 {0}" -> "FilterResonance {0, N=1}")",
|
||||||
|
R"("LFO 5 {0}" -> "FilterResonance {0, N=2}")",
|
||||||
|
R"("LFO 6 {0}" -> "FilterGain {0, N=1}")",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Modulations] EG Filter connections")
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
synth.loadSfzString("/modulation.sfz", R"(
|
||||||
|
<region> sample=*sine
|
||||||
|
eg1_time1=0.1 eg1_cutoff1=1
|
||||||
|
eg2_time1=1 eg2_cutoff=2
|
||||||
|
eg3_time1=2 eg3_resonance=3
|
||||||
|
eg4_time1=0.5 eg4_resonance1=4
|
||||||
|
eg5_time1=0.5 eg5_resonance2=5
|
||||||
|
eg6_time1=3 eg6_fil1_gain=-1
|
||||||
|
)");
|
||||||
|
|
||||||
|
const std::string graph = synth.getResources().modMatrix.toDotGraph();
|
||||||
|
REQUIRE(graph == createReferenceGraph({
|
||||||
|
R"("EG 1 {0}" -> "FilterCutoff {0, N=1}")",
|
||||||
|
R"("EG 2 {0}" -> "FilterCutoff {0, N=1}")",
|
||||||
|
R"("EG 3 {0}" -> "FilterResonance {0, N=1}")",
|
||||||
|
R"("EG 4 {0}" -> "FilterResonance {0, N=1}")",
|
||||||
|
R"("EG 5 {0}" -> "FilterResonance {0, N=2}")",
|
||||||
|
R"("EG 6 {0}" -> "FilterGain {0, N=1}")",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Modulations] LFO EQ connections")
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
synth.loadSfzString("/modulation.sfz", R"(
|
||||||
|
<region> sample=*sine
|
||||||
|
lfo1_freq=0.1 lfo1_eq1bw=1
|
||||||
|
lfo2_freq=1 lfo2_eq2freq=2
|
||||||
|
lfo3_freq=2 lfo3_eq3gain=3
|
||||||
|
lfo4_freq=0.5 lfo4_eq3bw=4
|
||||||
|
lfo5_freq=0.5 lfo5_eq2gain=5
|
||||||
|
lfo6_freq=3 lfo6_eq1freq=-1
|
||||||
|
)");
|
||||||
|
|
||||||
|
const std::string graph = synth.getResources().modMatrix.toDotGraph();
|
||||||
|
REQUIRE(graph == createReferenceGraph({
|
||||||
|
R"("LFO 1 {0}" -> "EqBandwidth {0, N=1}")",
|
||||||
|
R"("LFO 2 {0}" -> "EqFrequency {0, N=2}")",
|
||||||
|
R"("LFO 3 {0}" -> "EqGain {0, N=3}")",
|
||||||
|
R"("LFO 4 {0}" -> "EqBandwidth {0, N=3}")",
|
||||||
|
R"("LFO 5 {0}" -> "EqGain {0, N=2}")",
|
||||||
|
R"("LFO 6 {0}" -> "EqFrequency {0, N=1}")",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Modulations] EG EQ connections")
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
synth.loadSfzString("/modulation.sfz", R"(
|
||||||
|
<region> sample=*sine
|
||||||
|
eg1_freq=0.1 eg1_eq1bw=1
|
||||||
|
eg2_freq=1 eg2_eq2freq=2
|
||||||
|
eg3_freq=2 eg3_eq3gain=3
|
||||||
|
eg4_freq=0.5 eg4_eq3bw=4
|
||||||
|
eg5_freq=0.5 eg5_eq2gain=5
|
||||||
|
eg6_freq=3 eg6_eq1freq=-1
|
||||||
|
)");
|
||||||
|
|
||||||
|
const std::string graph = synth.getResources().modMatrix.toDotGraph();
|
||||||
|
REQUIRE(graph == createReferenceGraph({
|
||||||
|
R"("EG 1 {0}" -> "EqBandwidth {0, N=1}")",
|
||||||
|
R"("EG 2 {0}" -> "EqFrequency {0, N=2}")",
|
||||||
|
R"("EG 3 {0}" -> "EqGain {0, N=3}")",
|
||||||
|
R"("EG 4 {0}" -> "EqBandwidth {0, N=3}")",
|
||||||
|
R"("EG 5 {0}" -> "EqGain {0, N=2}")",
|
||||||
|
R"("EG 6 {0}" -> "EqFrequency {0, N=1}")",
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue