diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 3e7155d7..02e3ff27 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -253,15 +253,6 @@ struct Synth::Impl : public Voice::StateListener, public Parser::Listener { */ void startDelayedReleaseVoices(Region* region, int delay, SisterVoiceRingBuilder& ring) noexcept; - /** - * @brief Check if a playing voice matches the release region - * - * @param releaseRegion - * @return true - * @return false - */ - bool playingAttackVoice(const Region* releaseRegion) noexcept; - /** * @brief Finalize SFZ loading, following a successful execution of the * parsing step. @@ -1401,24 +1392,6 @@ void Synth::Impl::startVoice(Region* region, int delay, const TriggerEvent& trig polyphonyGroups_[region->group].registerVoice(selectedVoice); } -bool Synth::Impl::playingAttackVoice(const Region* releaseRegion) noexcept -{ - const auto compatibleVoice = [releaseRegion](const Voice* v) -> bool { - const TriggerEvent& event = v->getTriggerEvent(); - return ( - !v->isFree() - && event.type == TriggerEventType::NoteOn - && releaseRegion->keyRange.containsWithEnd(event.number) - && releaseRegion->velocityRange.containsWithEnd(event.value) - ); - }; - - if (absl::c_find_if(voiceViewArray_, compatibleVoice) == voiceViewArray_.end()) - return false; - else - return true; -} - void Synth::Impl::noteOffDispatch(int delay, int noteNumber, float velocity) noexcept { const auto randValue = randNoteDistribution_(Random::randomGenerator); @@ -1433,7 +1406,7 @@ void Synth::Impl::noteOffDispatch(int delay, int noteNumber, float velocity) noe for (auto& region : noteActivationLists_[noteNumber]) { if (region->registerNoteOff(noteNumber, velocity, randValue)) { - if (region->trigger == SfzTrigger::release && !region->rtDead && !playingAttackVoice(region)) + if (region->trigger == SfzTrigger::release && !region->rtDead && !voiceList_.playingAttackVoice(region)) continue; startVoice(region, delay, triggerEvent, ring); @@ -1577,7 +1550,7 @@ void Synth::Impl::noteOnDispatch(int delay, int noteNumber, float velocity) noex void Synth::Impl::startDelayedReleaseVoices(Region* region, int delay, SisterVoiceRingBuilder& ring) noexcept { - if (!region->rtDead && !playingAttackVoice(region)) { + if (!region->rtDead && !voiceList_.playingAttackVoice(region)) { region->delayedReleases.clear(); return; } diff --git a/src/sfizz/VoiceList.h b/src/sfizz/VoiceList.h index aae6f44f..0903c0bb 100644 --- a/src/sfizz/VoiceList.h +++ b/src/sfizz/VoiceList.h @@ -7,7 +7,9 @@ #pragma once #include "Voice.h" +#include "Region.h" #include +#include namespace sfz { @@ -21,7 +23,7 @@ struct VoiceList */ const Voice* getVoiceById(NumericId id) const noexcept { - const size_t size = list.size(); + const size_t size = list_.size(); if (size == 0 || !id.valid()) return nullptr; @@ -30,10 +32,10 @@ struct VoiceList size_t index = static_cast(id.number()); index = std::min(index, size - 1); - while (index > 0 && list[index].getId().number() > id.number()) + while (index > 0 && list_[index].getId().number() > id.number()) --index; - return (list[index].getId() == id) ? &list[index] : nullptr; + return (list_[index].getId() == id) ? &list_[index] : nullptr; } Voice* getVoiceById(NumericId id) noexcept @@ -44,25 +46,43 @@ struct VoiceList void reset() { - for (auto& voice : list) + for (auto& voice : list_) voice.reset(); } - typename std::vector::iterator begin() { return list.begin(); } - typename std::vector::const_iterator cbegin() const { return list.cbegin(); } - typename std::vector::iterator end() { return list.end(); } - typename std::vector::const_iterator cend() const { return list.cend(); } - typename std::vector::reference operator[] (size_t n) { return list[n]; } - typename std::vector::const_reference operator[] (size_t n) const { return list[n]; } - typename std::vector::reference back() { return list.back(); } - typename std::vector::const_reference back() const { return list.back(); } - size_t size() const { return list.size(); } - void clear() { list.clear(); } - void reserve(size_t n) { list.reserve(n); } + bool playingAttackVoice(const Region* releaseRegion) noexcept + { + const auto compatibleVoice = [releaseRegion](const Voice& v) -> bool { + const TriggerEvent& event = v.getTriggerEvent(); + return ( + !v.isFree() + && event.type == TriggerEventType::NoteOn + && releaseRegion->keyRange.containsWithEnd(event.number) + && releaseRegion->velocityRange.containsWithEnd(event.value) + ); + }; + + if (absl::c_find_if(list_, compatibleVoice) == list_.end()) + return false; + else + return true; + } + + typename std::vector::iterator begin() { return list_.begin(); } + typename std::vector::const_iterator cbegin() const { return list_.cbegin(); } + typename std::vector::iterator end() { return list_.end(); } + typename std::vector::const_iterator cend() const { return list_.cend(); } + typename std::vector::reference operator[] (size_t n) { return list_[n]; } + typename std::vector::const_reference operator[] (size_t n) const { return list_[n]; } + typename std::vector::reference back() { return list_.back(); } + typename std::vector::const_reference back() const { return list_.back(); } + size_t size() const { return list_.size(); } + void clear() { list_.clear(); } + void reserve(size_t n) { list_.reserve(n); } template< class... Args > - void emplace_back(Args&&... args) { list.emplace_back(std::forward(args)...); } + void emplace_back(Args&&... args) { list_.emplace_back(std::forward(args)...); } private: - std::vector list; + std::vector list_; }; } // namespace sfz