Use the soft engine polyphony limit
This commit is contained in:
parent
8071cd0131
commit
480a7d4628
5 changed files with 32 additions and 7 deletions
|
|
@ -61,13 +61,14 @@ struct SisterVoiceRing {
|
||||||
*
|
*
|
||||||
* @param voice
|
* @param voice
|
||||||
* @param delay
|
* @param delay
|
||||||
|
* @param fast whether to apply a fast release
|
||||||
*/
|
*/
|
||||||
template<class T,
|
template<class T,
|
||||||
absl::enable_if_t<std::is_same<Voice, absl::remove_const_t<T>>::value, int> = 0>
|
absl::enable_if_t<std::is_same<Voice, absl::remove_const_t<T>>::value, int> = 0>
|
||||||
static void offAllSisters(T* voice, int delay) {
|
static void offAllSisters(T* voice, int delay, bool fast = false) {
|
||||||
if (voice != nullptr) {
|
if (voice != nullptr) {
|
||||||
SisterVoiceRing::applyToRing(voice, [&] (Voice* v) {
|
SisterVoiceRing::applyToRing(voice, [&] (Voice* v) {
|
||||||
v->off(delay);
|
v->off(delay, fast);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ void sfz::Synth::onVoiceStateChanged(NumericId<Voice> id, Voice::State state)
|
||||||
if (state == Voice::State::idle) {
|
if (state == Voice::State::idle) {
|
||||||
auto voice = getVoiceById(id);
|
auto voice = getVoiceById(id);
|
||||||
RegionSet::removeVoiceFromHierarchy(voice->getRegion(), voice);
|
RegionSet::removeVoiceFromHierarchy(voice->getRegion(), voice);
|
||||||
|
engineSet->removeVoice(voice);
|
||||||
polyphonyGroups[voice->getRegion()->group].removeVoice(voice);
|
polyphonyGroups[voice->getRegion()->group].removeVoice(voice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -744,7 +745,7 @@ sfz::Voice* sfz::Synth::findFreeVoice() noexcept
|
||||||
if (freeVoice != voices.end())
|
if (freeVoice != voices.end())
|
||||||
return freeVoice->get();
|
return freeVoice->get();
|
||||||
|
|
||||||
DBG("Engine polyphony reached");
|
DBG("Engine hard polyphony reached");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -972,6 +973,7 @@ void sfz::Synth::startVoice(Region* region, int delay, const TriggerEvent& trigg
|
||||||
checkRegionPolyphony(region, delay);
|
checkRegionPolyphony(region, delay);
|
||||||
checkGroupPolyphony(region, delay);
|
checkGroupPolyphony(region, delay);
|
||||||
checkSetPolyphony(region, delay);
|
checkSetPolyphony(region, delay);
|
||||||
|
checkEnginePolyphony(delay);
|
||||||
|
|
||||||
Voice* selectedVoice = findFreeVoice();
|
Voice* selectedVoice = findFreeVoice();
|
||||||
if (selectedVoice == nullptr)
|
if (selectedVoice == nullptr)
|
||||||
|
|
@ -980,6 +982,7 @@ void sfz::Synth::startVoice(Region* region, int delay, const TriggerEvent& trigg
|
||||||
ASSERT(selectedVoice->isFree());
|
ASSERT(selectedVoice->isFree());
|
||||||
selectedVoice->startVoice(region, delay, triggerEvent);
|
selectedVoice->startVoice(region, delay, triggerEvent);
|
||||||
ring.addVoiceToRing(selectedVoice);
|
ring.addVoiceToRing(selectedVoice);
|
||||||
|
engineSet->registerVoice(selectedVoice);
|
||||||
RegionSet::registerVoiceInHierarchy(region, selectedVoice);
|
RegionSet::registerVoiceInHierarchy(region, selectedVoice);
|
||||||
polyphonyGroups[region->group].registerVoice(selectedVoice);
|
polyphonyGroups[region->group].registerVoice(selectedVoice);
|
||||||
}
|
}
|
||||||
|
|
@ -1108,6 +1111,19 @@ void sfz::Synth::checkSetPolyphony(const Region* region, int delay) noexcept
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sfz::Synth::checkEnginePolyphony(int delay) noexcept
|
||||||
|
{
|
||||||
|
auto& activeVoices = engineSet->getActiveVoices();
|
||||||
|
|
||||||
|
if (activeVoices.size() >= static_cast<size_t>(numRequiredVoices)) {
|
||||||
|
tempPolyphonyArray.clear();
|
||||||
|
absl::c_copy_if(activeVoices,
|
||||||
|
std::back_inserter(tempPolyphonyArray), [](Voice* v) { return !v->releasedOrFree(); });
|
||||||
|
const auto voiceToSteal = stealer.steal(absl::MakeSpan(tempPolyphonyArray));
|
||||||
|
SisterVoiceRing::offAllSisters(voiceToSteal, delay, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexcept
|
void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexcept
|
||||||
{
|
{
|
||||||
const auto randValue = randNoteDistribution(Random::randomGenerator);
|
const auto randValue = randNoteDistribution(Random::randomGenerator);
|
||||||
|
|
|
||||||
|
|
@ -865,6 +865,13 @@ private:
|
||||||
*/
|
*/
|
||||||
void checkSetPolyphony(const Region* region, int delay) noexcept;
|
void checkSetPolyphony(const Region* region, int delay) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check the engine polyphony, fast releasing voices if necessary
|
||||||
|
*
|
||||||
|
* @param delay
|
||||||
|
*/
|
||||||
|
void checkEnginePolyphony(int delay) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start a voice for a specific region.
|
* @brief Start a voice for a specific region.
|
||||||
* This will do the needed polyphony checks and voice stealing.
|
* This will do the needed polyphony checks and voice stealing.
|
||||||
|
|
|
||||||
|
|
@ -167,11 +167,11 @@ void sfz::Voice::release(int delay) noexcept
|
||||||
resources.modMatrix.releaseVoice(id, region->getId(), delay);
|
resources.modMatrix.releaseVoice(id, region->getId(), delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::off(int delay) noexcept
|
void sfz::Voice::off(int delay, bool fast) noexcept
|
||||||
{
|
{
|
||||||
if (!region->flexAmpEG) {
|
if (!region->flexAmpEG) {
|
||||||
if (region->offMode == SfzOffMode::fast) {
|
if (region->offMode == SfzOffMode::fast || fast) {
|
||||||
egAmplitude.setReleaseTime( Default::offTime );
|
egAmplitude.setReleaseTime(Default::offTime);
|
||||||
} else if (region->offMode == SfzOffMode::time) {
|
} else if (region->offMode == SfzOffMode::time) {
|
||||||
egAmplitude.setReleaseTime(region->offTime);
|
egAmplitude.setReleaseTime(region->offTime);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -328,8 +328,9 @@ public:
|
||||||
* and set the envelopes if necessary.
|
* and set the envelopes if necessary.
|
||||||
*
|
*
|
||||||
* @param delay
|
* @param delay
|
||||||
|
* @param fast whether to apply a fast release regardless of the off mode
|
||||||
*/
|
*/
|
||||||
void off(int delay) noexcept;
|
void off(int delay, bool fast = false) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief gets the age of the Voice
|
* @brief gets the age of the Voice
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue