Move even more stuff in the voiceList_

This commit is contained in:
Paul Ferrand 2020-10-31 19:48:42 +01:00
parent 4aeb12446e
commit 1b87fa3764
2 changed files with 31 additions and 38 deletions

View file

@ -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<RegionViewVector, 128> lastKeyswitchLists_;
std::array<RegionViewVector, 128> downKeyswitchLists_;
std::array<RegionViewVector, 128> 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<int>(config::numVoices * config::overflowVoiceMultiplier) };
int numVoices_ { config::numVoices };
int activeVoices_ { 0 };
Oversampling oversamplingFactor_ { config::defaultOversamplingFactor };
@ -1644,7 +1638,7 @@ const Region* Synth::getRegionById(NumericId<Region> 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<SpinMutex> 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<int>(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();

View file

@ -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<int>(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<int>(config::numVoices * config::overflowVoiceMultiplier) };
std::vector<Voice> list_;
std::vector<Voice*> activeVoices_;
std::vector<Voice*> temp_;
// These are the `group=` groups where you can off voices
std::vector<PolyphonyGroup> polyphonyGroups_;
std::unique_ptr<VoiceStealer> stealer_ { absl::make_unique<OldestStealer>() };
@ -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>(args)...); }
};
} // namespace sfz