Move the playing attack voice method in the voiceList

This commit is contained in:
Paul Ferrand 2020-10-31 09:07:36 +01:00
parent 887f475317
commit 13ff2350d3
2 changed files with 39 additions and 46 deletions

View file

@ -253,15 +253,6 @@ struct Synth::Impl : public Voice::StateListener, public Parser::Listener {
*/ */
void startDelayedReleaseVoices(Region* region, int delay, SisterVoiceRingBuilder& ring) noexcept; 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 * @brief Finalize SFZ loading, following a successful execution of the
* parsing step. * parsing step.
@ -1401,24 +1392,6 @@ void Synth::Impl::startVoice(Region* region, int delay, const TriggerEvent& trig
polyphonyGroups_[region->group].registerVoice(selectedVoice); 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 void Synth::Impl::noteOffDispatch(int delay, int noteNumber, float velocity) noexcept
{ {
const auto randValue = randNoteDistribution_(Random::randomGenerator); 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]) { for (auto& region : noteActivationLists_[noteNumber]) {
if (region->registerNoteOff(noteNumber, velocity, randValue)) { 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; continue;
startVoice(region, delay, triggerEvent, ring); 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 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(); region->delayedReleases.clear();
return; return;
} }

View file

@ -7,7 +7,9 @@
#pragma once #pragma once
#include "Voice.h" #include "Voice.h"
#include "Region.h"
#include <vector> #include <vector>
#include <absl/algorithm/container.h>
namespace sfz { namespace sfz {
@ -21,7 +23,7 @@ struct VoiceList
*/ */
const Voice* getVoiceById(NumericId<Voice> id) const noexcept const Voice* getVoiceById(NumericId<Voice> id) const noexcept
{ {
const size_t size = list.size(); const size_t size = list_.size();
if (size == 0 || !id.valid()) if (size == 0 || !id.valid())
return nullptr; return nullptr;
@ -30,10 +32,10 @@ struct VoiceList
size_t index = static_cast<size_t>(id.number()); size_t index = static_cast<size_t>(id.number());
index = std::min(index, size - 1); 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; --index;
return (list[index].getId() == id) ? &list[index] : nullptr; return (list_[index].getId() == id) ? &list_[index] : nullptr;
} }
Voice* getVoiceById(NumericId<Voice> id) noexcept Voice* getVoiceById(NumericId<Voice> id) noexcept
@ -44,25 +46,43 @@ struct VoiceList
void reset() void reset()
{ {
for (auto& voice : list) for (auto& voice : list_)
voice.reset(); voice.reset();
} }
typename std::vector<Voice>::iterator begin() { return list.begin(); } bool playingAttackVoice(const Region* releaseRegion) noexcept
typename std::vector<Voice>::const_iterator cbegin() const { return list.cbegin(); } {
typename std::vector<Voice>::iterator end() { return list.end(); } const auto compatibleVoice = [releaseRegion](const Voice& v) -> bool {
typename std::vector<Voice>::const_iterator cend() const { return list.cend(); } const TriggerEvent& event = v.getTriggerEvent();
typename std::vector<Voice>::reference operator[] (size_t n) { return list[n]; } return (
typename std::vector<Voice>::const_reference operator[] (size_t n) const { return list[n]; } !v.isFree()
typename std::vector<Voice>::reference back() { return list.back(); } && event.type == TriggerEventType::NoteOn
typename std::vector<Voice>::const_reference back() const { return list.back(); } && releaseRegion->keyRange.containsWithEnd(event.number)
size_t size() const { return list.size(); } && releaseRegion->velocityRange.containsWithEnd(event.value)
void clear() { list.clear(); } );
void reserve(size_t n) { list.reserve(n); } };
if (absl::c_find_if(list_, compatibleVoice) == list_.end())
return false;
else
return true;
}
typename std::vector<Voice>::iterator begin() { return list_.begin(); }
typename std::vector<Voice>::const_iterator cbegin() const { return list_.cbegin(); }
typename std::vector<Voice>::iterator end() { return list_.end(); }
typename std::vector<Voice>::const_iterator cend() const { return list_.cend(); }
typename std::vector<Voice>::reference operator[] (size_t n) { return list_[n]; }
typename std::vector<Voice>::const_reference operator[] (size_t n) const { return list_[n]; }
typename std::vector<Voice>::reference back() { return list_.back(); }
typename std::vector<Voice>::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 > template< class... Args >
void emplace_back(Args&&... args) { list.emplace_back(std::forward<Args>(args)...); } void emplace_back(Args&&... args) { list_.emplace_back(std::forward<Args>(args)...); }
private: private:
std::vector<Voice> list; std::vector<Voice> list_;
}; };
} // namespace sfz } // namespace sfz