Use a trigger event type instead of passing 3 parameters

This commit is contained in:
Paul Ferrand 2020-08-25 20:47:51 +02:00
parent afae38e6c3
commit dda10e8530
7 changed files with 117 additions and 96 deletions

View file

@ -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);

View file

@ -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
View 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;
};
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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());
}

View file

@ -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 );