Add vel2depth
This commit is contained in:
parent
897477e140
commit
48ddb4ad60
5 changed files with 40 additions and 9 deletions
|
|
@ -1251,8 +1251,22 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
ModKey::createNXYZ(ModId::FilCutoff, id)).sourceDepth = *value;
|
ModKey::createNXYZ(ModId::FilCutoff, id)).sourceDepth = *value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// TODO(jpc): pitcheg_vel2depth
|
case hash("pitcheg_vel&depth"):
|
||||||
// TODO(jpc): fileg_vel2depth
|
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
|
// Flex envelopes
|
||||||
case hash("eg&_dynamic"):
|
case hash("eg&_dynamic"):
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,7 @@ struct Region {
|
||||||
ModKey source;
|
ModKey source;
|
||||||
ModKey target;
|
ModKey target;
|
||||||
float sourceDepth = 0.0f;
|
float sourceDepth = 0.0f;
|
||||||
|
float velToDepth = 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);
|
||||||
|
|
|
||||||
|
|
@ -820,7 +820,7 @@ void sfz::Synth::renderBlock(AudioSpan<float> buffer) noexcept
|
||||||
if (voice->isFree())
|
if (voice->isFree())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mm.beginVoice(voice->getId(), voice->getRegion()->getId());
|
mm.beginVoice(voice->getId(), voice->getRegion()->getId(), voice->getTriggerEvent().value);
|
||||||
|
|
||||||
activeVoices++;
|
activeVoices++;
|
||||||
renderVoiceToOutputs(*voice, *tempSpan);
|
renderVoiceToOutputs(*voice, *tempSpan);
|
||||||
|
|
@ -1558,7 +1558,7 @@ void sfz::Synth::setupModMatrix()
|
||||||
continue;
|
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");
|
DBG("[sfizz] Failed to connect modulation source and target");
|
||||||
ASSERTFALSE;
|
ASSERTFALSE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ struct ModMatrix::Impl {
|
||||||
NumericId<Voice> currentVoiceId_ {};
|
NumericId<Voice> currentVoiceId_ {};
|
||||||
NumericId<Region> currentRegionId_ {};
|
NumericId<Region> currentRegionId_ {};
|
||||||
|
|
||||||
|
float currentVoiceTriggerValue_ {};
|
||||||
|
|
||||||
struct Source {
|
struct Source {
|
||||||
ModKey key;
|
ModKey key;
|
||||||
ModGenerator* gen {};
|
ModGenerator* gen {};
|
||||||
|
|
@ -36,6 +38,7 @@ struct ModMatrix::Impl {
|
||||||
|
|
||||||
struct ConnectionData {
|
struct ConnectionData {
|
||||||
float sourceDepth_ {};
|
float sourceDepth_ {};
|
||||||
|
float velToDepth_ {};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Target {
|
struct Target {
|
||||||
|
|
@ -190,7 +193,7 @@ ModMatrix::TargetId ModMatrix::findTarget(const ModKey& key) const
|
||||||
return TargetId(it->second);
|
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_;
|
Impl& impl = *impl_;
|
||||||
unsigned sourceIndex = sourceId.number();
|
unsigned sourceIndex = sourceId.number();
|
||||||
|
|
@ -202,6 +205,7 @@ bool ModMatrix::connect(SourceId sourceId, TargetId targetId, float sourceDepth)
|
||||||
Impl::Target& target = impl.targets_[targetIndex];
|
Impl::Target& target = impl.targets_[targetIndex];
|
||||||
Impl::ConnectionData& conn = target.connectedSources[sourceIndex];
|
Impl::ConnectionData& conn = target.connectedSources[sourceIndex];
|
||||||
conn.sourceDepth_ = sourceDepth;
|
conn.sourceDepth_ = sourceDepth;
|
||||||
|
conn.velToDepth_ = velToDepth;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -302,13 +306,15 @@ void ModMatrix::endCycle()
|
||||||
impl.numFrames_ = 0;
|
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& impl = *impl_;
|
||||||
|
|
||||||
impl.currentVoiceId_ = voiceId;
|
impl.currentVoiceId_ = voiceId;
|
||||||
impl.currentRegionId_ = regionId;
|
impl.currentRegionId_ = regionId;
|
||||||
|
|
||||||
|
impl.currentVoiceTriggerValue_ = triggerValue;
|
||||||
|
|
||||||
ASSERT(regionId);
|
ASSERT(regionId);
|
||||||
|
|
||||||
const auto idNumber = static_cast<size_t>(regionId.number());
|
const auto idNumber = static_cast<size_t>(regionId.number());
|
||||||
|
|
@ -345,6 +351,8 @@ void ModMatrix::endVoice()
|
||||||
|
|
||||||
impl.currentVoiceId_ = {};
|
impl.currentVoiceId_ = {};
|
||||||
impl.currentRegionId_ = {};
|
impl.currentRegionId_ = {};
|
||||||
|
|
||||||
|
impl.currentVoiceTriggerValue_ = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float* ModMatrix::getModulation(TargetId targetId)
|
float* ModMatrix::getModulation(TargetId targetId)
|
||||||
|
|
@ -354,6 +362,7 @@ float* ModMatrix::getModulation(TargetId targetId)
|
||||||
|
|
||||||
Impl& impl = *impl_;
|
Impl& impl = *impl_;
|
||||||
const NumericId<Region> regionId = impl.currentRegionId_;
|
const NumericId<Region> regionId = impl.currentRegionId_;
|
||||||
|
const float triggerValue = impl.currentVoiceTriggerValue_;
|
||||||
const uint32_t targetIndex = targetId.number();
|
const uint32_t targetIndex = targetId.number();
|
||||||
Impl::Target &target = impl.targets_[targetIndex];
|
Impl::Target &target = impl.targets_[targetIndex];
|
||||||
const int targetFlags = target.key.flags();
|
const int targetFlags = target.key.flags();
|
||||||
|
|
@ -381,7 +390,6 @@ float* ModMatrix::getModulation(TargetId targetId)
|
||||||
// then add or multiply, depending on target flags
|
// then add or multiply, depending on target flags
|
||||||
while (sourcesPos != sourcesEnd) {
|
while (sourcesPos != sourcesEnd) {
|
||||||
Impl::Source &source = impl.sources_[sourcesPos->first];
|
Impl::Source &source = impl.sources_[sourcesPos->first];
|
||||||
const float sourceDepth = sourcesPos->second.sourceDepth_;
|
|
||||||
const int sourceFlags = source.key.flags();
|
const int sourceFlags = source.key.flags();
|
||||||
|
|
||||||
// only accept per-voice sources of the same region
|
// only accept per-voice sources of the same region
|
||||||
|
|
@ -398,6 +406,12 @@ float* ModMatrix::getModulation(TargetId targetId)
|
||||||
source.bufferReady = true;
|
source.bufferReady = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float sourceDepth = sourcesPos->second.sourceDepth_;
|
||||||
|
if (sourceFlags & kModIsPerVoice) {
|
||||||
|
const float velToDepth = sourcesPos->second.velToDepth_;
|
||||||
|
sourceDepth += triggerValue * velToDepth;
|
||||||
|
}
|
||||||
|
|
||||||
if (isFirstSource) {
|
if (isFirstSource) {
|
||||||
if (sourceDepth != 1) {
|
if (sourceDepth != 1) {
|
||||||
for (uint32_t i = 0; i < numFrames; ++i)
|
for (uint32_t i = 0; i < numFrames; ++i)
|
||||||
|
|
|
||||||
|
|
@ -92,9 +92,10 @@ public:
|
||||||
* @param sourceId source of the connection
|
* @param sourceId source of the connection
|
||||||
* @param targetId target of the connection
|
* @param targetId target of the connection
|
||||||
* @param sourceDepth amount which multiplies the source output
|
* @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
|
* @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.
|
* @brief Reinitialize modulation sources overall.
|
||||||
|
|
@ -134,8 +135,9 @@ public:
|
||||||
*
|
*
|
||||||
* @param voiceId the identifier of the current voice
|
* @param voiceId the identifier of the current voice
|
||||||
* @param regionId the identifier of the region 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.
|
* @brief End modulation processing for a given voice.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue