Stepcc actually gives the step and not the number of steps...

This commit is contained in:
Paul Ferrand 2020-04-14 13:41:24 +02:00 committed by Paul Fd
parent b3dd8b3ce9
commit 6a7977b6c2
6 changed files with 45 additions and 40 deletions

View file

@ -110,17 +110,21 @@ namespace Default
constexpr float volume { 0.0f }; constexpr float volume { 0.0f };
constexpr Range<float> volumeRange { -144.0, 6.0 }; constexpr Range<float> volumeRange { -144.0, 6.0 };
constexpr Range<float> volumeCCRange { -144.0, 48.0 }; constexpr Range<float> volumeCCRange { -144.0, 48.0 };
constexpr Range<float> volumeStepRange { 0, 48.0 };
constexpr float amplitude { 100.0 }; constexpr float amplitude { 100.0 };
constexpr Range<float> amplitudeRange { 0.0, 100.0 }; constexpr Range<float> amplitudeRange { 0.0, 100.0 };
constexpr float pan { 0.0 }; constexpr float pan { 0.0 };
constexpr Range<float> panRange { -100.0, 100.0 }; constexpr Range<float> panRange { -100.0, 100.0 };
constexpr Range<float> panCCRange { -200.0, 200.0 }; constexpr Range<float> panCCRange { -200.0, 200.0 };
constexpr Range<float> panStepRange { 0.0, 200.0 };
constexpr float position { 0.0 }; constexpr float position { 0.0 };
constexpr Range<float> positionRange { -100.0, 100.0 }; constexpr Range<float> positionRange { -100.0, 100.0 };
constexpr Range<float> positionCCRange { -200.0, 200.0 }; constexpr Range<float> positionCCRange { -200.0, 200.0 };
constexpr Range<float> positionStepRange { 0.0, 200.0 };
constexpr float width { 100.0 }; constexpr float width { 100.0 };
constexpr Range<float> widthRange { -100.0, 100.0 }; constexpr Range<float> widthRange { -100.0, 100.0 };
constexpr Range<float> widthCCRange { -200.0, 200.0 }; constexpr Range<float> widthCCRange { -200.0, 200.0 };
constexpr Range<float> widthStepRange { 0.0, 200.0 };
constexpr uint8_t ampKeycenter { 60 }; constexpr uint8_t ampKeycenter { 60 };
constexpr float ampKeytrack { 0.0 }; constexpr float ampKeytrack { 0.0 };
constexpr Range<float> ampKeytrackRange { -96, 12 }; constexpr Range<float> ampKeytrackRange { -96, 12 };
@ -196,6 +200,7 @@ namespace Default
constexpr int tune { 0 }; constexpr int tune { 0 };
constexpr Range<int> tuneRange { -9600, 9600 }; // ±100 in SFZv1, more in ARIA constexpr Range<int> tuneRange { -9600, 9600 }; // ±100 in SFZv1, more in ARIA
constexpr Range<int> tuneCCRange { -9600, 9600 }; constexpr Range<int> tuneCCRange { -9600, 9600 };
constexpr Range<int> tuneStepRange { 0, 9600 };
constexpr Range<int> bendBoundRange { -9600, 9600 }; constexpr Range<int> bendBoundRange { -9600, 9600 };
constexpr Range<int> bendStepRange { 1, 1200 }; constexpr Range<int> bendStepRange { 1, 1200 };
constexpr int bendUp { 200 }; // No range here because the bounds can be inverted constexpr int bendUp { 200 }; // No range here because the bounds can be inverted

View file

@ -189,12 +189,12 @@ void linearModifier(const sfz::Resources& resources, absl::Span<float> span, con
{ {
const auto events = resources.midiState.getCCEvents(ccData.cc); const auto events = resources.midiState.getCCEvents(ccData.cc);
const auto curve = resources.curves.getCurve(ccData.data.curve); const auto curve = resources.curves.getCurve(ccData.data.curve);
if (ccData.data.steps < 2) { if (ccData.data.step == 0.0f) {
linearEnvelope(events, span, [&ccData, &curve, &lambda](float x) { linearEnvelope(events, span, [&ccData, &curve, &lambda](float x) {
return lambda(curve.evalNormalized(x) * ccData.data.value); return lambda(curve.evalNormalized(x) * ccData.data.value);
}); });
} else { } else {
const float stepSize { ccData.data.value / (ccData.data.steps - 1) }; const float stepSize { lambda(ccData.data.step) };
linearEnvelope(events, span, [&ccData, &curve, &lambda](float x) { linearEnvelope(events, span, [&ccData, &curve, &lambda](float x) {
return lambda(curve.evalNormalized(x) * ccData.data.value); return lambda(curve.evalNormalized(x) * ccData.data.value);
}, stepSize); }, stepSize);
@ -206,12 +206,12 @@ void multiplicativeModifier(const sfz::Resources& resources, absl::Span<float> s
{ {
const auto events = resources.midiState.getCCEvents(ccData.cc); const auto events = resources.midiState.getCCEvents(ccData.cc);
const auto curve = resources.curves.getCurve(ccData.data.curve); const auto curve = resources.curves.getCurve(ccData.data.curve);
if (ccData.data.steps < 2) { if (ccData.data.step == 0.0f) {
multiplicativeEnvelope(events, span, [&ccData, &curve, &lambda](float x) { multiplicativeEnvelope(events, span, [&ccData, &curve, &lambda](float x) {
return lambda(curve.evalNormalized(x) * ccData.data.value); return lambda(curve.evalNormalized(x) * ccData.data.value);
}); });
} else { } else {
const float stepSize { lambda(ccData.data.value / (ccData.data.steps - 1)) }; const float stepSize { lambda(ccData.data.step) };
multiplicativeEnvelope(events, span, [&ccData, &curve, &lambda](float x) { multiplicativeEnvelope(events, span, [&ccData, &curve, &lambda](float x) {
return lambda(curve.evalNormalized(x) * ccData.data.value); return lambda(curve.evalNormalized(x) * ccData.data.value);
}, stepSize); }, stepSize);

View file

@ -305,8 +305,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
case hash("volume_stepcc&"): case hash("volume_stepcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
return false; return false;
if (auto value = readOpcode(opcode.value, Default::stepCCRange)) if (auto value = readOpcode(opcode.value, Default::volumeStepRange))
volumeCC[opcode.parameters.back()].steps = *value; volumeCC[opcode.parameters.back()].step = *value;
break; break;
case hash("volume_smoothcc&"): case hash("volume_smoothcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
@ -335,8 +335,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
case hash("amplitude_stepcc&"): case hash("amplitude_stepcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
return false; return false;
if (auto value = readOpcode(opcode.value, Default::stepCCRange)) if (auto value = readOpcode(opcode.value, Default::amplitudeRange))
amplitudeCC[opcode.parameters.back()].steps = *value; amplitudeCC[opcode.parameters.back()].step = normalizePercents(*value);
break; break;
case hash("amplitude_smoothcc&"): case hash("amplitude_smoothcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
@ -364,8 +364,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
case hash("pan_stepcc&"): case hash("pan_stepcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
return false; return false;
if (auto value = readOpcode(opcode.value, Default::stepCCRange)) if (auto value = readOpcode(opcode.value, Default::panStepRange))
panCC[opcode.parameters.back()].steps = *value; panCC[opcode.parameters.back()].step = normalizePercents(*value);
break; break;
case hash("pan_smoothcc&"): case hash("pan_smoothcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
@ -393,8 +393,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
case hash("position_stepcc&"): case hash("position_stepcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
return false; return false;
if (auto value = readOpcode(opcode.value, Default::stepCCRange)) if (auto value = readOpcode(opcode.value, Default::positionStepRange))
positionCC[opcode.parameters.back()].steps = *value; positionCC[opcode.parameters.back()].step = normalizePercents(*value);
break; break;
case hash("position_smoothcc&"): case hash("position_smoothcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
@ -422,8 +422,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
case hash("width_stepcc&"): case hash("width_stepcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
return false; return false;
if (auto value = readOpcode(opcode.value, Default::stepCCRange)) if (auto value = readOpcode(opcode.value, Default::widthStepRange))
widthCC[opcode.parameters.back()].steps = *value; widthCC[opcode.parameters.back()].step = normalizePercents(*value);
break; break;
case hash("width_smoothcc&"): case hash("width_smoothcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
@ -827,8 +827,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
case hash("tune_stepcc&"): case hash("tune_stepcc&"):
if (opcode.parameters.back() > config::numCCs) if (opcode.parameters.back() > config::numCCs)
return false; return false;
if (auto value = readOpcode(opcode.value, Default::stepCCRange)) if (auto value = readOpcode(opcode.value, Default::tuneStepRange))
tuneCC[opcode.parameters.back()].steps = *value; tuneCC[opcode.parameters.back()].step = *value;
break; break;
case hash("pitch_smoothcc&"): // fallthrough case hash("pitch_smoothcc&"): // fallthrough
case hash("tune_smoothcc&"): case hash("tune_smoothcc&"):

View file

@ -32,8 +32,8 @@ struct CCData {
struct Modifier { struct Modifier {
float value { 0.0f }; float value { 0.0f };
float step { 0.0f };
uint8_t curve { 0 }; uint8_t curve { 0 };
uint8_t steps { 0 };
uint8_t smooth { 0 }; uint8_t smooth { 0 };
static_assert(config::maxCurves - 1 <= std::numeric_limits<decltype(curve)>::max(), "The curve type in the Modifier struct cannot support the required number of curves"); static_assert(config::maxCurves - 1 <= std::numeric_limits<decltype(curve)>::max(), "The curve type in the Modifier struct cannot support the required number of curves");
}; };

View file

@ -312,10 +312,10 @@ TEST_CASE("[linearModifiers] Compare with envelopes")
ccData.data.curve = 2; ccData.data.curve = 2;
ccData.data.value = 20.0f; ccData.data.value = 20.0f;
ccData.data.steps = 10; ccData.data.step = 2.0f;
linearEnvelope(resources.midiState.getCCEvents(20), absl::MakeSpan(envelope), [&ccData](float x) { linearEnvelope(resources.midiState.getCCEvents(20), absl::MakeSpan(envelope), [&ccData](float x) {
return ccData.data.value * (1 - x); return ccData.data.value * (1 - x);
}, ccData.data.value / (ccData.data.steps - 1)); }, ccData.data.step);
linearModifier(resources, absl::MakeSpan(output), ccData); linearModifier(resources, absl::MakeSpan(output), ccData);
REQUIRE(approxEqual<float>(output, envelope)); REQUIRE(approxEqual<float>(output, envelope));
} }
@ -364,10 +364,10 @@ TEST_CASE("[multiplicativeModifiers] Compare with envelopes")
ccData.data.curve = 2; ccData.data.curve = 2;
ccData.data.value = 20.0f; ccData.data.value = 20.0f;
ccData.data.steps = 10; ccData.data.step = 2.0f;
multiplicativeEnvelope(resources.midiState.getCCEvents(20), absl::MakeSpan(envelope), [&ccData](float x) { multiplicativeEnvelope(resources.midiState.getCCEvents(20), absl::MakeSpan(envelope), [&ccData](float x) {
return db2mag(ccData.data.value * (1 - x)); return db2mag(ccData.data.value * (1 - x));
}, db2mag(ccData.data.value / (ccData.data.steps - 1)) ); }, db2mag(ccData.data.step) );
multiplicativeModifier(resources, absl::MakeSpan(output), ccData, [](float x) { multiplicativeModifier(resources, absl::MakeSpan(output), ccData, [](float x) {
return db2mag(x); return db2mag(x);
}); });

View file

@ -484,11 +484,11 @@ TEST_CASE("[Region] Parsing opcodes")
region.parseOpcode({ "pan_smoothcc14", "-2" }); region.parseOpcode({ "pan_smoothcc14", "-2" });
REQUIRE(region.panCC[14].smooth == 0); REQUIRE(region.panCC[14].smooth == 0);
region.parseOpcode({ "pan_stepcc120", "24" }); region.parseOpcode({ "pan_stepcc120", "24" });
REQUIRE(region.panCC[120].steps == 24); REQUIRE(region.panCC[120].step == 0.24_a);
region.parseOpcode({ "pan_stepcc120", "15482" }); region.parseOpcode({ "pan_stepcc120", "15482" });
REQUIRE(region.panCC[120].steps == 127); REQUIRE(region.panCC[120].step == 2.0_a);
region.parseOpcode({ "pan_stepcc120", "-2" }); region.parseOpcode({ "pan_stepcc120", "-2" });
REQUIRE(region.panCC[120].steps == 0); REQUIRE(region.panCC[120].step == 0.0f);
} }
SECTION("width") SECTION("width")
@ -523,11 +523,11 @@ TEST_CASE("[Region] Parsing opcodes")
region.parseOpcode({ "width_smoothcc14", "-2" }); region.parseOpcode({ "width_smoothcc14", "-2" });
REQUIRE(region.widthCC[14].smooth == 0); REQUIRE(region.widthCC[14].smooth == 0);
region.parseOpcode({ "width_stepcc120", "24" }); region.parseOpcode({ "width_stepcc120", "24" });
REQUIRE(region.widthCC[120].steps == 24); REQUIRE(region.widthCC[120].step == 0.24_a);
region.parseOpcode({ "width_stepcc120", "15482" }); region.parseOpcode({ "width_stepcc120", "15482" });
REQUIRE(region.widthCC[120].steps == 127); REQUIRE(region.widthCC[120].step == 2.0_a);
region.parseOpcode({ "width_stepcc120", "-2" }); region.parseOpcode({ "width_stepcc120", "-20" });
REQUIRE(region.widthCC[120].steps == 0); REQUIRE(region.widthCC[120].step == 0.0f);
} }
SECTION("position") SECTION("position")
@ -562,11 +562,11 @@ TEST_CASE("[Region] Parsing opcodes")
region.parseOpcode({ "position_smoothcc14", "-2" }); region.parseOpcode({ "position_smoothcc14", "-2" });
REQUIRE(region.positionCC[14].smooth == 0); REQUIRE(region.positionCC[14].smooth == 0);
region.parseOpcode({ "position_stepcc120", "24" }); region.parseOpcode({ "position_stepcc120", "24" });
REQUIRE(region.positionCC[120].steps == 24); REQUIRE(region.positionCC[120].step == 0.24_a);
region.parseOpcode({ "position_stepcc120", "15482" }); region.parseOpcode({ "position_stepcc120", "15482" });
REQUIRE(region.positionCC[120].steps == 127); REQUIRE(region.positionCC[120].step == 2.0_a);
region.parseOpcode({ "position_stepcc120", "-2" }); region.parseOpcode({ "position_stepcc120", "-2" });
REQUIRE(region.positionCC[120].steps == 0); REQUIRE(region.positionCC[120].step == 0.0f);
} }
SECTION("amp_keycenter") SECTION("amp_keycenter")
@ -1519,11 +1519,11 @@ TEST_CASE("[Region] Parsing opcodes")
region.parseOpcode({ "amplitude_smoothcc14", "-2" }); region.parseOpcode({ "amplitude_smoothcc14", "-2" });
REQUIRE(region.amplitudeCC[14].smooth == 0); REQUIRE(region.amplitudeCC[14].smooth == 0);
region.parseOpcode({ "amplitude_stepcc120", "24" }); region.parseOpcode({ "amplitude_stepcc120", "24" });
REQUIRE(region.amplitudeCC[120].steps == 24); REQUIRE(region.amplitudeCC[120].step == 0.24_a);
region.parseOpcode({ "amplitude_stepcc120", "15482" }); region.parseOpcode({ "amplitude_stepcc120", "15482" });
REQUIRE(region.amplitudeCC[120].steps == 127); REQUIRE(region.amplitudeCC[120].step == 1.0_a);
region.parseOpcode({ "amplitude_stepcc120", "-2" }); region.parseOpcode({ "amplitude_stepcc120", "-2" });
REQUIRE(region.amplitudeCC[120].steps == 0); REQUIRE(region.amplitudeCC[120].step == 0.0f);
} }
SECTION("volume_oncc/gain_cc") SECTION("volume_oncc/gain_cc")
@ -1551,11 +1551,11 @@ TEST_CASE("[Region] Parsing opcodes")
region.parseOpcode({ "volume_smoothcc14", "-2" }); region.parseOpcode({ "volume_smoothcc14", "-2" });
REQUIRE(region.volumeCC[14].smooth == 0); REQUIRE(region.volumeCC[14].smooth == 0);
region.parseOpcode({ "volume_stepcc120", "24" }); region.parseOpcode({ "volume_stepcc120", "24" });
REQUIRE(region.volumeCC[120].steps == 24); REQUIRE(region.volumeCC[120].step == 24.0f);
region.parseOpcode({ "volume_stepcc120", "15482" }); region.parseOpcode({ "volume_stepcc120", "15482" });
REQUIRE(region.volumeCC[120].steps == 127); REQUIRE(region.volumeCC[120].step == 48.0f);
region.parseOpcode({ "volume_stepcc120", "-2" }); region.parseOpcode({ "volume_stepcc120", "-2" });
REQUIRE(region.volumeCC[120].steps == 0); REQUIRE(region.volumeCC[120].step == 0.0f);
} }
SECTION("tune_cc/pitch_cc") SECTION("tune_cc/pitch_cc")
@ -1583,11 +1583,11 @@ TEST_CASE("[Region] Parsing opcodes")
region.parseOpcode({ "pitch_smoothcc14", "-2" }); region.parseOpcode({ "pitch_smoothcc14", "-2" });
REQUIRE(region.tuneCC[14].smooth == 0); REQUIRE(region.tuneCC[14].smooth == 0);
region.parseOpcode({ "tune_stepcc120", "24" }); region.parseOpcode({ "tune_stepcc120", "24" });
REQUIRE(region.tuneCC[120].steps == 24); REQUIRE(region.tuneCC[120].step == 24.0f);
region.parseOpcode({ "pitch_stepcc120", "15482" }); region.parseOpcode({ "pitch_stepcc120", "15482" });
REQUIRE(region.tuneCC[120].steps == 127); REQUIRE(region.tuneCC[120].step == 9600.0f);
region.parseOpcode({ "tune_stepcc120", "-2" }); region.parseOpcode({ "tune_stepcc120", "-2" });
REQUIRE(region.tuneCC[120].steps == 0); REQUIRE(region.tuneCC[120].step == 0.0f);
} }
} }