From 11d5abe435e7ec7a90673fb36bbe5540c7f00a97 Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Thu, 10 Sep 2020 01:00:44 +0200 Subject: [PATCH 1/8] Precompute targets for the modulation on voice start --- src/sfizz/Voice.cpp | 33 +++++++++++++++++++-------------- src/sfizz/Voice.h | 13 +++++++++++++ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 8647de86..b19c6cb5 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -144,6 +144,7 @@ void sfz::Voice::startVoice(Region* region, int delay, const TriggerEvent& event egEnvelope.reset(region->amplitudeEG, *region, resources.midiState, delay, triggerEvent.value, sampleRate); resources.modMatrix.initVoice(id, region->getId(), delay); + saveModulationTargets(region); } int sfz::Voice::getCurrentSampleQuality() const noexcept @@ -370,22 +371,20 @@ void sfz::Voice::amplitudeEnvelope(absl::Span modulationSpan) noexcept const auto numSamples = modulationSpan.size(); ModMatrix& mm = resources.modMatrix; - const ModKey volumeKey = ModKey::createNXYZ(ModId::Volume, region->getId()); - const ModKey amplitudeKey = ModKey::createNXYZ(ModId::Amplitude, region->getId()); // AmpEG envelope egEnvelope.getBlock(modulationSpan); // Amplitude envelope applyGain1(baseGain, modulationSpan); - if (float* mod = mm.getModulationByKey(amplitudeKey)) { + if (float* mod = mm.getModulation(amplitudeTarget)) { for (size_t i = 0; i < numSamples; ++i) modulationSpan[i] *= normalizePercents(mod[i]); } // Volume envelope applyGain1(db2mag(baseVolumedB), modulationSpan); - if (float* mod = mm.getModulationByKey(volumeKey)) { + if (float* mod = mm.getModulation(volumeTarget)) { for (size_t i = 0; i < numSamples; ++i) modulationSpan[i] *= db2mag(mod[i]); } @@ -437,14 +436,13 @@ void sfz::Voice::panStageMono(AudioSpan buffer) noexcept return; ModMatrix& mm = resources.modMatrix; - const ModKey panKey = ModKey::createNXYZ(ModId::Pan, region->getId()); // Prepare for stereo output copy(leftBuffer, rightBuffer); // Apply panning fill(*modulationSpan, region->pan); - if (float* mod = mm.getModulationByKey(panKey)) { + if (float* mod = mm.getModulation(panTarget)) { for (size_t i = 0; i < numSamples; ++i) (*modulationSpan)[i] += normalizePercents(mod[i]); } @@ -463,13 +461,10 @@ void sfz::Voice::panStageStereo(AudioSpan buffer) noexcept return; ModMatrix& mm = resources.modMatrix; - const ModKey panKey = ModKey::createNXYZ(ModId::Pan, region->getId()); - const ModKey widthKey = ModKey::createNXYZ(ModId::Width, region->getId()); - const ModKey positionKey = ModKey::createNXYZ(ModId::Position, region->getId()); // Apply panning fill(*modulationSpan, region->pan); - if (float* mod = mm.getModulationByKey(panKey)) { + if (float* mod = mm.getModulation(panTarget)) { for (size_t i = 0; i < numSamples; ++i) (*modulationSpan)[i] += normalizePercents(mod[i]); } @@ -477,14 +472,14 @@ void sfz::Voice::panStageStereo(AudioSpan buffer) noexcept // Apply the width/position process fill(*modulationSpan, region->width); - if (float* mod = mm.getModulationByKey(widthKey)) { + if (float* mod = mm.getModulation(widthTarget)) { for (size_t i = 0; i < numSamples; ++i) (*modulationSpan)[i] += normalizePercents(mod[i]); } width(*modulationSpan, leftBuffer, rightBuffer); fill(*modulationSpan, region->position); - if (float* mod = mm.getModulationByKey(positionKey)) { + if (float* mod = mm.getModulation(positionTarget)) { for (size_t i = 0; i < numSamples; ++i) (*modulationSpan)[i] += normalizePercents(mod[i]); } @@ -889,9 +884,8 @@ void sfz::Voice::pitchEnvelope(absl::Span pitchSpan) noexcept applyGain(*bends, pitchSpan); ModMatrix& mm = resources.modMatrix; - const ModKey pitchKey = ModKey::createNXYZ(ModId::Pitch, region->getId()); - if (float* mod = mm.getModulationByKey(pitchKey)) { + if (float* mod = mm.getModulation(pitchTarget)) { for (size_t i = 0; i < numFrames; ++i) pitchSpan[i] *= centsFactor(mod[i]); } @@ -902,3 +896,14 @@ void sfz::Voice::resetSmoothers() noexcept bendSmoother.reset(1.0f); gainSmoother.reset(0.0f); } + +void sfz::Voice::saveModulationTargets(const Region* region) noexcept +{ + ModMatrix& mm = resources.modMatrix; + amplitudeTarget = mm.findTarget(ModKey::createNXYZ(ModId::Amplitude, region->getId())); + volumeTarget = mm.findTarget(ModKey::createNXYZ(ModId::Volume, region->getId())); + panTarget = mm.findTarget(ModKey::createNXYZ(ModId::Pan, region->getId())); + positionTarget = mm.findTarget(ModKey::createNXYZ(ModId::Position, region->getId())); + widthTarget = mm.findTarget(ModKey::createNXYZ(ModId::Width, region->getId())); + pitchTarget = mm.findTarget(ModKey::createNXYZ(ModId::Pitch, region->getId())); +} diff --git a/src/sfizz/Voice.h b/src/sfizz/Voice.h index c8ebb0c8..10e0df2a 100644 --- a/src/sfizz/Voice.h +++ b/src/sfizz/Voice.h @@ -406,6 +406,12 @@ private: */ void switchState(State s); + /** + * @brief Save the modulation targets to avoid recomputing them in every callback. + * Must be called during startVoice() ideally. + */ + void saveModulationTargets(const Region* region) noexcept; + const NumericId id; StateListener* stateListener = nullptr; @@ -466,6 +472,13 @@ private: Smoother xfadeSmoother; void resetSmoothers() noexcept; + ModMatrix::TargetId amplitudeTarget; + ModMatrix::TargetId volumeTarget; + ModMatrix::TargetId panTarget; + ModMatrix::TargetId positionTarget; + ModMatrix::TargetId widthTarget; + ModMatrix::TargetId pitchTarget; + PowerFollower powerFollower; LEAK_DETECTOR(Voice); From ba53028d8dcbc00b3eafcab26b6bc22bd7b8924d Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Wed, 9 Sep 2020 17:43:26 +0200 Subject: [PATCH 2/8] Store shortcuts from the region id to the source and targets in the MM --- src/sfizz/modulations/ModMatrix.cpp | 82 ++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index a8c1f8fe..4c9295f0 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -49,6 +49,10 @@ struct ModMatrix::Impl { absl::flat_hash_map sourceIndex_; absl::flat_hash_map targetIndex_; + int maxRegionIdx { -1 }; + std::vector> sourceRegionIndex_; + std::vector> targetRegionIndex_; + std::vector sources_; std::vector targets_; }; @@ -72,6 +76,9 @@ void ModMatrix::clear() impl.targetIndex_.clear(); impl.sources_.clear(); impl.targets_.clear(); + impl.sourceRegionIndex_.clear(); + impl.targetRegionIndex_.clear(); + impl.maxRegionIdx = -1; } void ModMatrix::setSampleRate(double sampleRate) @@ -124,6 +131,8 @@ ModMatrix::SourceId ModMatrix::registerSource(const ModKey& key, ModGenerator& g source.buffer.resize(impl.samplesPerBlock_); impl.sourceIndex_[key] = id.number(); + if (key.region().number() > impl.maxRegionIdx) + impl.maxRegionIdx = key.region().number(); gen.setSampleRate(impl.sampleRate_); gen.setSamplesPerBlock(impl.samplesPerBlock_); @@ -148,6 +157,9 @@ ModMatrix::TargetId ModMatrix::registerTarget(const ModKey& key) target.buffer.resize(impl.samplesPerBlock_); impl.targetIndex_[key] = id.number(); + if (key.region().number() > impl.maxRegionIdx) + impl.maxRegionIdx = key.region().number(); + return id; } @@ -193,20 +205,39 @@ void ModMatrix::init() { Impl& impl = *impl_; - for (Impl::Source &source : impl.sources_) { - const int flags = source.key.flags(); - if (flags & kModIsPerCycle) + if (impl.maxRegionIdx >= 0) { + const size_t numRegions = impl.maxRegionIdx + 1; + impl.sourceRegionIndex_.resize(numRegions); + impl.targetRegionIndex_.resize(numRegions); + } + + for (unsigned i = 0; i < impl.sources_.size(); ++i) { + Impl::Source& source = impl.sources_[i]; + if (source.key.flags() & kModIsPerCycle) source.gen->init(source.key, {}, 0); + + if (source.key.region().number() >= 0) { + impl.sourceRegionIndex_[source.key.region().number()].push_back(i); + } + } + + for (unsigned i = 0; i < impl.targets_.size(); ++i) { + Impl::Target& target = impl.targets_[i]; + if (target.key.region().number() >= 0) + impl.targetRegionIndex_[target.key.region().number()].push_back(i); } } void ModMatrix::initVoice(NumericId voiceId, NumericId regionId, unsigned delay) { Impl& impl = *impl_; + ASSERT(regionId.number() >= 0); + ASSERT(static_cast(regionId.number()) < impl.sourceRegionIndex_.size()); - for (Impl::Source &source : impl.sources_) { - const int flags = source.key.flags(); - if ((flags & kModIsPerVoice) && source.key.region() == regionId) + const auto idNumber = static_cast(regionId.number()); + for (auto idx: impl.sourceRegionIndex_[idNumber]) { + const auto& source = impl.sources_[idx]; + if (source.key.flags() & kModIsPerVoice) source.gen->init(source.key, voiceId, delay); } } @@ -215,9 +246,12 @@ void ModMatrix::releaseVoice(NumericId voiceId, NumericId regionI { Impl& impl = *impl_; - for (Impl::Source &source : impl.sources_) { - const int flags = source.key.flags(); - if ((flags & kModIsPerVoice) && source.key.region() == regionId) + ASSERT(regionId.number() >= 0); + + const auto idNumber = static_cast(regionId.number()); + for (auto idx: impl.sourceRegionIndex_[idNumber]) { + const auto& source = impl.sources_[idx]; + if (source.key.flags() & kModIsPerVoice) source.gen->release(source.key, voiceId, delay); } } @@ -241,8 +275,7 @@ void ModMatrix::endCycle() for (Impl::Source &source : impl.sources_) { if (!source.bufferReady) { - const int flags = source.key.flags(); - if (flags & kModIsPerCycle) { + if (source.key.flags() & kModIsPerCycle) { absl::Span buffer(source.buffer.data(), numFrames); source.gen->generateDiscarded(source.key, {}, buffer); } @@ -259,14 +292,18 @@ void ModMatrix::beginVoice(NumericId voiceId, NumericId regionId) impl.currentVoiceId_ = voiceId; impl.currentRegionId_ = regionId; - for (Impl::Source &source : impl.sources_) { - const int flags = source.key.flags(); - if (flags & kModIsPerVoice) + ASSERT(regionId.number() >= 0); + + const auto idNumber = static_cast(regionId.number()); + for (auto idx: impl.sourceRegionIndex_[idNumber]) { + auto& source = impl.sources_[idx]; + if (source.key.flags() & kModIsPerVoice) source.bufferReady = false; } - for (Impl::Target &target : impl.targets_) { - const int flags = target.key.flags(); - if (flags & kModIsPerVoice) + + for (auto idx: impl.targetRegionIndex_[idNumber]) { + auto& target = impl.targets_[idx]; + if (target.key.flags() & kModIsPerVoice) target.bufferReady = false; } } @@ -278,10 +315,15 @@ void ModMatrix::endVoice() const NumericId voiceId = impl.currentVoiceId_; const NumericId regionId = impl.currentRegionId_; - for (Impl::Source &source : impl.sources_) { + ASSERT(regionId.number() >= 0); + ASSERT(static_cast(regionId.number()) < impl.sourceRegionIndex_.size()); + + const auto idNumber = static_cast(regionId.number()); + + for (auto idx: impl.sourceRegionIndex_[idNumber]) { + const auto& source = impl.sources_[idx]; if (!source.bufferReady) { - const int flags = source.key.flags(); - if ((flags & kModIsPerVoice) && source.key.region() == regionId) { + if (source.key.flags() & kModIsPerVoice) { absl::Span buffer(source.buffer.data(), numFrames); source.gen->generateDiscarded(source.key, voiceId, buffer); } From c91c653d8aa4bec99c5c82bf577c07ef03a01232 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 11 Sep 2020 17:47:24 +0200 Subject: [PATCH 3/8] Use the operator bool of NumericId --- src/sfizz/modulations/ModMatrix.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index 4c9295f0..a9ca3a38 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -216,14 +216,14 @@ void ModMatrix::init() if (source.key.flags() & kModIsPerCycle) source.gen->init(source.key, {}, 0); - if (source.key.region().number() >= 0) { + if (source.key.region()) { impl.sourceRegionIndex_[source.key.region().number()].push_back(i); } } for (unsigned i = 0; i < impl.targets_.size(); ++i) { Impl::Target& target = impl.targets_[i]; - if (target.key.region().number() >= 0) + if (target.key.region()) impl.targetRegionIndex_[target.key.region().number()].push_back(i); } } @@ -231,7 +231,7 @@ void ModMatrix::init() void ModMatrix::initVoice(NumericId voiceId, NumericId regionId, unsigned delay) { Impl& impl = *impl_; - ASSERT(regionId.number() >= 0); + ASSERT(regionId); ASSERT(static_cast(regionId.number()) < impl.sourceRegionIndex_.size()); const auto idNumber = static_cast(regionId.number()); @@ -246,7 +246,7 @@ void ModMatrix::releaseVoice(NumericId voiceId, NumericId regionI { Impl& impl = *impl_; - ASSERT(regionId.number() >= 0); + ASSERT(regionId); const auto idNumber = static_cast(regionId.number()); for (auto idx: impl.sourceRegionIndex_[idNumber]) { @@ -292,7 +292,7 @@ void ModMatrix::beginVoice(NumericId voiceId, NumericId regionId) impl.currentVoiceId_ = voiceId; impl.currentRegionId_ = regionId; - ASSERT(regionId.number() >= 0); + ASSERT(regionId); const auto idNumber = static_cast(regionId.number()); for (auto idx: impl.sourceRegionIndex_[idNumber]) { @@ -315,7 +315,7 @@ void ModMatrix::endVoice() const NumericId voiceId = impl.currentVoiceId_; const NumericId regionId = impl.currentRegionId_; - ASSERT(regionId.number() >= 0); + ASSERT(regionId); ASSERT(static_cast(regionId.number()) < impl.sourceRegionIndex_.size()); const auto idNumber = static_cast(regionId.number()); From 9c5f9537fad69da276179b8dc48696add5156743 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 11 Sep 2020 17:51:05 +0200 Subject: [PATCH 4/8] Adopt the underscore convention for member variables --- src/sfizz/modulations/ModMatrix.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index a9ca3a38..a60397c8 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -49,7 +49,7 @@ struct ModMatrix::Impl { absl::flat_hash_map sourceIndex_; absl::flat_hash_map targetIndex_; - int maxRegionIdx { -1 }; + int maxRegionIdx_ { -1 }; std::vector> sourceRegionIndex_; std::vector> targetRegionIndex_; @@ -78,7 +78,7 @@ void ModMatrix::clear() impl.targets_.clear(); impl.sourceRegionIndex_.clear(); impl.targetRegionIndex_.clear(); - impl.maxRegionIdx = -1; + impl.maxRegionIdx_ = -1; } void ModMatrix::setSampleRate(double sampleRate) @@ -131,8 +131,8 @@ ModMatrix::SourceId ModMatrix::registerSource(const ModKey& key, ModGenerator& g source.buffer.resize(impl.samplesPerBlock_); impl.sourceIndex_[key] = id.number(); - if (key.region().number() > impl.maxRegionIdx) - impl.maxRegionIdx = key.region().number(); + if (key.region().number() > impl.maxRegionIdx_) + impl.maxRegionIdx_ = key.region().number(); gen.setSampleRate(impl.sampleRate_); gen.setSamplesPerBlock(impl.samplesPerBlock_); @@ -157,8 +157,8 @@ ModMatrix::TargetId ModMatrix::registerTarget(const ModKey& key) target.buffer.resize(impl.samplesPerBlock_); impl.targetIndex_[key] = id.number(); - if (key.region().number() > impl.maxRegionIdx) - impl.maxRegionIdx = key.region().number(); + if (key.region().number() > impl.maxRegionIdx_) + impl.maxRegionIdx_ = key.region().number(); return id; } @@ -205,8 +205,8 @@ void ModMatrix::init() { Impl& impl = *impl_; - if (impl.maxRegionIdx >= 0) { - const size_t numRegions = impl.maxRegionIdx + 1; + if (impl.maxRegionIdx_ >= 0) { + const size_t numRegions = impl.maxRegionIdx_ + 1; impl.sourceRegionIndex_.resize(numRegions); impl.targetRegionIndex_.resize(numRegions); } From 0fd5ec57ab494adb931c830efa7421e2303d8b5a Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 11 Sep 2020 17:52:24 +0200 Subject: [PATCH 5/8] Rename the variable to make it clearer what it is --- src/sfizz/modulations/ModMatrix.cpp | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index a60397c8..7365c2eb 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -50,8 +50,8 @@ struct ModMatrix::Impl { absl::flat_hash_map targetIndex_; int maxRegionIdx_ { -1 }; - std::vector> sourceRegionIndex_; - std::vector> targetRegionIndex_; + std::vector> sourceIndicesForRegion_; + std::vector> targetIndicesForRegion_; std::vector sources_; std::vector targets_; @@ -76,8 +76,8 @@ void ModMatrix::clear() impl.targetIndex_.clear(); impl.sources_.clear(); impl.targets_.clear(); - impl.sourceRegionIndex_.clear(); - impl.targetRegionIndex_.clear(); + impl.sourceIndicesForRegion_.clear(); + impl.targetIndicesForRegion_.clear(); impl.maxRegionIdx_ = -1; } @@ -207,8 +207,8 @@ void ModMatrix::init() if (impl.maxRegionIdx_ >= 0) { const size_t numRegions = impl.maxRegionIdx_ + 1; - impl.sourceRegionIndex_.resize(numRegions); - impl.targetRegionIndex_.resize(numRegions); + impl.sourceIndicesForRegion_.resize(numRegions); + impl.targetIndicesForRegion_.resize(numRegions); } for (unsigned i = 0; i < impl.sources_.size(); ++i) { @@ -217,14 +217,14 @@ void ModMatrix::init() source.gen->init(source.key, {}, 0); if (source.key.region()) { - impl.sourceRegionIndex_[source.key.region().number()].push_back(i); + impl.sourceIndicesForRegion_[source.key.region().number()].push_back(i); } } for (unsigned i = 0; i < impl.targets_.size(); ++i) { Impl::Target& target = impl.targets_[i]; if (target.key.region()) - impl.targetRegionIndex_[target.key.region().number()].push_back(i); + impl.targetIndicesForRegion_[target.key.region().number()].push_back(i); } } @@ -232,10 +232,10 @@ void ModMatrix::initVoice(NumericId voiceId, NumericId regionId, { Impl& impl = *impl_; ASSERT(regionId); - ASSERT(static_cast(regionId.number()) < impl.sourceRegionIndex_.size()); + ASSERT(static_cast(regionId.number()) < impl.sourceIndicesForRegion_.size()); const auto idNumber = static_cast(regionId.number()); - for (auto idx: impl.sourceRegionIndex_[idNumber]) { + for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { const auto& source = impl.sources_[idx]; if (source.key.flags() & kModIsPerVoice) source.gen->init(source.key, voiceId, delay); @@ -249,7 +249,7 @@ void ModMatrix::releaseVoice(NumericId voiceId, NumericId regionI ASSERT(regionId); const auto idNumber = static_cast(regionId.number()); - for (auto idx: impl.sourceRegionIndex_[idNumber]) { + for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { const auto& source = impl.sources_[idx]; if (source.key.flags() & kModIsPerVoice) source.gen->release(source.key, voiceId, delay); @@ -295,13 +295,13 @@ void ModMatrix::beginVoice(NumericId voiceId, NumericId regionId) ASSERT(regionId); const auto idNumber = static_cast(regionId.number()); - for (auto idx: impl.sourceRegionIndex_[idNumber]) { + for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { auto& source = impl.sources_[idx]; if (source.key.flags() & kModIsPerVoice) source.bufferReady = false; } - for (auto idx: impl.targetRegionIndex_[idNumber]) { + for (auto idx: impl.targetIndicesForRegion_[idNumber]) { auto& target = impl.targets_[idx]; if (target.key.flags() & kModIsPerVoice) target.bufferReady = false; @@ -316,11 +316,11 @@ void ModMatrix::endVoice() const NumericId regionId = impl.currentRegionId_; ASSERT(regionId); - ASSERT(static_cast(regionId.number()) < impl.sourceRegionIndex_.size()); + ASSERT(static_cast(regionId.number()) < impl.sourceIndicesForRegion_.size()); const auto idNumber = static_cast(regionId.number()); - for (auto idx: impl.sourceRegionIndex_[idNumber]) { + for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { const auto& source = impl.sources_[idx]; if (!source.bufferReady) { if (source.key.flags() & kModIsPerVoice) { From aaa51f6dfe3e5c6bbb3d90427e91e898204f2bab Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 11 Sep 2020 17:56:42 +0200 Subject: [PATCH 6/8] Use the flags, and assert key to be valid with said flags --- src/sfizz/modulations/ModMatrix.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index 7365c2eb..68501b40 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -213,18 +213,24 @@ void ModMatrix::init() for (unsigned i = 0; i < impl.sources_.size(); ++i) { Impl::Source& source = impl.sources_[i]; - if (source.key.flags() & kModIsPerCycle) + const int flags = source.key.flags(); + if (flags & kModIsPerCycle) { + ASSERT(!source.key.region()); source.gen->init(source.key, {}, 0); - - if (source.key.region()) { + } + else if (flags & kModIsPerVoice) { + ASSERT(source.key.region()); impl.sourceIndicesForRegion_[source.key.region().number()].push_back(i); } } for (unsigned i = 0; i < impl.targets_.size(); ++i) { Impl::Target& target = impl.targets_[i]; - if (target.key.region()) + const int flags = target.key.flags(); + if (flags & kModIsPerVoice) { + ASSERT(target.key.region()); impl.targetIndicesForRegion_[target.key.region().number()].push_back(i); + } } } From 89893503bef6068854efac95db7a827e4e08a6df Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 11 Sep 2020 17:58:42 +0200 Subject: [PATCH 7/8] Remove the conditions which are made redundant --- src/sfizz/modulations/ModMatrix.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index 68501b40..06a5fe2b 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -243,8 +243,7 @@ void ModMatrix::initVoice(NumericId voiceId, NumericId regionId, const auto idNumber = static_cast(regionId.number()); for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { const auto& source = impl.sources_[idx]; - if (source.key.flags() & kModIsPerVoice) - source.gen->init(source.key, voiceId, delay); + source.gen->init(source.key, voiceId, delay); } } @@ -257,8 +256,7 @@ void ModMatrix::releaseVoice(NumericId voiceId, NumericId regionI const auto idNumber = static_cast(regionId.number()); for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { const auto& source = impl.sources_[idx]; - if (source.key.flags() & kModIsPerVoice) - source.gen->release(source.key, voiceId, delay); + source.gen->release(source.key, voiceId, delay); } } @@ -303,14 +301,12 @@ void ModMatrix::beginVoice(NumericId voiceId, NumericId regionId) const auto idNumber = static_cast(regionId.number()); for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { auto& source = impl.sources_[idx]; - if (source.key.flags() & kModIsPerVoice) - source.bufferReady = false; + source.bufferReady = false; } for (auto idx: impl.targetIndicesForRegion_[idNumber]) { auto& target = impl.targets_[idx]; - if (target.key.flags() & kModIsPerVoice) - target.bufferReady = false; + target.bufferReady = false; } } @@ -329,10 +325,8 @@ void ModMatrix::endVoice() for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { const auto& source = impl.sources_[idx]; if (!source.bufferReady) { - if (source.key.flags() & kModIsPerVoice) { - absl::Span buffer(source.buffer.data(), numFrames); - source.gen->generateDiscarded(source.key, voiceId, buffer); - } + absl::Span buffer(source.buffer.data(), numFrames); + source.gen->generateDiscarded(source.key, voiceId, buffer); } } From 8d08c6700d5644ca0fa9141b8ffc9fdde5852451 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 11 Sep 2020 18:07:01 +0200 Subject: [PATCH 8/8] Replace auto for ease of reading --- src/sfizz/modulations/ModMatrix.cpp | 39 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index 06a5fe2b..4533d156 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -49,6 +49,9 @@ struct ModMatrix::Impl { absl::flat_hash_map sourceIndex_; absl::flat_hash_map targetIndex_; + std::vector sourceIndicesForGlobal_; + std::vector targetIndicesForGlobal_; + int maxRegionIdx_ { -1 }; std::vector> sourceIndicesForRegion_; std::vector> targetIndicesForRegion_; @@ -76,6 +79,8 @@ void ModMatrix::clear() impl.targetIndex_.clear(); impl.sources_.clear(); impl.targets_.clear(); + impl.sourceIndicesForGlobal_.clear(); + impl.targetIndicesForGlobal_.clear(); impl.sourceIndicesForRegion_.clear(); impl.targetIndicesForRegion_.clear(); impl.maxRegionIdx_ = -1; @@ -217,6 +222,7 @@ void ModMatrix::init() if (flags & kModIsPerCycle) { ASSERT(!source.key.region()); source.gen->init(source.key, {}, 0); + impl.sourceIndicesForGlobal_.push_back(i); } else if (flags & kModIsPerVoice) { ASSERT(source.key.region()); @@ -227,7 +233,11 @@ void ModMatrix::init() for (unsigned i = 0; i < impl.targets_.size(); ++i) { Impl::Target& target = impl.targets_[i]; const int flags = target.key.flags(); - if (flags & kModIsPerVoice) { + if (flags & kModIsPerCycle) { + ASSERT(!target.key.region()); + impl.targetIndicesForGlobal_.push_back(i); + } + else if (flags & kModIsPerVoice) { ASSERT(target.key.region()); impl.targetIndicesForRegion_[target.key.region().number()].push_back(i); } @@ -242,7 +252,7 @@ void ModMatrix::initVoice(NumericId voiceId, NumericId regionId, const auto idNumber = static_cast(regionId.number()); for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { - const auto& source = impl.sources_[idx]; + const Impl::Source& source = impl.sources_[idx]; source.gen->init(source.key, voiceId, delay); } } @@ -255,7 +265,7 @@ void ModMatrix::releaseVoice(NumericId voiceId, NumericId regionI const auto idNumber = static_cast(regionId.number()); for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { - const auto& source = impl.sources_[idx]; + const Impl::Source& source = impl.sources_[idx]; source.gen->release(source.key, voiceId, delay); } } @@ -266,10 +276,14 @@ void ModMatrix::beginCycle(unsigned numFrames) impl.numFrames_ = numFrames; - for (Impl::Source &source : impl.sources_) + for (auto idx: impl.sourceIndicesForGlobal_) { + Impl::Source& source = impl.sources_[idx]; source.bufferReady = false; - for (Impl::Target &target : impl.targets_) + } + for (auto idx: impl.targetIndicesForGlobal_) { + Impl::Target& target = impl.targets_[idx]; target.bufferReady = false; + } } void ModMatrix::endCycle() @@ -277,12 +291,11 @@ void ModMatrix::endCycle() Impl& impl = *impl_; const uint32_t numFrames = impl.numFrames_; - for (Impl::Source &source : impl.sources_) { + for (auto idx: impl.sourceIndicesForGlobal_) { + Impl::Source& source = impl.sources_[idx]; if (!source.bufferReady) { - if (source.key.flags() & kModIsPerCycle) { - absl::Span buffer(source.buffer.data(), numFrames); - source.gen->generateDiscarded(source.key, {}, buffer); - } + absl::Span buffer(source.buffer.data(), numFrames); + source.gen->generateDiscarded(source.key, {}, buffer); } } @@ -300,12 +313,12 @@ void ModMatrix::beginVoice(NumericId voiceId, NumericId regionId) const auto idNumber = static_cast(regionId.number()); for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { - auto& source = impl.sources_[idx]; + Impl::Source& source = impl.sources_[idx]; source.bufferReady = false; } for (auto idx: impl.targetIndicesForRegion_[idNumber]) { - auto& target = impl.targets_[idx]; + Impl::Target& target = impl.targets_[idx]; target.bufferReady = false; } } @@ -323,7 +336,7 @@ void ModMatrix::endVoice() const auto idNumber = static_cast(regionId.number()); for (auto idx: impl.sourceIndicesForRegion_[idNumber]) { - const auto& source = impl.sources_[idx]; + const Impl::Source& source = impl.sources_[idx]; if (!source.bufferReady) { absl::Span buffer(source.buffer.data(), numFrames); source.gen->generateDiscarded(source.key, voiceId, buffer);