Move the playing attack voice method in the voiceList
This commit is contained in:
parent
887f475317
commit
13ff2350d3
2 changed files with 39 additions and 46 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue