Refactor the midistate functions
This commit is contained in:
parent
a1dba6b60f
commit
4c2e0ab6b9
12 changed files with 92 additions and 92 deletions
|
|
@ -55,7 +55,7 @@ namespace sfz
|
||||||
inline float ccSwitchedValue(const MidiState& state, const absl::optional<CCValuePair<float>>& ccSwitch, float value) noexcept
|
inline float ccSwitchedValue(const MidiState& state, const absl::optional<CCValuePair<float>>& ccSwitch, float value) noexcept
|
||||||
{
|
{
|
||||||
if (ccSwitch)
|
if (ccSwitch)
|
||||||
return value + ccSwitch->value * state.getCCValueNormalized(ccSwitch->cc);
|
return value + ccSwitch->value * state.getCCValue(ccSwitch->cc);
|
||||||
else
|
else
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ sfz::MidiState::MidiState()
|
||||||
reset(0);
|
reset(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::MidiState::noteOnEventNormalized(int delay, int noteNumber, float velocity) noexcept
|
void sfz::MidiState::noteOnEvent(int delay, int noteNumber, float velocity) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(noteNumber >= 0 && noteNumber <= 127);
|
ASSERT(noteNumber >= 0 && noteNumber <= 127);
|
||||||
ASSERT(velocity >= 0 && velocity <= 1.0);
|
ASSERT(velocity >= 0 && velocity <= 1.0);
|
||||||
|
|
@ -26,7 +26,7 @@ void sfz::MidiState::noteOnEventNormalized(int delay, int noteNumber, float velo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::MidiState::noteOffEventNormalized(int delay, int noteNumber, float velocity) noexcept
|
void sfz::MidiState::noteOffEvent(int delay, int noteNumber, float velocity) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(noteNumber >= 0 && noteNumber <= 127);
|
ASSERT(noteNumber >= 0 && noteNumber <= 127);
|
||||||
ASSERT(velocity >= 0.0 && velocity <= 1.0);
|
ASSERT(velocity >= 0.0 && velocity <= 1.0);
|
||||||
|
|
@ -51,7 +51,7 @@ float sfz::MidiState::getNoteDuration(int noteNumber) const
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float sfz::MidiState::getNoteVelocityNormalized(int noteNumber) const noexcept
|
float sfz::MidiState::getNoteVelocity(int noteNumber) const noexcept
|
||||||
{
|
{
|
||||||
ASSERT(noteNumber >= 0 && noteNumber <= 127);
|
ASSERT(noteNumber >= 0 && noteNumber <= 127);
|
||||||
|
|
||||||
|
|
@ -71,14 +71,14 @@ int sfz::MidiState::getPitchBend() const noexcept
|
||||||
return pitchBend;
|
return pitchBend;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::MidiState::ccEventNormalized(int delay, int ccNumber, float ccValue) noexcept
|
void sfz::MidiState::ccEvent(int delay, int ccNumber, float ccValue) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(ccValue >= 0.0 && ccValue <= 1.0);
|
ASSERT(ccValue >= 0.0 && ccValue <= 1.0);
|
||||||
|
|
||||||
cc[ccNumber] = ccValue;
|
cc[ccNumber] = ccValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float sfz::MidiState::getCCValueNormalized(int ccNumber) const noexcept
|
float sfz::MidiState::getCCValue(int ccNumber) const noexcept
|
||||||
{
|
{
|
||||||
ASSERT(ccNumber >= 0 && ccNumber < config::numCCs);
|
ASSERT(ccNumber >= 0 && ccNumber < config::numCCs);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ public:
|
||||||
* @param noteNumber
|
* @param noteNumber
|
||||||
* @param velocity
|
* @param velocity
|
||||||
*/
|
*/
|
||||||
void noteOnEventNormalized(int delay, int noteNumber, float velocity) noexcept;
|
void noteOnEvent(int delay, int noteNumber, float velocity) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update the state after a note off event
|
* @brief Update the state after a note off event
|
||||||
|
|
@ -37,7 +37,7 @@ public:
|
||||||
* @param noteNumber
|
* @param noteNumber
|
||||||
* @param velocity
|
* @param velocity
|
||||||
*/
|
*/
|
||||||
void noteOffEventNormalized(int delay, int noteNumber, float velocity) noexcept;
|
void noteOffEvent(int delay, int noteNumber, float velocity) noexcept;
|
||||||
|
|
||||||
int getActiveNotes() const noexcept { return activeNotes; }
|
int getActiveNotes() const noexcept { return activeNotes; }
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ public:
|
||||||
* @param noteNumber
|
* @param noteNumber
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
float getNoteVelocityNormalized(int noteNumber) const noexcept;
|
float getNoteVelocity(int noteNumber) const noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Register a pitch bend event
|
* @brief Register a pitch bend event
|
||||||
|
|
@ -77,7 +77,7 @@ public:
|
||||||
* @param ccNumber
|
* @param ccNumber
|
||||||
* @param ccValue
|
* @param ccValue
|
||||||
*/
|
*/
|
||||||
void ccEventNormalized(int delay, int ccNumber, float ccValue) noexcept;
|
void ccEvent(int delay, int ccNumber, float ccValue) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the CC value for CC number
|
* @brief Get the CC value for CC number
|
||||||
|
|
@ -85,7 +85,7 @@ public:
|
||||||
* @param ccNumber
|
* @param ccNumber
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
float getCCValueNormalized(int ccNumber) const noexcept;
|
float getCCValue(int ccNumber) const noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reset the midi state (does not impact the last note on time)
|
* @brief Reset the midi state (does not impact the last note on time)
|
||||||
|
|
@ -113,7 +113,7 @@ public:
|
||||||
T modulate(T value, const CCMap<U>& modifiers, const Range<T>& validRange, const modFunction<T, U>& lambda = addToBase<T>) const noexcept
|
T modulate(T value, const CCMap<U>& modifiers, const Range<T>& validRange, const modFunction<T, U>& lambda = addToBase<T>) const noexcept
|
||||||
{
|
{
|
||||||
for (auto& mod: modifiers) {
|
for (auto& mod: modifiers) {
|
||||||
lambda(value, getCCValueNormalized(mod.cc) * mod.value);
|
lambda(value, getCCValue(mod.cc) * mod.value);
|
||||||
}
|
}
|
||||||
return validRange.clamp(value);
|
return validRange.clamp(value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1068,13 +1068,13 @@ float sfz::Region::getCrossfadeGain() const noexcept
|
||||||
|
|
||||||
// Crossfades due to CC states
|
// Crossfades due to CC states
|
||||||
for (const auto& valuePair : crossfadeCCInRange) {
|
for (const auto& valuePair : crossfadeCCInRange) {
|
||||||
const auto ccValue = midiState.getCCValueNormalized(valuePair.cc);
|
const auto ccValue = midiState.getCCValue(valuePair.cc);
|
||||||
const auto crossfadeRange = valuePair.value;
|
const auto crossfadeRange = valuePair.value;
|
||||||
gain *= crossfadeIn(crossfadeRange, ccValue, crossfadeCCCurve);
|
gain *= crossfadeIn(crossfadeRange, ccValue, crossfadeCCCurve);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& valuePair : crossfadeCCOutRange) {
|
for (const auto& valuePair : crossfadeCCOutRange) {
|
||||||
const auto ccValue = midiState.getCCValueNormalized(valuePair.cc);
|
const auto ccValue = midiState.getCCValue(valuePair.cc);
|
||||||
const auto crossfadeRange = valuePair.value;
|
const auto crossfadeRange = valuePair.value;
|
||||||
gain *= crossfadeOut(crossfadeRange, ccValue, crossfadeCCCurve);
|
gain *= crossfadeOut(crossfadeRange, ccValue, crossfadeCCCurve);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@ void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members)
|
||||||
if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) {
|
if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) {
|
||||||
const auto ccValue = readOpcode(member.value, Default::midi7Range);
|
const auto ccValue = readOpcode(member.value, Default::midi7Range);
|
||||||
if (ccValue)
|
if (ccValue)
|
||||||
resources.midiState.ccEventNormalized(0, member.parameters.back(), normalizeCC(*ccValue));
|
resources.midiState.ccEvent(0, member.parameters.back(), normalizeCC(*ccValue));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case hash("Label_cc&"): // fallthrough
|
case hash("Label_cc&"): // fallthrough
|
||||||
|
|
@ -387,7 +387,7 @@ bool sfz::Synth::loadSfzFile(const fs::path& file)
|
||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
for (unsigned cc = 0; cc < config::numCCs; cc++) {
|
for (unsigned cc = 0; cc < config::numCCs; cc++) {
|
||||||
region->registerCC(cc, resources.midiState.getCCValueNormalized(cc));
|
region->registerCC(cc, resources.midiState.getCCValue(cc));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultSwitch) {
|
if (defaultSwitch) {
|
||||||
|
|
@ -603,7 +603,7 @@ void sfz::Synth::noteOn(int delay, int noteNumber, uint8_t velocity) noexcept
|
||||||
ASSERT(noteNumber >= 0);
|
ASSERT(noteNumber >= 0);
|
||||||
const auto normalizedVelocity = normalizeVelocity(velocity);
|
const auto normalizedVelocity = normalizeVelocity(velocity);
|
||||||
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
||||||
resources.midiState.noteOnEventNormalized(delay, noteNumber, normalizedVelocity);
|
resources.midiState.noteOnEvent(delay, noteNumber, normalizedVelocity);
|
||||||
|
|
||||||
AtomicGuard callbackGuard { inCallback };
|
AtomicGuard callbackGuard { inCallback };
|
||||||
if (!canEnterCallback)
|
if (!canEnterCallback)
|
||||||
|
|
@ -619,7 +619,7 @@ void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity) noexcept
|
||||||
UNUSED(velocity);
|
UNUSED(velocity);
|
||||||
const auto normalizedVelocity = normalizeVelocity(velocity);
|
const auto normalizedVelocity = normalizeVelocity(velocity);
|
||||||
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
||||||
resources.midiState.noteOffEventNormalized(delay, noteNumber, normalizedVelocity);
|
resources.midiState.noteOffEvent(delay, noteNumber, normalizedVelocity);
|
||||||
|
|
||||||
AtomicGuard callbackGuard { inCallback };
|
AtomicGuard callbackGuard { inCallback };
|
||||||
if (!canEnterCallback)
|
if (!canEnterCallback)
|
||||||
|
|
@ -628,7 +628,7 @@ void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity) noexcept
|
||||||
// FIXME: Some keyboards (e.g. Casio PX5S) can send a real note-off velocity. In this case, do we have a
|
// FIXME: Some keyboards (e.g. Casio PX5S) can send a real note-off velocity. In this case, do we have a
|
||||||
// way in sfz to specify that a release trigger should NOT use the note-on velocity?
|
// way in sfz to specify that a release trigger should NOT use the note-on velocity?
|
||||||
// auto replacedVelocity = (velocity == 0 ? sfz::getNoteVelocity(noteNumber) : velocity);
|
// auto replacedVelocity = (velocity == 0 ? sfz::getNoteVelocity(noteNumber) : velocity);
|
||||||
const auto replacedVelocity = resources.midiState.getNoteVelocityNormalized(noteNumber);
|
const auto replacedVelocity = resources.midiState.getNoteVelocity(noteNumber);
|
||||||
|
|
||||||
for (auto& voice : voices)
|
for (auto& voice : voices)
|
||||||
voice->registerNoteOff(delay, noteNumber, replacedVelocity);
|
voice->registerNoteOff(delay, noteNumber, replacedVelocity);
|
||||||
|
|
@ -676,7 +676,7 @@ void sfz::Synth::cc(int delay, int ccNumber, uint8_t ccValue) noexcept
|
||||||
const auto normalizedCC = normalizeCC(ccValue);
|
const auto normalizedCC = normalizeCC(ccValue);
|
||||||
|
|
||||||
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
||||||
resources.midiState.ccEventNormalized(delay, ccNumber, normalizedCC);
|
resources.midiState.ccEvent(delay, ccNumber, normalizedCC);
|
||||||
|
|
||||||
AtomicGuard callbackGuard { inCallback };
|
AtomicGuard callbackGuard { inCallback };
|
||||||
if (!canEnterCallback)
|
if (!canEnterCallback)
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
|
||||||
baseVolumedB = region->getBaseVolumedB(number);
|
baseVolumedB = region->getBaseVolumedB(number);
|
||||||
auto volumedB = baseVolumedB;
|
auto volumedB = baseVolumedB;
|
||||||
if (region->volumeCC)
|
if (region->volumeCC)
|
||||||
volumedB += resources.midiState.getCCValueNormalized(region->volumeCC->cc) * region->volumeCC->value;
|
volumedB += resources.midiState.getCCValue(region->volumeCC->cc) * region->volumeCC->value;
|
||||||
volumeEnvelope.reset(db2mag(Default::volumeRange.clamp(volumedB)));
|
volumeEnvelope.reset(db2mag(Default::volumeRange.clamp(volumedB)));
|
||||||
|
|
||||||
baseGain = region->getBaseGain();
|
baseGain = region->getBaseGain();
|
||||||
|
|
@ -87,7 +87,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
|
||||||
|
|
||||||
float gain { baseGain };
|
float gain { baseGain };
|
||||||
if (region->amplitudeCC)
|
if (region->amplitudeCC)
|
||||||
gain += resources.midiState.getCCValueNormalized(region->amplitudeCC->cc) * normalizePercents(region->amplitudeCC->value);
|
gain += resources.midiState.getCCValue(region->amplitudeCC->cc) * normalizePercents(region->amplitudeCC->value);
|
||||||
amplitudeEnvelope.reset(Default::normalizedRange.clamp(gain));
|
amplitudeEnvelope.reset(Default::normalizedRange.clamp(gain));
|
||||||
|
|
||||||
float crossfadeGain { region->getCrossfadeGain() };
|
float crossfadeGain { region->getCrossfadeGain() };
|
||||||
|
|
@ -96,19 +96,19 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
|
||||||
basePan = normalizePercents(region->pan);
|
basePan = normalizePercents(region->pan);
|
||||||
auto pan = basePan;
|
auto pan = basePan;
|
||||||
if (region->panCC)
|
if (region->panCC)
|
||||||
pan += resources.midiState.getCCValueNormalized(region->panCC->cc) * normalizePercents(region->panCC->value);
|
pan += resources.midiState.getCCValue(region->panCC->cc) * normalizePercents(region->panCC->value);
|
||||||
panEnvelope.reset(Default::symmetricNormalizedRange.clamp(pan));
|
panEnvelope.reset(Default::symmetricNormalizedRange.clamp(pan));
|
||||||
|
|
||||||
basePosition = normalizePercents(region->position);
|
basePosition = normalizePercents(region->position);
|
||||||
auto position = basePosition;
|
auto position = basePosition;
|
||||||
if (region->positionCC)
|
if (region->positionCC)
|
||||||
position += resources.midiState.getCCValueNormalized(region->positionCC->cc) * normalizePercents(region->positionCC->value);
|
position += resources.midiState.getCCValue(region->positionCC->cc) * normalizePercents(region->positionCC->value);
|
||||||
positionEnvelope.reset(Default::symmetricNormalizedRange.clamp(position));
|
positionEnvelope.reset(Default::symmetricNormalizedRange.clamp(position));
|
||||||
|
|
||||||
baseWidth = normalizePercents(region->width);
|
baseWidth = normalizePercents(region->width);
|
||||||
auto width = baseWidth;
|
auto width = baseWidth;
|
||||||
if (region->widthCC)
|
if (region->widthCC)
|
||||||
width += resources.midiState.getCCValueNormalized(region->widthCC->cc) * normalizePercents(region->widthCC->value);
|
width += resources.midiState.getCCValue(region->widthCC->cc) * normalizePercents(region->widthCC->value);
|
||||||
widthEnvelope.reset(Default::symmetricNormalizedRange.clamp(width));
|
widthEnvelope.reset(Default::symmetricNormalizedRange.clamp(width));
|
||||||
|
|
||||||
pitchBendEnvelope.setFunction([region](float pitchValue){
|
pitchBendEnvelope.setFunction([region](float pitchValue){
|
||||||
|
|
@ -177,7 +177,7 @@ void sfz::Voice::registerNoteOff(int delay, int noteNumber, float velocity) noex
|
||||||
if (region->loopMode == SfzLoopMode::one_shot)
|
if (region->loopMode == SfzLoopMode::one_shot)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!region->checkSustain || resources.midiState.getCCValueNormalized(config::sustainCC) < config::halfCCThreshold)
|
if (!region->checkSustain || resources.midiState.getCCValue(config::sustainCC) < config::halfCCThreshold)
|
||||||
release(delay);
|
release(delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ TEST_CASE("[EGDescription] Attack range")
|
||||||
eg.ccAttack = { 63, 1.27f };
|
eg.ccAttack = { 63, 1.27f };
|
||||||
REQUIRE( eg.getAttack(state, 0) == 1.0f );
|
REQUIRE( eg.getAttack(state, 0) == 1.0f );
|
||||||
REQUIRE( eg.getAttack(state, 127) == 0.0f );
|
REQUIRE( eg.getAttack(state, 127) == 0.0f );
|
||||||
state.ccEventNormalized(0, 63, 127_norm);
|
state.ccEvent(0, 63, 127_norm);
|
||||||
REQUIRE( eg.getAttack(state, 127) == 1.0f );
|
REQUIRE( eg.getAttack(state, 127) == 1.0f );
|
||||||
REQUIRE( eg.getAttack(state, 0) == 2.27f );
|
REQUIRE( eg.getAttack(state, 0) == 2.27f );
|
||||||
eg.ccAttack = { 63, 127.0f };
|
eg.ccAttack = { 63, 127.0f };
|
||||||
|
|
@ -36,7 +36,7 @@ TEST_CASE("[EGDescription] Delay range")
|
||||||
eg.ccDelay = { 63, 1.27f };
|
eg.ccDelay = { 63, 1.27f };
|
||||||
REQUIRE( eg.getDelay(state, 0) == 1.0f );
|
REQUIRE( eg.getDelay(state, 0) == 1.0f );
|
||||||
REQUIRE( eg.getDelay(state, 127) == 0.0f );
|
REQUIRE( eg.getDelay(state, 127) == 0.0f );
|
||||||
state.ccEventNormalized(0, 63, 127_norm);
|
state.ccEvent(0, 63, 127_norm);
|
||||||
REQUIRE( eg.getDelay(state, 127) == 1.0f );
|
REQUIRE( eg.getDelay(state, 127) == 1.0f );
|
||||||
REQUIRE( eg.getDelay(state, 0) == 2.27f );
|
REQUIRE( eg.getDelay(state, 0) == 2.27f );
|
||||||
eg.ccDelay = { 63, 127.0f };
|
eg.ccDelay = { 63, 127.0f };
|
||||||
|
|
@ -52,7 +52,7 @@ TEST_CASE("[EGDescription] Decay range")
|
||||||
eg.ccDecay = { 63, 1.27f };
|
eg.ccDecay = { 63, 1.27f };
|
||||||
REQUIRE( eg.getDecay(state, 0) == 1.0f );
|
REQUIRE( eg.getDecay(state, 0) == 1.0f );
|
||||||
REQUIRE( eg.getDecay(state, 127) == 0.0f );
|
REQUIRE( eg.getDecay(state, 127) == 0.0f );
|
||||||
state.ccEventNormalized(0, 63, 127_norm);
|
state.ccEvent(0, 63, 127_norm);
|
||||||
REQUIRE( eg.getDecay(state, 127) == 1.0f );
|
REQUIRE( eg.getDecay(state, 127) == 1.0f );
|
||||||
REQUIRE( eg.getDecay(state, 0) == 2.27f );
|
REQUIRE( eg.getDecay(state, 0) == 2.27f );
|
||||||
eg.ccDecay = { 63, 127.0f };
|
eg.ccDecay = { 63, 127.0f };
|
||||||
|
|
@ -68,7 +68,7 @@ TEST_CASE("[EGDescription] Release range")
|
||||||
eg.ccRelease = { 63, 1.27f };
|
eg.ccRelease = { 63, 1.27f };
|
||||||
REQUIRE( eg.getRelease(state, 0) == 1.0f );
|
REQUIRE( eg.getRelease(state, 0) == 1.0f );
|
||||||
REQUIRE( eg.getRelease(state, 127) == 0.0f );
|
REQUIRE( eg.getRelease(state, 127) == 0.0f );
|
||||||
state.ccEventNormalized(0, 63, 127_norm);
|
state.ccEvent(0, 63, 127_norm);
|
||||||
REQUIRE( eg.getRelease(state, 127) == 1.0f );
|
REQUIRE( eg.getRelease(state, 127) == 1.0f );
|
||||||
REQUIRE( eg.getRelease(state, 0) == 2.27f );
|
REQUIRE( eg.getRelease(state, 0) == 2.27f );
|
||||||
eg.ccRelease = { 63, 127.0f };
|
eg.ccRelease = { 63, 127.0f };
|
||||||
|
|
@ -84,7 +84,7 @@ TEST_CASE("[EGDescription] Hold range")
|
||||||
eg.ccHold = { 63, 1.27f };
|
eg.ccHold = { 63, 1.27f };
|
||||||
REQUIRE( eg.getHold(state, 0) == 1.0f );
|
REQUIRE( eg.getHold(state, 0) == 1.0f );
|
||||||
REQUIRE( eg.getHold(state, 127) == 0.0f );
|
REQUIRE( eg.getHold(state, 127) == 0.0f );
|
||||||
state.ccEventNormalized(0, 63, 127_norm);
|
state.ccEvent(0, 63, 127_norm);
|
||||||
REQUIRE( eg.getHold(state, 127) == 1.0f );
|
REQUIRE( eg.getHold(state, 127) == 1.0f );
|
||||||
REQUIRE( eg.getHold(state, 0) == 2.27f );
|
REQUIRE( eg.getHold(state, 0) == 2.27f );
|
||||||
eg.ccHold = { 63, 127.0f };
|
eg.ccHold = { 63, 127.0f };
|
||||||
|
|
@ -100,7 +100,7 @@ TEST_CASE("[EGDescription] Sustain level")
|
||||||
eg.ccSustain = { 63, 100.0f };
|
eg.ccSustain = { 63, 100.0f };
|
||||||
REQUIRE( eg.getSustain(state, 0) == 50.0f );
|
REQUIRE( eg.getSustain(state, 0) == 50.0f );
|
||||||
REQUIRE( eg.getSustain(state, 127) == 0.0f );
|
REQUIRE( eg.getSustain(state, 127) == 0.0f );
|
||||||
state.ccEventNormalized(0, 63, 127_norm);
|
state.ccEvent(0, 63, 127_norm);
|
||||||
REQUIRE( eg.getSustain(state, 127) == 50.0f );
|
REQUIRE( eg.getSustain(state, 127) == 50.0f );
|
||||||
eg.ccSustain = { 63, 200.0f };
|
eg.ccSustain = { 63, 200.0f };
|
||||||
REQUIRE( eg.getSustain(state, 0) == 100.0f );
|
REQUIRE( eg.getSustain(state, 0) == 100.0f );
|
||||||
|
|
@ -114,7 +114,7 @@ TEST_CASE("[EGDescription] Start level")
|
||||||
eg.ccStart = { 63, 127.0f };
|
eg.ccStart = { 63, 127.0f };
|
||||||
REQUIRE( eg.getStart(state, 0) == 0.0f );
|
REQUIRE( eg.getStart(state, 0) == 0.0f );
|
||||||
REQUIRE( eg.getStart(state, 127) == 0.0f );
|
REQUIRE( eg.getStart(state, 127) == 0.0f );
|
||||||
state.ccEventNormalized(0, 63, 127_norm);
|
state.ccEvent(0, 63, 127_norm);
|
||||||
REQUIRE( eg.getStart(state, 0) == 100.0f );
|
REQUIRE( eg.getStart(state, 0) == 100.0f );
|
||||||
eg.ccStart = { 63, -127.0f };
|
eg.ccStart = { 63, -127.0f };
|
||||||
REQUIRE( eg.getStart(state, 0) == 0.0f );
|
REQUIRE( eg.getStart(state, 0) == 0.0f );
|
||||||
|
|
|
||||||
|
|
@ -355,8 +355,8 @@ TEST_CASE("[Files] Set CC applies properly")
|
||||||
{
|
{
|
||||||
sfz::Synth synth;
|
sfz::Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/set_cc.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/set_cc.sfz");
|
||||||
REQUIRE(synth.getMidiState().getCCValueNormalized(142) == 63_norm);
|
REQUIRE(synth.getMidiState().getCCValue(142) == 63_norm);
|
||||||
REQUIRE(synth.getMidiState().getCCValueNormalized(61) == 122_norm);
|
REQUIRE(synth.getMidiState().getCCValue(61) == 122_norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Note and octave offsets")
|
TEST_CASE("[Files] Note and octave offsets")
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,17 @@ TEST_CASE("[MidiState] Initial values")
|
||||||
{
|
{
|
||||||
sfz::MidiState state;
|
sfz::MidiState state;
|
||||||
for (unsigned cc = 0; cc < sfz::config::numCCs; cc++)
|
for (unsigned cc = 0; cc < sfz::config::numCCs; cc++)
|
||||||
REQUIRE( state.getCCValueNormalized(cc) == 0_norm );
|
REQUIRE( state.getCCValue(cc) == 0_norm );
|
||||||
REQUIRE( state.getPitchBend() == 0 );
|
REQUIRE( state.getPitchBend() == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MidiState] Set and get CCs")
|
TEST_CASE("[MidiState] Set and get CCs")
|
||||||
{
|
{
|
||||||
sfz::MidiState state;
|
sfz::MidiState state;
|
||||||
state.ccEventNormalized(0, 24, 23_norm);
|
state.ccEvent(0, 24, 23_norm);
|
||||||
state.ccEventNormalized(0, 123, 124_norm);
|
state.ccEvent(0, 123, 124_norm);
|
||||||
REQUIRE(state.getCCValueNormalized(24) == 23_norm);
|
REQUIRE(state.getCCValue(24) == 23_norm);
|
||||||
REQUIRE(state.getCCValueNormalized(123) == 124_norm);
|
REQUIRE(state.getCCValue(123) == 124_norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MidiState] Set and get pitch bends")
|
TEST_CASE("[MidiState] Set and get pitch bends")
|
||||||
|
|
@ -47,25 +47,25 @@ TEST_CASE("[MidiState] Reset")
|
||||||
{
|
{
|
||||||
sfz::MidiState state;
|
sfz::MidiState state;
|
||||||
state.pitchBendEvent(0, 894);
|
state.pitchBendEvent(0, 894);
|
||||||
state.noteOnEventNormalized(0, 64, 24_norm);
|
state.noteOnEvent(0, 64, 24_norm);
|
||||||
state.ccEventNormalized(0, 123, 124_norm);
|
state.ccEvent(0, 123, 124_norm);
|
||||||
state.reset(0);
|
state.reset(0);
|
||||||
REQUIRE(state.getPitchBend() == 0);
|
REQUIRE(state.getPitchBend() == 0);
|
||||||
REQUIRE(state.getNoteVelocityNormalized(64) == 0_norm);
|
REQUIRE(state.getNoteVelocity(64) == 0_norm);
|
||||||
REQUIRE(state.getCCValueNormalized(123) == 0_norm);
|
REQUIRE(state.getCCValue(123) == 0_norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MidiState] Set and get note velocities")
|
TEST_CASE("[MidiState] Set and get note velocities")
|
||||||
{
|
{
|
||||||
sfz::MidiState state;
|
sfz::MidiState state;
|
||||||
state.noteOnEventNormalized(0, 64, 24_norm);
|
state.noteOnEvent(0, 64, 24_norm);
|
||||||
REQUIRE(+state.getNoteVelocityNormalized(64) == 24_norm);
|
REQUIRE(+state.getNoteVelocity(64) == 24_norm);
|
||||||
state.noteOnEventNormalized(0, 64, 123_norm);
|
state.noteOnEvent(0, 64, 123_norm);
|
||||||
REQUIRE(+state.getNoteVelocityNormalized(64) == 123_norm);
|
REQUIRE(+state.getNoteVelocity(64) == 123_norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MidiState] Extended CCs")
|
TEST_CASE("[MidiState] Extended CCs")
|
||||||
{
|
{
|
||||||
sfz::MidiState state;
|
sfz::MidiState state;
|
||||||
state.ccEventNormalized(0, 142, 64_norm); // should not trap
|
state.ccEvent(0, 142, 64_norm); // should not trap
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,15 +137,15 @@ TEST_CASE("Legato triggers", "Region triggers")
|
||||||
region.parseOpcode({ "lokey", "40" });
|
region.parseOpcode({ "lokey", "40" });
|
||||||
region.parseOpcode({ "hikey", "50" });
|
region.parseOpcode({ "hikey", "50" });
|
||||||
region.parseOpcode({ "trigger", "first" });
|
region.parseOpcode({ "trigger", "first" });
|
||||||
midiState.noteOnEventNormalized(0, 40, 64_norm);
|
midiState.noteOnEvent(0, 40, 64_norm);
|
||||||
REQUIRE(region.registerNoteOn(40, 64_norm, 0.5f));
|
REQUIRE(region.registerNoteOn(40, 64_norm, 0.5f));
|
||||||
midiState.noteOnEventNormalized(0, 41, 64_norm);
|
midiState.noteOnEvent(0, 41, 64_norm);
|
||||||
REQUIRE(!region.registerNoteOn(41, 64_norm, 0.5f));
|
REQUIRE(!region.registerNoteOn(41, 64_norm, 0.5f));
|
||||||
midiState.noteOffEventNormalized(0, 40, 0_norm);
|
midiState.noteOffEvent(0, 40, 0_norm);
|
||||||
region.registerNoteOff(40, 0_norm, 0.5f);
|
region.registerNoteOff(40, 0_norm, 0.5f);
|
||||||
midiState.noteOffEventNormalized(0, 41, 0_norm);
|
midiState.noteOffEvent(0, 41, 0_norm);
|
||||||
region.registerNoteOff(41, 0_norm, 0.5f);
|
region.registerNoteOff(41, 0_norm, 0.5f);
|
||||||
midiState.noteOnEventNormalized(0, 42, 64_norm);
|
midiState.noteOnEvent(0, 42, 64_norm);
|
||||||
REQUIRE(region.registerNoteOn(42, 64_norm, 0.5f));
|
REQUIRE(region.registerNoteOn(42, 64_norm, 0.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,15 +154,15 @@ TEST_CASE("Legato triggers", "Region triggers")
|
||||||
region.parseOpcode({ "lokey", "40" });
|
region.parseOpcode({ "lokey", "40" });
|
||||||
region.parseOpcode({ "hikey", "50" });
|
region.parseOpcode({ "hikey", "50" });
|
||||||
region.parseOpcode({ "trigger", "legato" });
|
region.parseOpcode({ "trigger", "legato" });
|
||||||
midiState.noteOnEventNormalized(0, 40, 64_norm);
|
midiState.noteOnEvent(0, 40, 64_norm);
|
||||||
REQUIRE(!region.registerNoteOn(40, 64_norm, 0.5f));
|
REQUIRE(!region.registerNoteOn(40, 64_norm, 0.5f));
|
||||||
midiState.noteOnEventNormalized(0, 41, 64_norm);
|
midiState.noteOnEvent(0, 41, 64_norm);
|
||||||
REQUIRE(region.registerNoteOn(41, 64_norm, 0.5f));
|
REQUIRE(region.registerNoteOn(41, 64_norm, 0.5f));
|
||||||
midiState.noteOffEventNormalized(0, 40, 64_norm);
|
midiState.noteOffEvent(0, 40, 64_norm);
|
||||||
region.registerNoteOff(40, 0_norm, 0.5f);
|
region.registerNoteOff(40, 0_norm, 0.5f);
|
||||||
midiState.noteOffEventNormalized(0, 41, 64_norm);
|
midiState.noteOffEvent(0, 41, 64_norm);
|
||||||
region.registerNoteOff(41, 0_norm, 0.5f);
|
region.registerNoteOff(41, 0_norm, 0.5f);
|
||||||
midiState.noteOnEventNormalized(0, 42, 64_norm);
|
midiState.noteOnEvent(0, 42, 64_norm);
|
||||||
REQUIRE(!region.registerNoteOn(42, 64_norm, 0.5f));
|
REQUIRE(!region.registerNoteOn(42, 64_norm, 0.5f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,13 +167,13 @@ TEST_CASE("[Region] Crossfade in on CC")
|
||||||
region.parseOpcode({ "xfin_locc24", "20" });
|
region.parseOpcode({ "xfin_locc24", "20" });
|
||||||
region.parseOpcode({ "xfin_hicc24", "24" });
|
region.parseOpcode({ "xfin_hicc24", "24" });
|
||||||
region.parseOpcode({ "amp_veltrack", "0" });
|
region.parseOpcode({ "amp_veltrack", "0" });
|
||||||
midiState.ccEventNormalized(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
midiState.ccEvent(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
midiState.ccEvent(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
midiState.ccEvent(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
||||||
midiState.ccEventNormalized(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.70711_a );
|
midiState.ccEvent(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.70711_a );
|
||||||
midiState.ccEventNormalized(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.86603_a );
|
midiState.ccEvent(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.86603_a );
|
||||||
midiState.ccEventNormalized(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
midiState.ccEvent(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
midiState.ccEvent(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Region] Crossfade in on CC - gain")
|
TEST_CASE("[Region] Crossfade in on CC - gain")
|
||||||
|
|
@ -185,13 +185,13 @@ TEST_CASE("[Region] Crossfade in on CC - gain")
|
||||||
region.parseOpcode({ "xfin_hicc24", "24" });
|
region.parseOpcode({ "xfin_hicc24", "24" });
|
||||||
region.parseOpcode({ "amp_veltrack", "0" });
|
region.parseOpcode({ "amp_veltrack", "0" });
|
||||||
region.parseOpcode({ "xf_cccurve", "gain" });
|
region.parseOpcode({ "xf_cccurve", "gain" });
|
||||||
midiState.ccEventNormalized(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
midiState.ccEvent(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
midiState.ccEvent(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.25_a );
|
midiState.ccEvent(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.25_a );
|
||||||
midiState.ccEventNormalized(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
midiState.ccEvent(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
||||||
midiState.ccEventNormalized(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.75_a );
|
midiState.ccEvent(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.75_a );
|
||||||
midiState.ccEventNormalized(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
midiState.ccEvent(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
midiState.ccEvent(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||||
}
|
}
|
||||||
TEST_CASE("[Region] Crossfade out on CC")
|
TEST_CASE("[Region] Crossfade out on CC")
|
||||||
{
|
{
|
||||||
|
|
@ -201,13 +201,13 @@ TEST_CASE("[Region] Crossfade out on CC")
|
||||||
region.parseOpcode({ "xfout_locc24", "20" });
|
region.parseOpcode({ "xfout_locc24", "20" });
|
||||||
region.parseOpcode({ "xfout_hicc24", "24" });
|
region.parseOpcode({ "xfout_hicc24", "24" });
|
||||||
region.parseOpcode({ "amp_veltrack", "0" });
|
region.parseOpcode({ "amp_veltrack", "0" });
|
||||||
midiState.ccEventNormalized(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
midiState.ccEvent(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
midiState.ccEvent(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.86603_a );
|
midiState.ccEvent(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.86603_a );
|
||||||
midiState.ccEventNormalized(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.70711_a );
|
midiState.ccEvent(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.70711_a );
|
||||||
midiState.ccEventNormalized(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
midiState.ccEvent(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
||||||
midiState.ccEventNormalized(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
midiState.ccEvent(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
midiState.ccEvent(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Region] Crossfade out on CC - gain")
|
TEST_CASE("[Region] Crossfade out on CC - gain")
|
||||||
|
|
@ -219,13 +219,13 @@ TEST_CASE("[Region] Crossfade out on CC - gain")
|
||||||
region.parseOpcode({ "xfout_hicc24", "24" });
|
region.parseOpcode({ "xfout_hicc24", "24" });
|
||||||
region.parseOpcode({ "amp_veltrack", "0" });
|
region.parseOpcode({ "amp_veltrack", "0" });
|
||||||
region.parseOpcode({ "xf_cccurve", "gain" });
|
region.parseOpcode({ "xf_cccurve", "gain" });
|
||||||
midiState.ccEventNormalized(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
midiState.ccEvent(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
midiState.ccEvent(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.75_a );
|
midiState.ccEvent(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.75_a );
|
||||||
midiState.ccEventNormalized(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
midiState.ccEvent(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
||||||
midiState.ccEventNormalized(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.25_a );
|
midiState.ccEvent(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.25_a );
|
||||||
midiState.ccEventNormalized(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
midiState.ccEvent(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||||
midiState.ccEventNormalized(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
midiState.ccEvent(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Region] Velocity bug for extreme values - veltrack at 0")
|
TEST_CASE("[Region] Velocity bug for extreme values - veltrack at 0")
|
||||||
|
|
@ -266,15 +266,15 @@ TEST_CASE("[Region] rt_decay")
|
||||||
region.parseOpcode({ "sample", "*sine" });
|
region.parseOpcode({ "sample", "*sine" });
|
||||||
region.parseOpcode({ "trigger", "release" });
|
region.parseOpcode({ "trigger", "release" });
|
||||||
region.parseOpcode({ "rt_decay", "10" });
|
region.parseOpcode({ "rt_decay", "10" });
|
||||||
midiState.noteOnEventNormalized(0, 64, 64_norm);
|
midiState.noteOnEvent(0, 64, 64_norm);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
REQUIRE( region.getBaseVolumedB(64) == Approx(sfz::Default::volume - 1.0f).margin(0.1) );
|
REQUIRE( region.getBaseVolumedB(64) == Approx(sfz::Default::volume - 1.0f).margin(0.1) );
|
||||||
region.parseOpcode({ "rt_decay", "20" });
|
region.parseOpcode({ "rt_decay", "20" });
|
||||||
midiState.noteOnEventNormalized(0, 64, 64_norm);
|
midiState.noteOnEvent(0, 64, 64_norm);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
REQUIRE( region.getBaseVolumedB(64) == Approx(sfz::Default::volume - 2.0f).margin(0.1) );
|
REQUIRE( region.getBaseVolumedB(64) == Approx(sfz::Default::volume - 2.0f).margin(0.1) );
|
||||||
region.parseOpcode({ "trigger", "attack" });
|
region.parseOpcode({ "trigger", "attack" });
|
||||||
midiState.noteOnEventNormalized(0, 64, 64_norm);
|
midiState.noteOnEvent(0, 64, 64_norm);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
REQUIRE( region.getBaseVolumedB(64) == Approx(sfz::Default::volume).margin(0.1) );
|
REQUIRE( region.getBaseVolumedB(64) == Approx(sfz::Default::volume).margin(0.1) );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,9 +141,9 @@ TEST_CASE("[Synth] Reset all controllers")
|
||||||
{
|
{
|
||||||
sfz::Synth synth;
|
sfz::Synth synth;
|
||||||
synth.cc(0, 12, 64);
|
synth.cc(0, 12, 64);
|
||||||
REQUIRE( synth.getMidiState().getCCValueNormalized(12) == 64_norm );
|
REQUIRE( synth.getMidiState().getCCValue(12) == 64_norm );
|
||||||
synth.cc(0, 121, 64);
|
synth.cc(0, 121, 64);
|
||||||
REQUIRE( synth.getMidiState().getCCValueNormalized(12) == 0_norm );
|
REQUIRE( synth.getMidiState().getCCValue(12) == 0_norm );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Synth] Releasing before the EG started smoothing (initial delay) kills the voice")
|
TEST_CASE("[Synth] Releasing before the EG started smoothing (initial delay) kills the voice")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue