Add pitcheg and fileg opcodes, and modulation key
This commit is contained in:
parent
23b7f50760
commit
0f2bb80434
6 changed files with 106 additions and 17 deletions
|
|
@ -1186,6 +1186,58 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
parseEGopcode(opcode, amplitudeEG);
|
parseEGopcode(opcode, amplitudeEG);
|
||||||
break;
|
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
|
// Flex envelopes
|
||||||
case hash("eg&_dynamic"):
|
case hash("eg&_dynamic"):
|
||||||
{
|
{
|
||||||
|
|
@ -1408,6 +1460,19 @@ bool sfz::Region::parseEGopcode(const Opcode& opcode, EGDescription& eg)
|
||||||
#undef case_any_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)
|
bool sfz::Region::processGenericCc(const Opcode& opcode, Range<float> range, const ModKey& target)
|
||||||
{
|
{
|
||||||
if (!opcode.isAnyCcN())
|
if (!opcode.isAnyCcN())
|
||||||
|
|
|
||||||
|
|
@ -266,6 +266,16 @@ struct Region {
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
bool parseEGopcode(const Opcode& opcode, EGDescription& eg);
|
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.
|
* @brief Process a generic CC opcode, and fill the modulation parameters.
|
||||||
*
|
*
|
||||||
|
|
@ -410,8 +420,8 @@ struct Region {
|
||||||
|
|
||||||
// Envelopes
|
// Envelopes
|
||||||
EGDescription amplitudeEG;
|
EGDescription amplitudeEG;
|
||||||
EGDescription pitchEG;
|
absl::optional<EGDescription> pitchEG;
|
||||||
EGDescription filterEG;
|
absl::optional<EGDescription> filterEG;
|
||||||
|
|
||||||
// Envelopes
|
// Envelopes
|
||||||
std::vector<FlexEGDescription> flexEGs;
|
std::vector<FlexEGDescription> flexEGs;
|
||||||
|
|
@ -431,7 +441,7 @@ struct Region {
|
||||||
struct Connection {
|
struct Connection {
|
||||||
ModKey source;
|
ModKey source;
|
||||||
ModKey target;
|
ModKey target;
|
||||||
float sourceDepth = 1.0f;
|
float sourceDepth = 0.0f;
|
||||||
};
|
};
|
||||||
std::vector<Connection> connections;
|
std::vector<Connection> connections;
|
||||||
Connection& getOrCreateConnection(const ModKey& source, const ModKey& target);
|
Connection& getOrCreateConnection(const ModKey& source, const ModKey& target);
|
||||||
|
|
|
||||||
|
|
@ -1702,20 +1702,24 @@ void sfz::Synth::updateUsedCCsFromRegion(std::bitset<sfz::config::numCCs>& usedC
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.amplitudeEG.ccHold);
|
updateUsedCCsFromCCMap(usedCCs, region.amplitudeEG.ccHold);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.amplitudeEG.ccStart);
|
updateUsedCCsFromCCMap(usedCCs, region.amplitudeEG.ccStart);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.amplitudeEG.ccSustain);
|
updateUsedCCsFromCCMap(usedCCs, region.amplitudeEG.ccSustain);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccAttack);
|
if (region.pitchEG) {
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccRelease);
|
updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccAttack);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccDecay);
|
updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccRelease);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccDelay);
|
updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccDecay);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccHold);
|
updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccDelay);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccStart);
|
updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccHold);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.pitchEG.ccSustain);
|
updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccStart);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccAttack);
|
updateUsedCCsFromCCMap(usedCCs, region.pitchEG->ccSustain);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccRelease);
|
}
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccDecay);
|
if (region.filterEG) {
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccDelay);
|
updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccAttack);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccHold);
|
updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccRelease);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccStart);
|
updateUsedCCsFromCCMap(usedCCs, region.filterEG->ccDecay);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.filterEG.ccSustain);
|
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.ccConditions);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.ccTriggers);
|
updateUsedCCsFromCCMap(usedCCs, region.ccTriggers);
|
||||||
updateUsedCCsFromCCMap(usedCCs, region.crossfadeCCInRange);
|
updateUsedCCsFromCCMap(usedCCs, region.crossfadeCCInRange);
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ int ModIds::flags(ModId id) noexcept
|
||||||
return kModIsPerVoice;
|
return kModIsPerVoice;
|
||||||
case ModId::LFO:
|
case ModId::LFO:
|
||||||
return kModIsPerVoice;
|
return kModIsPerVoice;
|
||||||
|
case ModId::PitchEG:
|
||||||
|
return kModIsPerVoice;
|
||||||
|
case ModId::FilEG:
|
||||||
|
return kModIsPerVoice;
|
||||||
|
|
||||||
// targets
|
// targets
|
||||||
case ModId::Amplitude:
|
case ModId::Amplitude:
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ enum class ModId : int {
|
||||||
Controller = _SourcesStart,
|
Controller = _SourcesStart,
|
||||||
Envelope,
|
Envelope,
|
||||||
LFO,
|
LFO,
|
||||||
|
PitchEG,
|
||||||
|
FilEG,
|
||||||
|
|
||||||
_SourcesEnd,
|
_SourcesEnd,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,10 @@ std::string ModKey::toString() const
|
||||||
return absl::StrCat("EG ", 1 + params_.N, " {", region_.number(), "}");
|
return absl::StrCat("EG ", 1 + params_.N, " {", region_.number(), "}");
|
||||||
case ModId::LFO:
|
case ModId::LFO:
|
||||||
return absl::StrCat("LFO ", 1 + params_.N, " {", region_.number(), "}");
|
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:
|
case ModId::Amplitude:
|
||||||
return absl::StrCat("Amplitude {", region_.number(), "}");
|
return absl::StrCat("Amplitude {", region_.number(), "}");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue