From 0f2bb804347e83aded33c3aa531084b77064387a Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Wed, 23 Sep 2020 22:41:12 +0200 Subject: [PATCH] Add pitcheg and fileg opcodes, and modulation key --- src/sfizz/Region.cpp | 65 ++++++++++++++++++++++++++++++++ src/sfizz/Region.h | 16 ++++++-- src/sfizz/Synth.cpp | 32 +++++++++------- src/sfizz/modulations/ModId.cpp | 4 ++ src/sfizz/modulations/ModId.h | 2 + src/sfizz/modulations/ModKey.cpp | 4 ++ 6 files changed, 106 insertions(+), 17 deletions(-) diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index a95734b6..7ca3e928 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -1186,6 +1186,58 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) parseEGopcode(opcode, amplitudeEG); break; + case hash("pitcheg_attack"): + case hash("pitcheg_decay"): + case hash("pitcheg_delay"): + case hash("pitcheg_hold"): + case hash("pitcheg_release"): + case hash("pitcheg_start"): + case hash("pitcheg_sustain"): + case hash("pitcheg_vel&attack"): + case hash("pitcheg_vel&decay"): + case hash("pitcheg_vel&delay"): + case hash("pitcheg_vel&hold"): + case hash("pitcheg_vel&release"): + case hash("pitcheg_vel&sustain"): + case hash("pitcheg_attack_oncc&"): // also pitcheg_attackcc& + case hash("pitcheg_decay_oncc&"): // also pitcheg_decaycc& + case hash("pitcheg_delay_oncc&"): // also pitcheg_delaycc& + case hash("pitcheg_hold_oncc&"): // also pitcheg_holdcc& + case hash("pitcheg_release_oncc&"): // also pitcheg_releasecc& + case hash("pitcheg_start_oncc&"): // also pitcheg_startcc& + case hash("pitcheg_sustain_oncc&"): // also pitcheg_sustaincc& + if (parseEGopcode(opcode, pitchEG)) + getOrCreateConnection( + ModKey::createNXYZ(ModId::PitchEG, id), + ModKey::createNXYZ(ModId::Pitch, id)); + break; + + case hash("fileg_attack"): + case hash("fileg_decay"): + case hash("fileg_delay"): + case hash("fileg_hold"): + case hash("fileg_release"): + case hash("fileg_start"): + case hash("fileg_sustain"): + case hash("fileg_vel&attack"): + case hash("fileg_vel&decay"): + case hash("fileg_vel&delay"): + case hash("fileg_vel&hold"): + case hash("fileg_vel&release"): + case hash("fileg_vel&sustain"): + case hash("fileg_attack_oncc&"): // also fileg_attackcc& + case hash("fileg_decay_oncc&"): // also fileg_decaycc& + case hash("fileg_delay_oncc&"): // also fileg_delaycc& + case hash("fileg_hold_oncc&"): // also fileg_holdcc& + case hash("fileg_release_oncc&"): // also fileg_releasecc& + case hash("fileg_start_oncc&"): // also fileg_startcc& + case hash("fileg_sustain_oncc&"): // also fileg_sustaincc& + if (parseEGopcode(opcode, filterEG)) + getOrCreateConnection( + ModKey::createNXYZ(ModId::FilEG, id), + ModKey::createNXYZ(ModId::FilCutoff, id)); + break; + // Flex envelopes case hash("eg&_dynamic"): { @@ -1408,6 +1460,19 @@ bool sfz::Region::parseEGopcode(const Opcode& opcode, EGDescription& eg) #undef case_any_eg } +bool sfz::Region::parseEGopcode(const Opcode& opcode, absl::optional& eg) +{ + bool create = eg == absl::nullopt; + if (create) + eg = EGDescription(); + + bool parsed = parseEGopcode(opcode, *eg); + if (!parsed && create) + eg = absl::nullopt; + + return parsed; +} + bool sfz::Region::processGenericCc(const Opcode& opcode, Range range, const ModKey& target) { if (!opcode.isAnyCcN()) diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index 59439b3d..6bb15849 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -266,6 +266,16 @@ struct Region { * @return false */ bool parseEGopcode(const Opcode& opcode, EGDescription& eg); + /** + * @brief Parse a opcode which is specific to a particular SFZv1 EG: + * ampeg, pitcheg, fileg. + * + * @param opcode + * @param eg + * @return true if the opcode was properly read and stored. + * @return false + */ + bool parseEGopcode(const Opcode& opcode, absl::optional& eg); /** * @brief Process a generic CC opcode, and fill the modulation parameters. * @@ -410,8 +420,8 @@ struct Region { // Envelopes EGDescription amplitudeEG; - EGDescription pitchEG; - EGDescription filterEG; + absl::optional pitchEG; + absl::optional filterEG; // Envelopes std::vector flexEGs; @@ -431,7 +441,7 @@ struct Region { struct Connection { ModKey source; ModKey target; - float sourceDepth = 1.0f; + float sourceDepth = 0.0f; }; std::vector connections; Connection& getOrCreateConnection(const ModKey& source, const ModKey& target); diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index c08dde96..c58340f8 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -1702,20 +1702,24 @@ void sfz::Synth::updateUsedCCsFromRegion(std::bitset& usedC updateUsedCCsFromCCMap(usedCCs, region.amplitudeEG.ccHold); updateUsedCCsFromCCMap(usedCCs, region.amplitudeEG.ccStart); updateUsedCCsFromCCMap(usedCCs, region.amplitudeEG.ccSustain); - updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccAttack); - updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccRelease); - updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccDecay); - updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccDelay); - updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccHold); - updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccStart); - updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccSustain); - updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccAttack); - updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccRelease); - updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccDecay); - updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccDelay); - updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccHold); - updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccStart); - updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccSustain); + if (region.pitchEG) { + updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccAttack); + updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccRelease); + updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccDecay); + updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccDelay); + updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccHold); + updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccStart); + updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccSustain); + } + if (region.filterEG) { + updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccAttack); + updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccRelease); + updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccDecay); + updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccDelay); + updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccHold); + updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccStart); + updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccSustain); + } updateUsedCCsFromCCMap(usedCCs, region.ccConditions); updateUsedCCsFromCCMap(usedCCs, region.ccTriggers); updateUsedCCsFromCCMap(usedCCs, region.crossfadeCCInRange); diff --git a/src/sfizz/modulations/ModId.cpp b/src/sfizz/modulations/ModId.cpp index f294a0bc..427d7511 100644 --- a/src/sfizz/modulations/ModId.cpp +++ b/src/sfizz/modulations/ModId.cpp @@ -30,6 +30,10 @@ int ModIds::flags(ModId id) noexcept return kModIsPerVoice; case ModId::LFO: return kModIsPerVoice; + case ModId::PitchEG: + return kModIsPerVoice; + case ModId::FilEG: + return kModIsPerVoice; // targets case ModId::Amplitude: diff --git a/src/sfizz/modulations/ModId.h b/src/sfizz/modulations/ModId.h index daf7f72f..ccd25b98 100644 --- a/src/sfizz/modulations/ModId.h +++ b/src/sfizz/modulations/ModId.h @@ -23,6 +23,8 @@ enum class ModId : int { Controller = _SourcesStart, Envelope, LFO, + PitchEG, + FilEG, _SourcesEnd, diff --git a/src/sfizz/modulations/ModKey.cpp b/src/sfizz/modulations/ModKey.cpp index efb6c8a0..80c3accb 100644 --- a/src/sfizz/modulations/ModKey.cpp +++ b/src/sfizz/modulations/ModKey.cpp @@ -74,6 +74,10 @@ std::string ModKey::toString() const return absl::StrCat("EG ", 1 + params_.N, " {", region_.number(), "}"); case ModId::LFO: return absl::StrCat("LFO ", 1 + params_.N, " {", region_.number(), "}"); + case ModId::PitchEG: + return absl::StrCat("PitchEG {", region_.number(), "}"); + case ModId::FilEG: + return absl::StrCat("FilterEG {", region_.number(), "}"); case ModId::Amplitude: return absl::StrCat("Amplitude {", region_.number(), "}");