diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 4402664d..7f0d7b91 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -245,11 +245,6 @@ struct Synth::Impl: public Parser::Listener { // engine polyphony RegionSetPtr engineSet_; - // Views to speed up iteration over the regions and voices when events - // occur in the audio callback - VoiceViewVector tempPolyphonyArray_; - VoiceViewVector voiceViewArray_; - std::array lastKeyswitchLists_; std::array downKeyswitchLists_; std::array upKeyswitchLists_; @@ -265,8 +260,7 @@ struct Synth::Impl: public Parser::Listener { int samplesPerBlock_ { config::defaultSamplesPerBlock }; float sampleRate_ { config::defaultSampleRate }; float volume_ { Default::globalVolume }; - int numRequiredVoices_ { config::numVoices }; - int numActualVoices_ { static_cast(config::numVoices * config::overflowVoiceMultiplier) }; + int numVoices_ { config::numVoices }; int activeVoices_ { 0 }; Oversampling oversamplingFactor_ { config::defaultOversamplingFactor }; @@ -1644,7 +1638,7 @@ const Region* Synth::getRegionById(NumericId id) const noexcept const Voice* Synth::getVoiceView(int idx) const noexcept { Impl& impl = *impl_; - return (size_t)idx < impl.voiceList_.size() ? &impl.voiceList_[idx] : nullptr; + return idx < impl.numVoices_ ? &impl.voiceList_[idx] : nullptr; } unsigned Synth::getNumPolyphonyGroups() const noexcept @@ -1711,7 +1705,7 @@ void Synth::setVolume(float volume) noexcept int Synth::getNumVoices() const noexcept { Impl& impl = *impl_; - return impl.numRequiredVoices_; + return impl.numVoices_; } void Synth::setNumVoices(int numVoices) noexcept @@ -1721,7 +1715,7 @@ void Synth::setNumVoices(int numVoices) noexcept const std::lock_guard disableCallback { impl.callbackGuard_ }; // fast path - if (numVoices == impl.numRequiredVoices_) + if (numVoices == impl.numVoices_) return; impl.resetVoices(numVoices); @@ -1729,31 +1723,18 @@ void Synth::setNumVoices(int numVoices) noexcept void Synth::Impl::resetVoices(int numVoices) { - numActualVoices_ = - static_cast(config::overflowVoiceMultiplier * numVoices); - numRequiredVoices_ = numVoices; + numVoices_ = numVoices; for (auto& set : sets_) set->removeAllVoices(); engineSet_->removeAllVoices(); - engineSet_->setPolyphonyLimit(numRequiredVoices_); + engineSet_->setPolyphonyLimit(numVoices_); - voiceList_.clear(); - voiceList_.reserve(numActualVoices_); + voiceList_.requireNumVoices(numVoices_, resources_); - voiceViewArray_.clear(); - voiceViewArray_.reserve(numActualVoices_); - - tempPolyphonyArray_.clear(); - tempPolyphonyArray_.reserve(numActualVoices_); - - for (int i = 0; i < numActualVoices_; ++i) { - voiceList_.emplace_back(i, resources_); - Voice& lastVoice = voiceList_.back(); - lastVoice.setSampleRate(this->sampleRate_); - lastVoice.setSamplesPerBlock(this->samplesPerBlock_); - lastVoice.setStateListener(&voiceList_); - voiceViewArray_.push_back(&lastVoice); + for (auto& voice : voiceList_) { + voice.setSampleRate(this->sampleRate_); + voice.setSamplesPerBlock(this->samplesPerBlock_); } applySettingsPerVoice(); diff --git a/src/sfizz/VoiceList.h b/src/sfizz/VoiceList.h index bd347f84..5e9c572e 100644 --- a/src/sfizz/VoiceList.h +++ b/src/sfizz/VoiceList.h @@ -7,6 +7,7 @@ #pragma once #include "Voice.h" +#include "Resources.h" #include "Config.h" #include "Region.h" #include "SisterVoiceRing.h" @@ -183,10 +184,28 @@ struct VoiceList : public Voice::StateListener return {}; } + void requireNumVoices(int numVoices, Resources& resources) + { + numActualVoices_ = + static_cast(config::overflowVoiceMultiplier * numVoices); + numRequiredVoices_ = numVoices; + + clear(); + list_.reserve(numActualVoices_); + activeVoices_.reserve(numActualVoices_); + + for (int i = 0; i < numActualVoices_; ++i) { + list_.emplace_back(i, resources); + Voice& lastVoice = list_.back(); + lastVoice.setStateListener(this); + } + } + private: + int numRequiredVoices_ { config::numVoices }; + int numActualVoices_ { static_cast(config::numVoices * config::overflowVoiceMultiplier) }; std::vector list_; std::vector activeVoices_; - std::vector temp_; // These are the `group=` groups where you can off voices std::vector polyphonyGroups_; std::unique_ptr stealer_ { absl::make_unique() }; @@ -285,9 +304,8 @@ private: */ void checkEnginePolyphony(int delay) noexcept { - // TODO (paul): should have the "required" vs "actual" number of voices here Voice* candidate = stealer_->checkPolyphony( - absl::MakeSpan(activeVoices_), list_.size()); + absl::MakeSpan(activeVoices_), numRequiredVoices_); SisterVoiceRing::offAllSisters(candidate, delay); } @@ -299,12 +317,6 @@ public: typename decltype(list_)::const_iterator cend() const { return list_.cend(); } typename decltype(list_)::reference operator[] (size_t n) { return list_[n]; } typename decltype(list_)::const_reference operator[] (size_t n) const { return list_[n]; } - typename decltype(list_)::reference back() { return list_.back(); } - typename decltype(list_)::const_reference back() const { return list_.back(); } - size_t size() const { return list_.size(); } - void reserve(size_t n) { list_.reserve(n); } - template< class... Args > - void emplace_back(Args&&... args) { list_.emplace_back(std::forward(args)...); } }; } // namespace sfz