Add vel2depth

This commit is contained in:
Jean Pierre Cimalando 2020-09-24 16:12:52 +02:00
parent 897477e140
commit 48ddb4ad60
5 changed files with 40 additions and 9 deletions

View file

@ -1251,8 +1251,22 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
ModKey::createNXYZ(ModId::FilCutoff, id)).sourceDepth = *value;
break;
// TODO(jpc): pitcheg_vel2depth
// TODO(jpc): fileg_vel2depth
case hash("pitcheg_vel&depth"):
if (opcode.parameters.front() != 2)
return false; // Was not vel2...
if (auto value = readOpcode(opcode.value, Default::pitchEgDepthRange))
getOrCreateConnection(
ModKey::createNXYZ(ModId::PitchEG, id),
ModKey::createNXYZ(ModId::Pitch, id)).velToDepth = *value;
break;
case hash("fileg_vel&depth"):
if (opcode.parameters.front() != 2)
return false; // Was not vel2...
if (auto value = readOpcode(opcode.value, Default::filterEgDepthRange))
getOrCreateConnection(
ModKey::createNXYZ(ModId::FilEG, id),
ModKey::createNXYZ(ModId::FilCutoff, id)).velToDepth = *value;
break;
// Flex envelopes
case hash("eg&_dynamic"):

View file

@ -442,6 +442,7 @@ struct Region {
ModKey source;
ModKey target;
float sourceDepth = 0.0f;
float velToDepth = 0.0f;
};
std::vector<Connection> connections;
Connection& getOrCreateConnection(const ModKey& source, const ModKey& target);

View file

@ -820,7 +820,7 @@ void sfz::Synth::renderBlock(AudioSpan<float> buffer) noexcept
if (voice->isFree())
continue;
mm.beginVoice(voice->getId(), voice->getRegion()->getId());
mm.beginVoice(voice->getId(), voice->getRegion()->getId(), voice->getTriggerEvent().value);
activeVoices++;
renderVoiceToOutputs(*voice, *tempSpan);
@ -1558,7 +1558,7 @@ void sfz::Synth::setupModMatrix()
continue;
}
if (!mm.connect(source, target, conn.sourceDepth)) {
if (!mm.connect(source, target, conn.sourceDepth, conn.velToDepth)) {
DBG("[sfizz] Failed to connect modulation source and target");
ASSERTFALSE;
}

View file

@ -27,6 +27,8 @@ struct ModMatrix::Impl {
NumericId<Voice> currentVoiceId_ {};
NumericId<Region> currentRegionId_ {};
float currentVoiceTriggerValue_ {};
struct Source {
ModKey key;
ModGenerator* gen {};
@ -36,6 +38,7 @@ struct ModMatrix::Impl {
struct ConnectionData {
float sourceDepth_ {};
float velToDepth_ {};
};
struct Target {
@ -190,7 +193,7 @@ ModMatrix::TargetId ModMatrix::findTarget(const ModKey& key) const
return TargetId(it->second);
}
bool ModMatrix::connect(SourceId sourceId, TargetId targetId, float sourceDepth)
bool ModMatrix::connect(SourceId sourceId, TargetId targetId, float sourceDepth, float velToDepth)
{
Impl& impl = *impl_;
unsigned sourceIndex = sourceId.number();
@ -202,6 +205,7 @@ bool ModMatrix::connect(SourceId sourceId, TargetId targetId, float sourceDepth)
Impl::Target& target = impl.targets_[targetIndex];
Impl::ConnectionData& conn = target.connectedSources[sourceIndex];
conn.sourceDepth_ = sourceDepth;
conn.velToDepth_ = velToDepth;
return true;
}
@ -302,13 +306,15 @@ void ModMatrix::endCycle()
impl.numFrames_ = 0;
}
void ModMatrix::beginVoice(NumericId<Voice> voiceId, NumericId<Region> regionId)
void ModMatrix::beginVoice(NumericId<Voice> voiceId, NumericId<Region> regionId, float triggerValue)
{
Impl& impl = *impl_;
impl.currentVoiceId_ = voiceId;
impl.currentRegionId_ = regionId;
impl.currentVoiceTriggerValue_ = triggerValue;
ASSERT(regionId);
const auto idNumber = static_cast<size_t>(regionId.number());
@ -345,6 +351,8 @@ void ModMatrix::endVoice()
impl.currentVoiceId_ = {};
impl.currentRegionId_ = {};
impl.currentVoiceTriggerValue_ = 0.0f;
}
float* ModMatrix::getModulation(TargetId targetId)
@ -354,6 +362,7 @@ float* ModMatrix::getModulation(TargetId targetId)
Impl& impl = *impl_;
const NumericId<Region> regionId = impl.currentRegionId_;
const float triggerValue = impl.currentVoiceTriggerValue_;
const uint32_t targetIndex = targetId.number();
Impl::Target &target = impl.targets_[targetIndex];
const int targetFlags = target.key.flags();
@ -381,7 +390,6 @@ float* ModMatrix::getModulation(TargetId targetId)
// then add or multiply, depending on target flags
while (sourcesPos != sourcesEnd) {
Impl::Source &source = impl.sources_[sourcesPos->first];
const float sourceDepth = sourcesPos->second.sourceDepth_;
const int sourceFlags = source.key.flags();
// only accept per-voice sources of the same region
@ -398,6 +406,12 @@ float* ModMatrix::getModulation(TargetId targetId)
source.bufferReady = true;
}
float sourceDepth = sourcesPos->second.sourceDepth_;
if (sourceFlags & kModIsPerVoice) {
const float velToDepth = sourcesPos->second.velToDepth_;
sourceDepth += triggerValue * velToDepth;
}
if (isFirstSource) {
if (sourceDepth != 1) {
for (uint32_t i = 0; i < numFrames; ++i)

View file

@ -92,9 +92,10 @@ public:
* @param sourceId source of the connection
* @param targetId target of the connection
* @param sourceDepth amount which multiplies the source output
* @param velToDepth amount which full velocity adds to the source depth
* @return true if the connection was successfully made, otherwise false
*/
bool connect(SourceId sourceId, TargetId targetId, float sourceDepth);
bool connect(SourceId sourceId, TargetId targetId, float sourceDepth, float velToDepth = 0.0f);
/**
* @brief Reinitialize modulation sources overall.
@ -134,8 +135,9 @@ public:
*
* @param voiceId the identifier of the current voice
* @param regionId the identifier of the region of the current voice
* @param triggerValue the velocity of the current voice
*/
void beginVoice(NumericId<Voice> voiceId, NumericId<Region> regionId);
void beginVoice(NumericId<Voice> voiceId, NumericId<Region> regionId, float triggerValue);
/**
* @brief End modulation processing for a given voice.