Add pitcheg and fileg opcodes, and modulation key

This commit is contained in:
Jean Pierre Cimalando 2020-09-23 22:41:12 +02:00
parent 23b7f50760
commit 0f2bb80434
6 changed files with 106 additions and 17 deletions

View file

@ -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<EGDescription>& 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<float> range, const ModKey& target)
{
if (!opcode.isAnyCcN())

View file

@ -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<EGDescription>& 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<EGDescription> pitchEG;
absl::optional<EGDescription> filterEG;
// Envelopes
std::vector<FlexEGDescription> flexEGs;
@ -431,7 +441,7 @@ struct Region {
struct Connection {
ModKey source;
ModKey target;
float sourceDepth = 1.0f;
float sourceDepth = 0.0f;
};
std::vector<Connection> connections;
Connection& getOrCreateConnection(const ModKey& source, const ModKey& target);

View file

@ -1702,20 +1702,24 @@ void sfz::Synth::updateUsedCCsFromRegion(std::bitset<sfz::config::numCCs>& 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);

View file

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

View file

@ -23,6 +23,8 @@ enum class ModId : int {
Controller = _SourcesStart,
Envelope,
LFO,
PitchEG,
FilEG,
_SourcesEnd,

View file

@ -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(), "}");