diff --git a/src/sfizz/PolyphonyGroup.cpp b/src/sfizz/PolyphonyGroup.cpp index d5b1615c..18b7a34f 100644 --- a/src/sfizz/PolyphonyGroup.cpp +++ b/src/sfizz/PolyphonyGroup.cpp @@ -17,6 +17,11 @@ void sfz::PolyphonyGroup::removeVoice(const Voice* voice) noexcept swapAndPopFirst(voices, [voice](const Voice* v) { return v == voice; }); } +void sfz::PolyphonyGroup::removeAllVoices() noexcept +{ + voices.clear(); +} + unsigned sfz::PolyphonyGroup::numPlayingVoices() const noexcept { return absl::c_count_if(voices, [](const Voice* v) { diff --git a/src/sfizz/PolyphonyGroup.h b/src/sfizz/PolyphonyGroup.h index f3d47257..6a87d05f 100644 --- a/src/sfizz/PolyphonyGroup.h +++ b/src/sfizz/PolyphonyGroup.h @@ -35,6 +35,10 @@ public: * @param voice */ void removeVoice(const Voice* voice) noexcept; + /** + * @brief Remove all the voices from this polyphony group. + */ + void removeAllVoices() noexcept; /** * @brief Get the polyphony limit for this group * diff --git a/src/sfizz/VoiceManager.cpp b/src/sfizz/VoiceManager.cpp index f8bf71f8..b4d93e13 100644 --- a/src/sfizz/VoiceManager.cpp +++ b/src/sfizz/VoiceManager.cpp @@ -13,17 +13,22 @@ namespace sfz { void VoiceManager::onVoiceStateChanging(NumericId id, Voice::State state) { - (void)id; if (state == Voice::State::idle) { - auto voice = getVoiceById(id); - RegionSet::removeVoiceFromHierarchy(voice->getRegion(), voice); + Voice* voice = getVoiceById(id); + const Region* region = voice->getRegion(); + const uint32_t group = region->group; + RegionSet::removeVoiceFromHierarchy(region, voice); swapAndPopFirst(activeVoices_, [voice](const Voice* v) { return v == voice; }); - polyphonyGroups_[voice->getRegion()->group].removeVoice(voice); + ASSERT(group < polyphonyGroups_.size()); + polyphonyGroups_[group].removeVoice(voice); } else if (state == Voice::State::playing) { - auto voice = getVoiceById(id); + Voice* voice = getVoiceById(id); + const Region* region = voice->getRegion(); + const uint32_t group = region->group; activeVoices_.push_back(voice); - RegionSet::registerVoiceInHierarchy(voice->getRegion(), voice); - polyphonyGroups_[voice->getRegion()->group].registerVoice(voice); + RegionSet::registerVoiceInHierarchy(region, voice); + ASSERT(group < polyphonyGroups_.size()); + polyphonyGroups_[group].registerVoice(voice); } } @@ -81,8 +86,9 @@ bool VoiceManager::playingAttackVoice(const Region* releaseRegion) noexcept void VoiceManager::ensureNumPolyphonyGroups(unsigned groupIdx) noexcept { - while (polyphonyGroups_.size() <= groupIdx) - polyphonyGroups_.emplace_back(); + size_t neededSize = static_cast(groupIdx) + 1; + if (polyphonyGroups_.size() < neededSize) + polyphonyGroups_.resize(neededSize); } void VoiceManager::setGroupPolyphony(unsigned groupIdx, unsigned polyphony) noexcept @@ -99,7 +105,8 @@ const PolyphonyGroup* VoiceManager::getPolyphonyGroupView(int idx) const noexcep void VoiceManager::clear() { - reset(); + for (PolyphonyGroup& pg : polyphonyGroups_) + pg.removeAllVoices(); list_.clear(); activeVoices_.clear(); }