Use a trigger event type instead of passing 3 parameters
This commit is contained in:
parent
afae38e6c3
commit
dda10e8530
7 changed files with 117 additions and 96 deletions
|
|
@ -9,6 +9,7 @@
|
|||
#include "Debug.h"
|
||||
#include "Macros.h"
|
||||
#include "MidiState.h"
|
||||
#include "TriggerEvent.h"
|
||||
#include "ModifierHelpers.h"
|
||||
#include "ScopedFTZ.h"
|
||||
#include "StringViewHelpers.h"
|
||||
|
|
@ -892,12 +893,14 @@ void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity) noexcept
|
|||
noteOffDispatch(delay, noteNumber, replacedVelocity);
|
||||
}
|
||||
|
||||
bool matchReleaseRegionAndVoice(const sfz::Region& region, const sfz::Voice& voice) {
|
||||
bool matchReleaseRegionAndVoice(const sfz::Region& region, const sfz::Voice& voice)
|
||||
{
|
||||
const sfz::TriggerEvent& event = voice.getTriggerEvent();
|
||||
return (
|
||||
!voice.isFree()
|
||||
&& voice.getTriggerType() == sfz::Voice::TriggerType::NoteOn
|
||||
&& region.keyRange.containsWithEnd(voice.getTriggerNumber())
|
||||
&& region.velocityRange.containsWithEnd(voice.getTriggerValue())
|
||||
&& event.type == sfz::TriggerEventType::NoteOn
|
||||
&& region.keyRange.containsWithEnd(event.number)
|
||||
&& region.velocityRange.containsWithEnd(event.value)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -905,6 +908,7 @@ void sfz::Synth::noteOffDispatch(int delay, int noteNumber, float velocity) noex
|
|||
{
|
||||
const auto randValue = randNoteDistribution(Random::randomGenerator);
|
||||
SisterVoiceRingBuilder ring;
|
||||
const TriggerEvent triggerEvent { TriggerEventType::NoteOff, noteNumber, velocity };
|
||||
|
||||
for (auto& region : noteActivationLists[noteNumber]) {
|
||||
if (region->registerNoteOff(noteNumber, velocity, randValue)) {
|
||||
|
|
@ -924,7 +928,7 @@ void sfz::Synth::noteOffDispatch(int delay, int noteNumber, float velocity) noex
|
|||
|
||||
if (Voice* selectedVoice = findFreeVoice()) {
|
||||
ASSERT(selectedVoice->isFree());
|
||||
selectedVoice->startVoice(region, delay, noteNumber, velocity, Voice::TriggerType::NoteOff);
|
||||
selectedVoice->startVoice(region, delay, triggerEvent);
|
||||
ring.addVoiceToRing(selectedVoice);
|
||||
RegionSet::registerVoiceInHierarchy(region, selectedVoice);
|
||||
polyphonyGroups[region->group].registerVoice(selectedVoice);
|
||||
|
|
@ -949,7 +953,7 @@ void sfz::Synth::checkRegionPolyphony(const Region* region, int delay) noexcept
|
|||
}
|
||||
}
|
||||
|
||||
void sfz::Synth::checkNotePolyphony(const Region* region, int delay, int number, float value, Voice::TriggerType triggerType) noexcept
|
||||
void sfz::Synth::checkNotePolyphony(const Region* region, int delay, const TriggerEvent& triggerEvent) noexcept
|
||||
{
|
||||
if (!region->notePolyphony)
|
||||
return;
|
||||
|
|
@ -958,15 +962,16 @@ void sfz::Synth::checkNotePolyphony(const Region* region, int delay, int number,
|
|||
Voice* selfMaskCandidate { nullptr };
|
||||
|
||||
for (Voice* voice : voiceViewArray) {
|
||||
const sfz::TriggerEvent& voiceTriggerEvent = voice->getTriggerEvent();
|
||||
if (!voice->releasedOrFree()
|
||||
&& voice->getRegion()->group == region->group
|
||||
&& voice->getTriggerNumber() == number
|
||||
&& voice->getTriggerType() ==triggerType) {
|
||||
&& voiceTriggerEvent.number == triggerEvent.number
|
||||
&& voiceTriggerEvent.type == triggerEvent.type) {
|
||||
notePolyphonyCounter += 1;
|
||||
switch (region->selfMask) {
|
||||
case SfzSelfMask::mask:
|
||||
if (voice->getTriggerValue() <= value) {
|
||||
if (!selfMaskCandidate || selfMaskCandidate->getTriggerValue() > voice->getTriggerValue())
|
||||
if (voiceTriggerEvent.value <= triggerEvent.value) {
|
||||
if (!selfMaskCandidate || selfMaskCandidate->getTriggerEvent().value > voiceTriggerEvent.value)
|
||||
selfMaskCandidate = voice;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1023,23 +1028,26 @@ void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexc
|
|||
{
|
||||
const auto randValue = randNoteDistribution(Random::randomGenerator);
|
||||
SisterVoiceRingBuilder ring;
|
||||
const TriggerEvent triggerEvent { TriggerEventType::NoteOn, noteNumber, velocity };
|
||||
|
||||
for (auto& region : noteActivationLists[noteNumber]) {
|
||||
if (region->registerNoteOn(noteNumber, velocity, randValue)) {
|
||||
|
||||
for (auto& voice : voices) {
|
||||
if (voice->checkOffGroup(delay, region->group))
|
||||
noteOffDispatch(delay, voice->getTriggerNumber(), voice->getTriggerValue());
|
||||
if (voice->checkOffGroup(delay, region->group)) {
|
||||
const TriggerEvent& event = voice->getTriggerEvent();
|
||||
noteOffDispatch(delay, event.number, event.value);
|
||||
}
|
||||
}
|
||||
|
||||
checkNotePolyphony(region, delay, noteNumber, velocity, Voice::TriggerType::NoteOn);
|
||||
checkNotePolyphony(region, delay, triggerEvent);
|
||||
checkRegionPolyphony(region, delay);
|
||||
checkGroupPolyphony(region, delay);
|
||||
checkSetPolyphony(region, delay);
|
||||
|
||||
if (Voice* selectedVoice = findFreeVoice()) {
|
||||
ASSERT(selectedVoice->isFree());
|
||||
selectedVoice->startVoice(region, delay, noteNumber, velocity, Voice::TriggerType::NoteOn);
|
||||
selectedVoice->startVoice(region, delay, triggerEvent);
|
||||
ring.addVoiceToRing(selectedVoice);
|
||||
RegionSet::registerVoiceInHierarchy(region, selectedVoice);
|
||||
polyphonyGroups[region->group].registerVoice(selectedVoice);
|
||||
|
|
@ -1082,6 +1090,7 @@ void sfz::Synth::hdcc(int delay, int ccNumber, float normValue) noexcept
|
|||
voice->registerCC(delay, ccNumber, normValue);
|
||||
|
||||
SisterVoiceRingBuilder ring;
|
||||
const TriggerEvent triggerEvent { TriggerEventType::CC, ccNumber, normValue };
|
||||
|
||||
for (auto& region : ccActivationLists[ccNumber]) {
|
||||
if (ccNumber == region->sustainCC) {
|
||||
|
|
@ -1105,7 +1114,8 @@ void sfz::Synth::hdcc(int delay, int ccNumber, float normValue) noexcept
|
|||
if (voice == nullptr)
|
||||
continue;
|
||||
|
||||
voice->startVoice(region, delay, note.first, note.second, Voice::TriggerType::NoteOff);
|
||||
const TriggerEvent noteOffEvent { TriggerEventType::NoteOff, note.first, note.second };
|
||||
voice->startVoice(region, delay, noteOffEvent);
|
||||
|
||||
ring.addVoiceToRing(voice);
|
||||
RegionSet::registerVoiceInHierarchy(region, voice);
|
||||
|
|
@ -1118,7 +1128,7 @@ void sfz::Synth::hdcc(int delay, int ccNumber, float normValue) noexcept
|
|||
if (region->registerCC(ccNumber, normValue)) {
|
||||
if (Voice* selectedVoice = findFreeVoice()) {
|
||||
ASSERT(selectedVoice->isFree());
|
||||
selectedVoice->startVoice(region, delay, ccNumber, normValue, Voice::TriggerType::CC);
|
||||
selectedVoice->startVoice(region, delay, triggerEvent);
|
||||
ring.addVoiceToRing(selectedVoice);
|
||||
RegionSet::registerVoiceInHierarchy(region, selectedVoice);
|
||||
polyphonyGroups[region->group].registerVoice(selectedVoice);
|
||||
|
|
|
|||
|
|
@ -781,7 +781,7 @@ private:
|
|||
VoiceStealing stealer;
|
||||
|
||||
void checkRegionPolyphony(const Region* region, int delay) noexcept;
|
||||
void checkNotePolyphony(const Region* region, int delay, int number, float value, Voice::TriggerType triggerType) noexcept;
|
||||
void checkNotePolyphony(const Region* region, int delay, const TriggerEvent& triggerEvent) noexcept;
|
||||
void checkGroupPolyphony(const Region* region, int delay) noexcept;
|
||||
void checkSetPolyphony(const Region* region, int delay) noexcept;
|
||||
|
||||
|
|
|
|||
24
src/sfizz/TriggerEvent.h
Normal file
24
src/sfizz/TriggerEvent.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// license. You should have receive a LICENSE.md file along with the code.
|
||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace sfz
|
||||
{
|
||||
enum class TriggerEventType { NoteOn, NoteOff, CC };
|
||||
|
||||
/**
|
||||
* @brief Encapsulate a midi event with normalized values
|
||||
*
|
||||
*/
|
||||
struct TriggerEvent
|
||||
{
|
||||
TriggerEventType type;
|
||||
int number;
|
||||
float value;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -36,22 +36,18 @@ sfz::Voice::~Voice()
|
|||
{
|
||||
}
|
||||
|
||||
void sfz::Voice::startVoice(Region* region, int delay, int number, float value, sfz::Voice::TriggerType triggerType) noexcept
|
||||
void sfz::Voice::startVoice(Region* region, int delay, const TriggerEvent& event) noexcept
|
||||
{
|
||||
ASSERT(value >= 0.0f && value <= 1.0f);
|
||||
|
||||
if (triggerType == TriggerType::CC)
|
||||
number = region->pitchKeycenter;
|
||||
|
||||
this->triggerType = triggerType;
|
||||
triggerNumber = number;
|
||||
triggerValue = value;
|
||||
ASSERT(event.value >= 0.0f && event.value <= 1.0f);
|
||||
|
||||
this->region = region;
|
||||
|
||||
if (region->disabled())
|
||||
return;
|
||||
|
||||
triggerEvent = event;
|
||||
if (triggerEvent.type == TriggerEventType::CC)
|
||||
triggerEvent.number = region->pitchKeycenter;
|
||||
|
||||
switchState(State::playing);
|
||||
|
||||
ASSERT(delay >= 0);
|
||||
|
|
@ -106,18 +102,18 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
|
|||
}
|
||||
|
||||
// do Scala retuning and reconvert the frequency into a 12TET key number
|
||||
const float numberRetuned = resources.tuning.getKeyFractional12TET(number);
|
||||
const float numberRetuned = resources.tuning.getKeyFractional12TET(triggerEvent.number);
|
||||
|
||||
pitchRatio = region->getBasePitchVariation(numberRetuned, value);
|
||||
pitchRatio = region->getBasePitchVariation(numberRetuned, triggerEvent.value);
|
||||
|
||||
// apply stretch tuning if set
|
||||
if (resources.stretch)
|
||||
pitchRatio *= resources.stretch->getRatioForFractionalKey(numberRetuned);
|
||||
|
||||
baseVolumedB = region->getBaseVolumedB(number);
|
||||
baseVolumedB = region->getBaseVolumedB(triggerEvent.number);
|
||||
baseGain = region->getBaseGain();
|
||||
if (triggerType != TriggerType::CC)
|
||||
baseGain *= region->getNoteGain(number, value);
|
||||
if (triggerEvent.type != TriggerEventType::CC)
|
||||
baseGain *= region->getNoteGain(triggerEvent.number, triggerEvent.value);
|
||||
gainSmoother.reset();
|
||||
resetCrossfades();
|
||||
|
||||
|
|
@ -127,13 +123,13 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
|
|||
|
||||
const unsigned numChannels = region->isStereo() ? 2 : 1;
|
||||
for (auto& filter: region->filters) {
|
||||
auto newFilter = resources.filterPool.getFilter(filter, numChannels, number, value);
|
||||
auto newFilter = resources.filterPool.getFilter(filter, numChannels, triggerEvent.number, triggerEvent.value);
|
||||
if (newFilter)
|
||||
filters.push_back(newFilter);
|
||||
}
|
||||
|
||||
for (auto& eq: region->equalizers) {
|
||||
auto newEQ = resources.eqPool.getEQ(eq, numChannels, value);
|
||||
auto newEQ = resources.eqPool.getEQ(eq, numChannels, triggerEvent.value);
|
||||
if (newEQ)
|
||||
equalizers.push_back(newEQ);
|
||||
}
|
||||
|
|
@ -141,11 +137,11 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
|
|||
sourcePosition = region->getOffset();
|
||||
triggerDelay = delay;
|
||||
initialDelay = delay + static_cast<int>(region->getDelay() * sampleRate);
|
||||
baseFrequency = resources.tuning.getFrequencyOfKey(number);
|
||||
baseFrequency = resources.tuning.getFrequencyOfKey(triggerEvent.number);
|
||||
bendStepFactor = centsFactor(region->bendStep);
|
||||
bendSmoother.setSmoothing(region->bendSmooth, sampleRate);
|
||||
bendSmoother.reset(centsFactor(region->getBendInCents(resources.midiState.getPitchBend())));
|
||||
egEnvelope.reset(region->amplitudeEG, *region, resources.midiState, delay, value, sampleRate);
|
||||
egEnvelope.reset(region->amplitudeEG, *region, resources.midiState, delay, triggerEvent.value, sampleRate);
|
||||
|
||||
resources.modMatrix.initVoice(id, region->getId(), delay);
|
||||
}
|
||||
|
|
@ -197,7 +193,7 @@ void sfz::Voice::registerNoteOff(int delay, int noteNumber, float velocity) noex
|
|||
if (state != State::playing)
|
||||
return;
|
||||
|
||||
if (triggerNumber == noteNumber) {
|
||||
if (triggerEvent.number == noteNumber) {
|
||||
noteIsOff = true;
|
||||
|
||||
if (region->loopMode == SfzLoopMode::one_shot)
|
||||
|
|
@ -717,7 +713,7 @@ bool sfz::Voice::checkOffGroup(int delay, uint32_t group) noexcept
|
|||
if (region == nullptr)
|
||||
return false;
|
||||
|
||||
if (triggerType == TriggerType::NoteOn && region->offBy == group) {
|
||||
if (triggerEvent.type == TriggerEventType::NoteOn && region->offBy == group) {
|
||||
off(delay);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#pragma once
|
||||
#include "TriggerEvent.h"
|
||||
#include "Config.h"
|
||||
#include "ADSREnvelope.h"
|
||||
#include "HistoricalBuffer.h"
|
||||
|
|
@ -113,11 +114,9 @@ public:
|
|||
*
|
||||
* @param region
|
||||
* @param delay
|
||||
* @param number
|
||||
* @param value
|
||||
* @param triggerType
|
||||
* @param evebt
|
||||
*/
|
||||
void startVoice(Region* region, int delay, int number, float value, TriggerType triggerType) noexcept;
|
||||
void startVoice(Region* region, int delay, const TriggerEvent& event) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Get the sample quality determined by the active region.
|
||||
|
|
@ -198,23 +197,11 @@ public:
|
|||
*/
|
||||
bool releasedOrFree() const noexcept;
|
||||
/**
|
||||
* @brief Get the number that triggered the voice (note number or cc number)
|
||||
* @brief Get the event that triggered the voice
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int getTriggerNumber() const noexcept { return triggerNumber; }
|
||||
/**
|
||||
* @brief Get the value that triggered the voice (note velocity or cc value)
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
float getTriggerValue() const noexcept { return triggerValue; }
|
||||
/**
|
||||
* @brief Get the type of trigger
|
||||
*
|
||||
* @return TriggerType
|
||||
*/
|
||||
TriggerType getTriggerType() const noexcept { return triggerType; }
|
||||
const TriggerEvent& getTriggerEvent() const noexcept { return triggerEvent; }
|
||||
|
||||
/**
|
||||
* @brief Reset the voice to its initial values
|
||||
|
|
@ -432,9 +419,7 @@ private:
|
|||
State state { State::idle };
|
||||
bool noteIsOff { false };
|
||||
|
||||
TriggerType triggerType;
|
||||
int triggerNumber;
|
||||
float triggerValue;
|
||||
TriggerEvent triggerEvent;
|
||||
absl::optional<int> triggerDelay;
|
||||
|
||||
float speedRatio { 1.0 };
|
||||
|
|
@ -496,13 +481,16 @@ inline bool sisterVoices(const Voice* lhs, const Voice* rhs)
|
|||
if (lhs->getAge() != rhs->getAge())
|
||||
return false;
|
||||
|
||||
if (lhs->getTriggerNumber() != rhs->getTriggerNumber())
|
||||
const TriggerEvent& lhsTrigger = lhs->getTriggerEvent();
|
||||
const TriggerEvent& rhsTrigger = rhs->getTriggerEvent();
|
||||
|
||||
if (lhsTrigger.number != rhsTrigger.number)
|
||||
return false;
|
||||
|
||||
if (lhs->getTriggerValue() != rhs->getTriggerValue())
|
||||
if (lhsTrigger.value != rhsTrigger.value)
|
||||
return false;
|
||||
|
||||
if (lhs->getTriggerType() != rhs->getTriggerType())
|
||||
if (lhsTrigger.type != rhsTrigger.type)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
@ -513,14 +501,17 @@ inline bool voiceOrdering(const Voice* lhs, const Voice* rhs)
|
|||
if (lhs->getAge() != rhs->getAge())
|
||||
return lhs->getAge() > rhs->getAge();
|
||||
|
||||
if (lhs->getTriggerNumber() != rhs->getTriggerNumber())
|
||||
return lhs->getTriggerNumber() < rhs->getTriggerNumber();
|
||||
const TriggerEvent& lhsTrigger = lhs->getTriggerEvent();
|
||||
const TriggerEvent& rhsTrigger = rhs->getTriggerEvent();
|
||||
|
||||
if (lhs->getTriggerValue() != rhs->getTriggerValue())
|
||||
return lhs->getTriggerValue() < rhs->getTriggerValue();
|
||||
if (lhsTrigger.number != rhsTrigger.number)
|
||||
return lhsTrigger.number < rhsTrigger.number;
|
||||
|
||||
if (lhs->getTriggerType() != rhs->getTriggerType())
|
||||
return lhs->getTriggerType() > rhs->getTriggerType();
|
||||
if (lhsTrigger.value != rhsTrigger.value)
|
||||
return lhsTrigger.value < rhsTrigger.value;
|
||||
|
||||
if (lhsTrigger.type != rhsTrigger.type)
|
||||
return lhsTrigger.type > rhsTrigger.type;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,11 +227,11 @@ TEST_CASE("[Polyphony] Self-masking")
|
|||
REQUIRE( synth.getNumActiveVoices(true) == 3 ); // One of these is releasing
|
||||
synth.renderBlock(buffer);
|
||||
REQUIRE( numPlayingVoices(synth) == 2 );
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE(!synth.getVoiceView(0)->releasedOrFree());
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerValue() == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerEvent().value == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->releasedOrFree()); // The lowest velocity voice is the masking candidate
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerValue() == 64_norm);
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerEvent().value == 64_norm);
|
||||
REQUIRE(!synth.getVoiceView(2)->releasedOrFree());
|
||||
}
|
||||
|
||||
|
|
@ -248,11 +248,11 @@ TEST_CASE("[Polyphony] Not self-masking")
|
|||
REQUIRE( synth.getNumActiveVoices(true) == 3 ); // One of these is releasing
|
||||
synth.renderBlock(buffer);
|
||||
REQUIRE( numPlayingVoices(synth) == 2 );
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->releasedOrFree());
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerValue() == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerEvent().value == 62_norm);
|
||||
REQUIRE(!synth.getVoiceView(1)->releasedOrFree());
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerValue() == 64_norm);
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerEvent().value == 64_norm);
|
||||
REQUIRE(!synth.getVoiceView(2)->releasedOrFree());
|
||||
}
|
||||
|
||||
|
|
@ -269,11 +269,11 @@ TEST_CASE("[Polyphony] Self-masking with the exact same velocity")
|
|||
REQUIRE( synth.getNumActiveVoices(true) == 3 ); // One of these is releasing
|
||||
synth.renderBlock(buffer);
|
||||
REQUIRE( numPlayingVoices(synth) == 2 );
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerValue() == 64_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerEvent().value == 64_norm);
|
||||
REQUIRE(!synth.getVoiceView(0)->releasedOrFree());
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->releasedOrFree()); // The first one is the masking candidate since they have the same velocity
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE(!synth.getVoiceView(2)->releasedOrFree());
|
||||
}
|
||||
|
||||
|
|
@ -286,9 +286,9 @@ TEST_CASE("[Polyphony] Self-masking only works from low to high")
|
|||
synth.noteOn(0, 64, 63 );
|
||||
synth.noteOn(0, 64, 62 );
|
||||
REQUIRE( synth.getNumActiveVoices(true) == 2 ); // Both notes are playing
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE(!synth.getVoiceView(0)->releasedOrFree());
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerValue() == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerEvent().value == 62_norm);
|
||||
REQUIRE(!synth.getVoiceView(1)->releasedOrFree());
|
||||
}
|
||||
|
||||
|
|
@ -305,13 +305,13 @@ TEST_CASE("[Polyphony] Note polyphony checks works across regions in the same po
|
|||
REQUIRE( synth.getNumActiveVoices(true) == 4);
|
||||
synth.renderBlock(buffer);
|
||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerValue() == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerEvent().value == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->releasedOrFree()); // got killed
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerValue() == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerEvent().value == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->releasedOrFree()); // got killed
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(2)->releasedOrFree()); // got killed
|
||||
REQUIRE( synth.getVoiceView(3)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(3)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE(!synth.getVoiceView(3)->releasedOrFree());
|
||||
}
|
||||
|
||||
|
|
@ -333,9 +333,9 @@ TEST_CASE("[Polyphony] Note polyphony checks works across regions in the same po
|
|||
REQUIRE( synth.getNumActiveVoices(true) == 2 );
|
||||
synth.renderBlock(buffer);
|
||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->releasedOrFree());
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerValue() == 64_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerEvent().value == 64_norm);
|
||||
REQUIRE(!synth.getVoiceView(1)->releasedOrFree());
|
||||
}
|
||||
|
||||
|
|
@ -353,13 +353,13 @@ TEST_CASE("[Polyphony] Note polyphony do not operate across polyphony groups")
|
|||
REQUIRE( synth.getNumActiveVoices(true) == 4); // Both notes are playing
|
||||
synth.renderBlock(buffer);
|
||||
REQUIRE(numPlayingVoices(synth) == 2 );
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerValue() == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerEvent().value == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->releasedOrFree()); // got killed
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerValue() == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerEvent().value == 62_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->releasedOrFree()); // got killed
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(2)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE(!synth.getVoiceView(2)->releasedOrFree());
|
||||
REQUIRE( synth.getVoiceView(3)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(3)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE(!synth.getVoiceView(3)->releasedOrFree());
|
||||
}
|
||||
|
||||
|
|
@ -381,8 +381,8 @@ TEST_CASE("[Polyphony] Note polyphony do not operate across polyphony groups (wi
|
|||
REQUIRE( synth.getNumActiveVoices(true) == 2 );
|
||||
synth.renderBlock(buffer);
|
||||
REQUIRE(numPlayingVoices(synth) == 2 );
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerValue() == 63_norm);
|
||||
REQUIRE( synth.getVoiceView(0)->getTriggerEvent().value == 63_norm);
|
||||
REQUIRE(!synth.getVoiceView(0)->releasedOrFree());
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerValue() == 64_norm);
|
||||
REQUIRE( synth.getVoiceView(1)->getTriggerEvent().value == 64_norm);
|
||||
REQUIRE(!synth.getVoiceView(1)->releasedOrFree());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -660,7 +660,7 @@ TEST_CASE("[Synth] Apply function on sisters")
|
|||
REQUIRE( sfz::SisterVoiceRing::countSisterVoices(synth.getVoiceView(0)) == 3 );
|
||||
float start = 1.0f;
|
||||
sfz::SisterVoiceRing::applyToRing(synth.getVoiceView(0), [&](const sfz::Voice* v) {
|
||||
start += static_cast<float>(v->getTriggerNumber());
|
||||
start += static_cast<float>(v->getTriggerEvent().number);
|
||||
});
|
||||
REQUIRE( start == 1.0f + 3.0f * 63.0f );
|
||||
}
|
||||
|
|
@ -828,7 +828,7 @@ TEST_CASE("[Synth] Release (Multiple notes, release_key ignores the pedal)")
|
|||
std::vector<float> requiredVelocities { 34_norm, 78_norm, 85_norm};
|
||||
std::vector<float> actualVelocities;
|
||||
for (auto* v: getActiveVoices(synth)) {
|
||||
actualVelocities.push_back(v->getTriggerValue());
|
||||
actualVelocities.push_back(v->getTriggerEvent().value);
|
||||
}
|
||||
sortAll(requiredVelocities, actualVelocities);
|
||||
REQUIRE( requiredVelocities == actualVelocities );
|
||||
|
|
@ -856,7 +856,7 @@ TEST_CASE("[Synth] Release (Multiple notes, release, cleared the delayed voices
|
|||
std::vector<float> requiredVelocities { 34_norm, 78_norm, 85_norm, 34_norm, 78_norm, 85_norm };
|
||||
std::vector<float> actualVelocities;
|
||||
for (auto* v: getActiveVoices(synth)) {
|
||||
actualVelocities.push_back(v->getTriggerValue());
|
||||
actualVelocities.push_back(v->getTriggerEvent().value);
|
||||
}
|
||||
sortAll(requiredVelocities, actualVelocities);
|
||||
REQUIRE( requiredVelocities == actualVelocities );
|
||||
|
|
@ -886,7 +886,7 @@ TEST_CASE("[Synth] Release (Multiple notes after pedal is down, release, cleared
|
|||
std::vector<float> requiredVelocities { 34_norm, 78_norm, 85_norm, 34_norm, 78_norm, 85_norm };
|
||||
std::vector<float> actualVelocities;
|
||||
for (auto* v: getActiveVoices(synth)) {
|
||||
actualVelocities.push_back(v->getTriggerValue());
|
||||
actualVelocities.push_back(v->getTriggerEvent().value);
|
||||
}
|
||||
sortAll(requiredVelocities, actualVelocities);
|
||||
REQUIRE( requiredVelocities == actualVelocities );
|
||||
|
|
@ -914,7 +914,7 @@ TEST_CASE("[Synth] Release (Multiple note ons during pedal down)")
|
|||
std::vector<float> requiredVelocities { 78_norm, 85_norm, 78_norm, 85_norm };
|
||||
std::vector<float> actualVelocities;
|
||||
for (auto* v: getActiveVoices(synth)) {
|
||||
actualVelocities.push_back(v->getTriggerValue());
|
||||
actualVelocities.push_back(v->getTriggerEvent().value);
|
||||
}
|
||||
sortAll(requiredVelocities, actualVelocities);
|
||||
REQUIRE( requiredVelocities == actualVelocities );
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue