Merge pull request #300 from paulfd/eg-modifiers

ampeg_XX_oncc can now contain multiple modifiers
This commit is contained in:
Paul Ferrand 2020-07-02 08:52:10 +02:00 committed by GitHub
commit e99ec8d94b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 227 additions and 77 deletions

View file

@ -80,13 +80,13 @@ struct EGDescription {
float vel2sustain { Default::vel2sustain }; float vel2sustain { Default::vel2sustain };
int vel2depth { Default::depth }; int vel2depth { Default::depth };
absl::optional<CCData<float>> ccAttack; CCMap<float> ccAttack;
absl::optional<CCData<float>> ccDecay; CCMap<float> ccDecay;
absl::optional<CCData<float>> ccDelay; CCMap<float> ccDelay;
absl::optional<CCData<float>> ccHold; CCMap<float> ccHold;
absl::optional<CCData<float>> ccRelease; CCMap<float> ccRelease;
absl::optional<CCData<float>> ccStart; CCMap<float> ccStart;
absl::optional<CCData<float>> ccSustain; CCMap<float> ccSustain;
/** /**
* @brief Get the attack with possibly a CC modifier and a velocity modifier * @brief Get the attack with possibly a CC modifier and a velocity modifier
@ -98,7 +98,11 @@ struct EGDescription {
float getAttack(const MidiState& state, float velocity) const noexcept float getAttack(const MidiState& state, float velocity) const noexcept
{ {
ASSERT(velocity >= 0.0f && velocity <= 1.0f); ASSERT(velocity >= 0.0f && velocity <= 1.0f);
return Default::egTimeRange.clamp(ccSwitchedValue(state, ccAttack, attack) + velocity * vel2attack); float returnedValue { attack + velocity * vel2attack };
for (auto& mod: ccAttack) {
returnedValue += state.getCCValue(mod.cc) * mod.data;
}
return Default::egTimeRange.clamp(returnedValue);
} }
/** /**
* @brief Get the decay with possibly a CC modifier and a velocity modifier * @brief Get the decay with possibly a CC modifier and a velocity modifier
@ -110,7 +114,11 @@ struct EGDescription {
float getDecay(const MidiState& state, float velocity) const noexcept float getDecay(const MidiState& state, float velocity) const noexcept
{ {
ASSERT(velocity >= 0.0f && velocity <= 1.0f); ASSERT(velocity >= 0.0f && velocity <= 1.0f);
return Default::egTimeRange.clamp(ccSwitchedValue(state, ccDecay, decay) + velocity * vel2decay); float returnedValue { decay + velocity * vel2decay };
for (auto& mod: ccDecay) {
returnedValue += state.getCCValue(mod.cc) * mod.data;
}
return Default::egTimeRange.clamp(returnedValue);
} }
/** /**
* @brief Get the delay with possibly a CC modifier and a velocity modifier * @brief Get the delay with possibly a CC modifier and a velocity modifier
@ -122,7 +130,11 @@ struct EGDescription {
float getDelay(const MidiState& state, float velocity) const noexcept float getDelay(const MidiState& state, float velocity) const noexcept
{ {
ASSERT(velocity >= 0.0f && velocity <= 1.0f); ASSERT(velocity >= 0.0f && velocity <= 1.0f);
return Default::egTimeRange.clamp(ccSwitchedValue(state, ccDelay, delay) + velocity * vel2delay); float returnedValue { delay + velocity * vel2delay };
for (auto& mod: ccDelay) {
returnedValue += state.getCCValue(mod.cc) * mod.data;
}
return Default::egTimeRange.clamp(returnedValue);
} }
/** /**
* @brief Get the holding duration with possibly a CC modifier and a velocity modifier * @brief Get the holding duration with possibly a CC modifier and a velocity modifier
@ -134,7 +146,11 @@ struct EGDescription {
float getHold(const MidiState& state, float velocity) const noexcept float getHold(const MidiState& state, float velocity) const noexcept
{ {
ASSERT(velocity >= 0.0f && velocity <= 1.0f); ASSERT(velocity >= 0.0f && velocity <= 1.0f);
return Default::egTimeRange.clamp(ccSwitchedValue(state, ccHold, hold) + velocity * vel2hold); float returnedValue { hold + velocity * vel2hold };
for (auto& mod: ccHold) {
returnedValue += state.getCCValue(mod.cc) * mod.data;
}
return Default::egTimeRange.clamp(returnedValue);
} }
/** /**
* @brief Get the release duration with possibly a CC modifier and a velocity modifier * @brief Get the release duration with possibly a CC modifier and a velocity modifier
@ -146,7 +162,11 @@ struct EGDescription {
float getRelease(const MidiState& state, float velocity) const noexcept float getRelease(const MidiState& state, float velocity) const noexcept
{ {
ASSERT(velocity >= 0.0f && velocity <= 1.0f); ASSERT(velocity >= 0.0f && velocity <= 1.0f);
return Default::egTimeRange.clamp(ccSwitchedValue(state, ccRelease, release) + velocity * vel2release); float returnedValue { release + velocity * vel2release };
for (auto& mod: ccRelease) {
returnedValue += state.getCCValue(mod.cc) * mod.data;
}
return Default::egTimeRange.clamp(returnedValue);
} }
/** /**
* @brief Get the starting level with possibly a CC modifier and a velocity modifier * @brief Get the starting level with possibly a CC modifier and a velocity modifier
@ -158,7 +178,11 @@ struct EGDescription {
float getStart(const MidiState& state, float velocity) const noexcept float getStart(const MidiState& state, float velocity) const noexcept
{ {
UNUSED(velocity); UNUSED(velocity);
return Default::egPercentRange.clamp(ccSwitchedValue(state, ccStart, start)); float returnedValue { start };
for (auto& mod: ccStart) {
returnedValue += state.getCCValue(mod.cc) * mod.data;
}
return Default::egPercentRange.clamp(returnedValue);
} }
/** /**
* @brief Get the sustain level with possibly a CC modifier and a velocity modifier * @brief Get the sustain level with possibly a CC modifier and a velocity modifier
@ -170,7 +194,11 @@ struct EGDescription {
float getSustain(const MidiState& state, float velocity) const noexcept float getSustain(const MidiState& state, float velocity) const noexcept
{ {
ASSERT(velocity >= 0.0f && velocity <= 1.0f); ASSERT(velocity >= 0.0f && velocity <= 1.0f);
return Default::egPercentRange.clamp(ccSwitchedValue(state, ccSustain, sustain) + velocity * vel2sustain); float returnedValue { sustain + velocity * vel2sustain };
for (auto& mod: ccSustain) {
returnedValue += state.getCCValue(mod.cc) * mod.data;
}
return Default::egPercentRange.clamp(returnedValue);
} }
LEAK_DETECTOR(EGDescription); LEAK_DETECTOR(EGDescription);
}; };

View file

@ -816,25 +816,60 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
setValueFromOpcode(opcode, amplitudeEG.vel2sustain, Default::egOnCCPercentRange); setValueFromOpcode(opcode, amplitudeEG.vel2sustain, Default::egOnCCPercentRange);
break; break;
case hash("ampeg_attack_oncc&"): // also ampeg_attackcc& case hash("ampeg_attack_oncc&"): // also ampeg_attackcc&
setCCPairFromOpcode(opcode, amplitudeEG.ccAttack, Default::egOnCCTimeRange); if (opcode.parameters.back() >= config::numCCs)
return false;
if (auto value = readOpcode(opcode.value, Default::egOnCCTimeRange))
amplitudeEG.ccAttack[opcode.parameters.back()] = *value;
break; break;
case hash("ampeg_decay_oncc&"): // also ampeg_decaycc& case hash("ampeg_decay_oncc&"): // also ampeg_decaycc&
setCCPairFromOpcode(opcode, amplitudeEG.ccDecay, Default::egOnCCTimeRange); if (opcode.parameters.back() >= config::numCCs)
return false;
if (auto value = readOpcode(opcode.value, Default::egOnCCTimeRange))
amplitudeEG.ccDecay[opcode.parameters.back()] = *value;
break; break;
case hash("ampeg_delay_oncc&"): // also ampeg_delaycc& case hash("ampeg_delay_oncc&"): // also ampeg_delaycc&
setCCPairFromOpcode(opcode, amplitudeEG.ccDelay, Default::egOnCCTimeRange); if (opcode.parameters.back() >= config::numCCs)
return false;
if (auto value = readOpcode(opcode.value, Default::egOnCCTimeRange))
amplitudeEG.ccDelay[opcode.parameters.back()] = *value;
break; break;
case hash("ampeg_hold_oncc&"): // also ampeg_holdcc& case hash("ampeg_hold_oncc&"): // also ampeg_holdcc&
setCCPairFromOpcode(opcode, amplitudeEG.ccHold, Default::egOnCCTimeRange); if (opcode.parameters.back() >= config::numCCs)
return false;
if (auto value = readOpcode(opcode.value, Default::egOnCCTimeRange))
amplitudeEG.ccHold[opcode.parameters.back()] = *value;
break; break;
case hash("ampeg_release_oncc&"): // also ampeg_releasecc& case hash("ampeg_release_oncc&"): // also ampeg_releasecc&
setCCPairFromOpcode(opcode, amplitudeEG.ccRelease, Default::egOnCCTimeRange); if (opcode.parameters.back() >= config::numCCs)
return false;
if (auto value = readOpcode(opcode.value, Default::egOnCCTimeRange))
amplitudeEG.ccRelease[opcode.parameters.back()] = *value;
break; break;
case hash("ampeg_start_oncc&"): // also ampeg_startcc& case hash("ampeg_start_oncc&"): // also ampeg_startcc&
setCCPairFromOpcode(opcode, amplitudeEG.ccStart, Default::egOnCCPercentRange); if (opcode.parameters.back() >= config::numCCs)
return false;
if (auto value = readOpcode(opcode.value, Default::egOnCCPercentRange))
amplitudeEG.ccStart[opcode.parameters.back()] = *value;
break; break;
case hash("ampeg_sustain_oncc&"): // also ampeg_sustaincc& case hash("ampeg_sustain_oncc&"): // also ampeg_sustaincc&
setCCPairFromOpcode(opcode, amplitudeEG.ccSustain, Default::egOnCCPercentRange); if (opcode.parameters.back() >= config::numCCs)
return false;
if (auto value = readOpcode(opcode.value, Default::egOnCCPercentRange))
amplitudeEG.ccSustain[opcode.parameters.back()] = *value;
break; break;
case hash("effect&"): case hash("effect&"):

View file

@ -17,14 +17,21 @@ TEST_CASE("[EGDescription] Attack range")
sfz::MidiState state; sfz::MidiState state;
eg.attack = 1; eg.attack = 1;
eg.vel2attack = -1.27f; eg.vel2attack = -1.27f;
eg.ccAttack = { 63, 1.27f }; eg.ccAttack[63] = 1.27f;
REQUIRE(eg.getAttack(state, 0_norm) == 1.0f); REQUIRE(eg.getAttack(state, 0_norm) == 1.0f);
REQUIRE(eg.getAttack(state, 127_norm) == 0.0f); REQUIRE(eg.getAttack(state, 127_norm) == 0.0f);
state.ccEvent(0, 63, 127_norm); state.ccEvent(0, 63, 127_norm);
REQUIRE(eg.getAttack(state, 127_norm) == 1.0f); REQUIRE(eg.getAttack(state, 127_norm) == 1.0f);
REQUIRE(eg.getAttack(state, 0_norm) == 2.27f); REQUIRE(eg.getAttack(state, 0_norm) == 2.27f);
eg.ccAttack = { 63, 127.0f }; eg.ccAttack[63] = 127.0f;
REQUIRE(eg.getAttack(state, 0_norm) == 100.0f); REQUIRE(eg.getAttack(state, 0_norm) == 100.0f);
eg.ccAttack[63] = 1.27f;
eg.ccAttack[65] = 1.0f;
REQUIRE(eg.getAttack(state, 0_norm) == 2.27f);
REQUIRE(eg.getAttack(state, 127_norm) == 1.0f);
state.ccEvent(0, 65, 127_norm);
REQUIRE(eg.getAttack(state, 0_norm) == 3.27f);
REQUIRE(eg.getAttack(state, 127_norm) == 2.0f);
} }
TEST_CASE("[EGDescription] Delay range") TEST_CASE("[EGDescription] Delay range")
@ -33,14 +40,21 @@ TEST_CASE("[EGDescription] Delay range")
sfz::MidiState state; sfz::MidiState state;
eg.delay = 1; eg.delay = 1;
eg.vel2delay = -1.27f; eg.vel2delay = -1.27f;
eg.ccDelay = { 63, 1.27f }; eg.ccDelay[63] = 1.27f;
REQUIRE(eg.getDelay(state, 0_norm) == 1.0f); REQUIRE(eg.getDelay(state, 0_norm) == 1.0f);
REQUIRE(eg.getDelay(state, 127_norm) == 0.0f); REQUIRE(eg.getDelay(state, 127_norm) == 0.0f);
state.ccEvent(0, 63, 127_norm); state.ccEvent(0, 63, 127_norm);
REQUIRE(eg.getDelay(state, 127_norm) == 1.0f); REQUIRE(eg.getDelay(state, 127_norm) == 1.0f);
REQUIRE(eg.getDelay(state, 0_norm) == 2.27f); REQUIRE(eg.getDelay(state, 0_norm) == 2.27f);
eg.ccDelay = { 63, 127.0f }; eg.ccDelay[63] = 127.0f;
REQUIRE(eg.getDelay(state, 0_norm) == 100.0f); REQUIRE(eg.getDelay(state, 0_norm) == 100.0f);
eg.ccDelay[63] = 1.27f;
eg.ccDelay[65] = 1.0f;
REQUIRE(eg.getDelay(state, 0_norm) == 2.27f);
REQUIRE(eg.getDelay(state, 127_norm) == 1.0f);
state.ccEvent(0, 65, 127_norm);
REQUIRE(eg.getDelay(state, 0_norm) == 3.27f);
REQUIRE(eg.getDelay(state, 127_norm) == 2.0f);
} }
TEST_CASE("[EGDescription] Decay range") TEST_CASE("[EGDescription] Decay range")
@ -49,14 +63,21 @@ TEST_CASE("[EGDescription] Decay range")
sfz::MidiState state; sfz::MidiState state;
eg.decay = 1.0f; eg.decay = 1.0f;
eg.vel2decay = -1.27f; eg.vel2decay = -1.27f;
eg.ccDecay = { 63, 1.27f }; eg.ccDecay[63] = 1.27f;
REQUIRE(eg.getDecay(state, 0_norm) == 1.0f); REQUIRE(eg.getDecay(state, 0_norm) == 1.0f);
REQUIRE(eg.getDecay(state, 127_norm) == 0.0f); REQUIRE(eg.getDecay(state, 127_norm) == 0.0f);
state.ccEvent(0, 63, 127_norm); state.ccEvent(0, 63, 127_norm);
REQUIRE(eg.getDecay(state, 127_norm) == 1.0f); REQUIRE(eg.getDecay(state, 127_norm) == 1.0f);
REQUIRE(eg.getDecay(state, 0_norm) == 2.27f); REQUIRE(eg.getDecay(state, 0_norm) == 2.27f);
eg.ccDecay = { 63, 127.0f }; eg.ccDecay[63] = 127.0f;
REQUIRE(eg.getDecay(state, 0_norm) == 100.0f); REQUIRE(eg.getDecay(state, 0_norm) == 100.0f);
eg.ccDecay[63] = 1.27f;
eg.ccDecay[65] = 1.0f;
REQUIRE(eg.getDecay(state, 0_norm) == 2.27f);
REQUIRE(eg.getDecay(state, 127_norm) == 1.0f);
state.ccEvent(0, 65, 127_norm);
REQUIRE(eg.getDecay(state, 0_norm) == 3.27f);
REQUIRE(eg.getDecay(state, 127_norm) == 2.0f);
} }
TEST_CASE("[EGDescription] Release range") TEST_CASE("[EGDescription] Release range")
@ -65,14 +86,21 @@ TEST_CASE("[EGDescription] Release range")
sfz::MidiState state; sfz::MidiState state;
eg.release = 1; eg.release = 1;
eg.vel2release = -1.27f; eg.vel2release = -1.27f;
eg.ccRelease = { 63, 1.27f }; eg.ccRelease[63] = 1.27f;
REQUIRE(eg.getRelease(state, 0_norm) == 1.0f); REQUIRE(eg.getRelease(state, 0_norm) == 1.0f);
REQUIRE(eg.getRelease(state, 127_norm) == 0.0f); REQUIRE(eg.getRelease(state, 127_norm) == 0.0f);
state.ccEvent(0, 63, 127_norm); state.ccEvent(0, 63, 127_norm);
REQUIRE(eg.getRelease(state, 127_norm) == 1.0f); REQUIRE(eg.getRelease(state, 127_norm) == 1.0f);
REQUIRE(eg.getRelease(state, 0_norm) == 2.27f); REQUIRE(eg.getRelease(state, 0_norm) == 2.27f);
eg.ccRelease = { 63, 127.0f }; eg.ccRelease[63] = 127.0f;
REQUIRE(eg.getRelease(state, 0_norm) == 100.0f); REQUIRE(eg.getRelease(state, 0_norm) == 100.0f);
eg.ccRelease[63] = 1.27f;
eg.ccRelease[65] = 1.0f;
REQUIRE(eg.getRelease(state, 0_norm) == 2.27f);
REQUIRE(eg.getRelease(state, 127_norm) == 1.0f);
state.ccEvent(0, 65, 127_norm);
REQUIRE(eg.getRelease(state, 0_norm) == 3.27f);
REQUIRE(eg.getRelease(state, 127_norm) == 2.0f);
} }
TEST_CASE("[EGDescription] Hold range") TEST_CASE("[EGDescription] Hold range")
@ -81,14 +109,21 @@ TEST_CASE("[EGDescription] Hold range")
sfz::MidiState state; sfz::MidiState state;
eg.hold = 1; eg.hold = 1;
eg.vel2hold = -1.27f; eg.vel2hold = -1.27f;
eg.ccHold = { 63, 1.27f }; eg.ccHold[63] = 1.27f;
REQUIRE(eg.getHold(state, 0_norm) == 1.0f); REQUIRE(eg.getHold(state, 0_norm) == 1.0f);
REQUIRE(eg.getHold(state, 127_norm) == 0.0f); REQUIRE(eg.getHold(state, 127_norm) == 0.0f);
state.ccEvent(0, 63, 127_norm); state.ccEvent(0, 63, 127_norm);
REQUIRE(eg.getHold(state, 127_norm) == 1.0f); REQUIRE(eg.getHold(state, 127_norm) == 1.0f);
REQUIRE(eg.getHold(state, 0_norm) == 2.27f); REQUIRE(eg.getHold(state, 0_norm) == 2.27f);
eg.ccHold = { 63, 127.0f }; eg.ccHold[63] = 127.0f;
REQUIRE(eg.getHold(state, 0_norm) == 100.0f); REQUIRE(eg.getHold(state, 0_norm) == 100.0f);
eg.ccHold[63] = 1.27f;
eg.ccHold[65] = 1.0f;
REQUIRE(eg.getHold(state, 0_norm) == 2.27f);
REQUIRE(eg.getHold(state, 127_norm) == 1.0f);
state.ccEvent(0, 65, 127_norm);
REQUIRE(eg.getHold(state, 0_norm) == 3.27f);
REQUIRE(eg.getHold(state, 127_norm) == 2.0f);
} }
TEST_CASE("[EGDescription] Sustain level") TEST_CASE("[EGDescription] Sustain level")
@ -97,13 +132,21 @@ TEST_CASE("[EGDescription] Sustain level")
sfz::MidiState state; sfz::MidiState state;
eg.sustain = 50; eg.sustain = 50;
eg.vel2sustain = -100; eg.vel2sustain = -100;
eg.ccSustain = { 63, 100.0f }; eg.ccSustain[63] = 100.0f;
REQUIRE(eg.getSustain(state, 0_norm) == 50.0f); REQUIRE(eg.getSustain(state, 0_norm) == 50.0f);
REQUIRE(eg.getSustain(state, 127_norm) == 0.0f); REQUIRE(eg.getSustain(state, 127_norm) == 0.0f);
state.ccEvent(0, 63, 127_norm); state.ccEvent(0, 63, 127_norm);
REQUIRE(eg.getSustain(state, 127_norm) == 50.0f); REQUIRE(eg.getSustain(state, 127_norm) == 50.0f);
eg.ccSustain = { 63, 200.0f }; eg.ccSustain[63] = 200.0f;
REQUIRE(eg.getSustain(state, 0_norm) == 100.0f); REQUIRE(eg.getSustain(state, 0_norm) == 100.0f);
eg.sustain = 0;
eg.ccSustain[63] = 50.0f;
eg.ccSustain[65] = 50.0f;
REQUIRE(eg.getSustain(state, 0_norm) == 50.0f);
REQUIRE(eg.getSustain(state, 127_norm) == 0.0f);
state.ccEvent(0, 65, 127_norm);
REQUIRE(eg.getSustain(state, 0_norm) == 100.0f);
REQUIRE(eg.getSustain(state, 127_norm) == 0.0f);
} }
TEST_CASE("[EGDescription] Start level") TEST_CASE("[EGDescription] Start level")
@ -111,11 +154,19 @@ TEST_CASE("[EGDescription] Start level")
sfz::EGDescription eg; sfz::EGDescription eg;
sfz::MidiState state; sfz::MidiState state;
eg.start = 0; eg.start = 0;
eg.ccStart = { 63, 127.0f }; eg.ccStart[63] = 127.0f;
REQUIRE(eg.getStart(state, 0_norm) == 0.0f); REQUIRE(eg.getStart(state, 0_norm) == 0.0f);
REQUIRE(eg.getStart(state, 127_norm) == 0.0f); REQUIRE(eg.getStart(state, 127_norm) == 0.0f);
state.ccEvent(0, 63, 127_norm); state.ccEvent(0, 63, 127_norm);
REQUIRE(eg.getStart(state, 0_norm) == 100.0f); REQUIRE(eg.getStart(state, 0_norm) == 100.0f);
eg.ccStart = { 63, -127.0f }; eg.ccStart[63] = -127.0f;
REQUIRE(eg.getStart(state, 0_norm) == 0.0f); REQUIRE(eg.getStart(state, 0_norm) == 0.0f);
eg.start = 0;
eg.ccStart[63] = 50.0f;
eg.ccStart[65] = 50.0f;
REQUIRE(eg.getStart(state, 0_norm) == 50.0f);
REQUIRE(eg.getStart(state, 127_norm) == 50.0f);
state.ccEvent(0, 65, 127_norm);
REQUIRE(eg.getStart(state, 0_norm) == 100.0f);
REQUIRE(eg.getStart(state, 127_norm) == 100.0f);
} }

View file

@ -1083,13 +1083,13 @@ TEST_CASE("[Region] Parsing opcodes")
SECTION("ampeg_XX_onccNN") SECTION("ampeg_XX_onccNN")
{ {
// Defaults // Defaults
REQUIRE(!region.amplitudeEG.ccAttack); REQUIRE(region.amplitudeEG.ccAttack.empty());
REQUIRE(!region.amplitudeEG.ccDecay); REQUIRE(region.amplitudeEG.ccDecay.empty());
REQUIRE(!region.amplitudeEG.ccDelay); REQUIRE(region.amplitudeEG.ccDelay.empty());
REQUIRE(!region.amplitudeEG.ccHold); REQUIRE(region.amplitudeEG.ccHold.empty());
REQUIRE(!region.amplitudeEG.ccRelease); REQUIRE(region.amplitudeEG.ccRelease.empty());
REQUIRE(!region.amplitudeEG.ccStart); REQUIRE(region.amplitudeEG.ccStart.empty());
REQUIRE(!region.amplitudeEG.ccSustain); REQUIRE(region.amplitudeEG.ccSustain.empty());
// //
region.parseOpcode({ "ampeg_attack_oncc1", "1" }); region.parseOpcode({ "ampeg_attack_oncc1", "1" });
region.parseOpcode({ "ampeg_decay_oncc2", "2" }); region.parseOpcode({ "ampeg_decay_oncc2", "2" });
@ -1098,27 +1098,20 @@ TEST_CASE("[Region] Parsing opcodes")
region.parseOpcode({ "ampeg_release_oncc5", "5" }); region.parseOpcode({ "ampeg_release_oncc5", "5" });
region.parseOpcode({ "ampeg_start_oncc6", "6" }); region.parseOpcode({ "ampeg_start_oncc6", "6" });
region.parseOpcode({ "ampeg_sustain_oncc7", "7" }); region.parseOpcode({ "ampeg_sustain_oncc7", "7" });
REQUIRE(region.amplitudeEG.ccAttack); REQUIRE(region.amplitudeEG.ccAttack.contains(1));
REQUIRE(region.amplitudeEG.ccDecay); REQUIRE(region.amplitudeEG.ccDecay.contains(2));
REQUIRE(region.amplitudeEG.ccDelay); REQUIRE(region.amplitudeEG.ccDelay.contains(3));
REQUIRE(region.amplitudeEG.ccHold); REQUIRE(region.amplitudeEG.ccHold.contains(4));
REQUIRE(region.amplitudeEG.ccRelease); REQUIRE(region.amplitudeEG.ccRelease.contains(5));
REQUIRE(region.amplitudeEG.ccStart); REQUIRE(region.amplitudeEG.ccStart.contains(6));
REQUIRE(region.amplitudeEG.ccSustain); REQUIRE(region.amplitudeEG.ccSustain.contains(7));
REQUIRE(region.amplitudeEG.ccAttack->cc == 1); REQUIRE(region.amplitudeEG.ccAttack[1] == 1.0f);
REQUIRE(region.amplitudeEG.ccDecay->cc == 2); REQUIRE(region.amplitudeEG.ccDecay[2] == 2.0f);
REQUIRE(region.amplitudeEG.ccDelay->cc == 3); REQUIRE(region.amplitudeEG.ccDelay[3] == 3.0f);
REQUIRE(region.amplitudeEG.ccHold->cc == 4); REQUIRE(region.amplitudeEG.ccHold[4] == 4.0f);
REQUIRE(region.amplitudeEG.ccRelease->cc == 5); REQUIRE(region.amplitudeEG.ccRelease[5] == 5.0f);
REQUIRE(region.amplitudeEG.ccStart->cc == 6); REQUIRE(region.amplitudeEG.ccStart[6] == 6.0f);
REQUIRE(region.amplitudeEG.ccSustain->cc == 7); REQUIRE(region.amplitudeEG.ccSustain[7] == 7.0f);
REQUIRE(region.amplitudeEG.ccAttack->data == 1.0f);
REQUIRE(region.amplitudeEG.ccDecay->data == 2.0f);
REQUIRE(region.amplitudeEG.ccDelay->data == 3.0f);
REQUIRE(region.amplitudeEG.ccHold->data == 4.0f);
REQUIRE(region.amplitudeEG.ccRelease->data == 5.0f);
REQUIRE(region.amplitudeEG.ccStart->data == 6.0f);
REQUIRE(region.amplitudeEG.ccSustain->data == 7.0f);
// //
region.parseOpcode({ "ampeg_attack_oncc1", "101" }); region.parseOpcode({ "ampeg_attack_oncc1", "101" });
region.parseOpcode({ "ampeg_decay_oncc2", "101" }); region.parseOpcode({ "ampeg_decay_oncc2", "101" });
@ -1127,13 +1120,13 @@ TEST_CASE("[Region] Parsing opcodes")
region.parseOpcode({ "ampeg_release_oncc5", "101" }); region.parseOpcode({ "ampeg_release_oncc5", "101" });
region.parseOpcode({ "ampeg_start_oncc6", "101" }); region.parseOpcode({ "ampeg_start_oncc6", "101" });
region.parseOpcode({ "ampeg_sustain_oncc7", "101" }); region.parseOpcode({ "ampeg_sustain_oncc7", "101" });
REQUIRE(region.amplitudeEG.ccAttack->data == 100.0f); REQUIRE(region.amplitudeEG.ccAttack[1] == 100.0f);
REQUIRE(region.amplitudeEG.ccDecay->data == 100.0f); REQUIRE(region.amplitudeEG.ccDecay[2] == 100.0f);
REQUIRE(region.amplitudeEG.ccDelay->data == 100.0f); REQUIRE(region.amplitudeEG.ccDelay[3] == 100.0f);
REQUIRE(region.amplitudeEG.ccHold->data == 100.0f); REQUIRE(region.amplitudeEG.ccHold[4] == 100.0f);
REQUIRE(region.amplitudeEG.ccRelease->data == 100.0f); REQUIRE(region.amplitudeEG.ccRelease[5] == 100.0f);
REQUIRE(region.amplitudeEG.ccStart->data == 100.0f); REQUIRE(region.amplitudeEG.ccStart[6] == 100.0f);
REQUIRE(region.amplitudeEG.ccSustain->data == 100.0f); REQUIRE(region.amplitudeEG.ccSustain[7] == 100.0f);
// //
region.parseOpcode({ "ampeg_attack_oncc1", "-101" }); region.parseOpcode({ "ampeg_attack_oncc1", "-101" });
region.parseOpcode({ "ampeg_decay_oncc2", "-101" }); region.parseOpcode({ "ampeg_decay_oncc2", "-101" });
@ -1142,13 +1135,56 @@ TEST_CASE("[Region] Parsing opcodes")
region.parseOpcode({ "ampeg_release_oncc5", "-101" }); region.parseOpcode({ "ampeg_release_oncc5", "-101" });
region.parseOpcode({ "ampeg_start_oncc6", "-101" }); region.parseOpcode({ "ampeg_start_oncc6", "-101" });
region.parseOpcode({ "ampeg_sustain_oncc7", "-101" }); region.parseOpcode({ "ampeg_sustain_oncc7", "-101" });
REQUIRE(region.amplitudeEG.ccAttack->data == -100.0f); REQUIRE(region.amplitudeEG.ccAttack[1] == -100.0f);
REQUIRE(region.amplitudeEG.ccDecay->data == -100.0f); REQUIRE(region.amplitudeEG.ccDecay[2] == -100.0f);
REQUIRE(region.amplitudeEG.ccDelay->data == -100.0f); REQUIRE(region.amplitudeEG.ccDelay[3] == -100.0f);
REQUIRE(region.amplitudeEG.ccHold->data == -100.0f); REQUIRE(region.amplitudeEG.ccHold[4] == -100.0f);
REQUIRE(region.amplitudeEG.ccRelease->data == -100.0f); REQUIRE(region.amplitudeEG.ccRelease[5] == -100.0f);
REQUIRE(region.amplitudeEG.ccStart->data == -100.0f); REQUIRE(region.amplitudeEG.ccStart[6] == -100.0f);
REQUIRE(region.amplitudeEG.ccSustain->data == -100.0f); REQUIRE(region.amplitudeEG.ccSustain[7] == -100.0f);
//
region.parseOpcode({ "ampeg_attack_oncc1", "1" });
region.parseOpcode({ "ampeg_decay_oncc2", "2" });
region.parseOpcode({ "ampeg_delay_oncc3", "3" });
region.parseOpcode({ "ampeg_hold_oncc4", "4" });
region.parseOpcode({ "ampeg_release_oncc5", "5" });
region.parseOpcode({ "ampeg_start_oncc6", "6" });
region.parseOpcode({ "ampeg_sustain_oncc7", "7" });
region.parseOpcode({ "ampeg_attack_oncc2", "2" });
region.parseOpcode({ "ampeg_decay_oncc3", "3" });
region.parseOpcode({ "ampeg_delay_oncc4", "4" });
region.parseOpcode({ "ampeg_hold_oncc5", "5" });
region.parseOpcode({ "ampeg_release_oncc6", "6" });
region.parseOpcode({ "ampeg_start_oncc7", "7" });
region.parseOpcode({ "ampeg_sustain_oncc8", "8" });
REQUIRE(region.amplitudeEG.ccAttack.contains(1));
REQUIRE(region.amplitudeEG.ccDecay.contains(2));
REQUIRE(region.amplitudeEG.ccDelay.contains(3));
REQUIRE(region.amplitudeEG.ccHold.contains(4));
REQUIRE(region.amplitudeEG.ccRelease.contains(5));
REQUIRE(region.amplitudeEG.ccStart.contains(6));
REQUIRE(region.amplitudeEG.ccSustain.contains(7));
REQUIRE(region.amplitudeEG.ccAttack.contains(2));
REQUIRE(region.amplitudeEG.ccDecay.contains(3));
REQUIRE(region.amplitudeEG.ccDelay.contains(4));
REQUIRE(region.amplitudeEG.ccHold.contains(5));
REQUIRE(region.amplitudeEG.ccRelease.contains(6));
REQUIRE(region.amplitudeEG.ccStart.contains(7));
REQUIRE(region.amplitudeEG.ccSustain.contains(8));
REQUIRE(region.amplitudeEG.ccAttack[1] == 1.0f);
REQUIRE(region.amplitudeEG.ccDecay[2] == 2.0f);
REQUIRE(region.amplitudeEG.ccDelay[3] == 3.0f);
REQUIRE(region.amplitudeEG.ccHold[4] == 4.0f);
REQUIRE(region.amplitudeEG.ccRelease[5] == 5.0f);
REQUIRE(region.amplitudeEG.ccStart[6] == 6.0f);
REQUIRE(region.amplitudeEG.ccSustain[7] == 7.0f);
REQUIRE(region.amplitudeEG.ccAttack[2] == 2.0f);
REQUIRE(region.amplitudeEG.ccDecay[3] == 3.0f);
REQUIRE(region.amplitudeEG.ccDelay[4] == 4.0f);
REQUIRE(region.amplitudeEG.ccHold[5] == 5.0f);
REQUIRE(region.amplitudeEG.ccRelease[6] == 6.0f);
REQUIRE(region.amplitudeEG.ccStart[7] == 7.0f);
REQUIRE(region.amplitudeEG.ccSustain[8] == 8.0f);
} }
SECTION("sustain_sw and sostenuto_sw") SECTION("sustain_sw and sostenuto_sw")