diff --git a/src/sfizz/ModifierHelpers.h b/src/sfizz/ModifierHelpers.h index 02502fcc..6aa757fe 100644 --- a/src/sfizz/ModifierHelpers.h +++ b/src/sfizz/ModifierHelpers.h @@ -88,7 +88,7 @@ void linearEnvelope(const EventVector& events, absl::Span envelope, F&& l return; auto quantize = [step](float value) -> float { - return std::round(value / step) * step; + return std::floor(value / step) * step; }; const auto maxDelay = static_cast(envelope.size() - 1); @@ -158,7 +158,7 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span envelop // log q log q // and log(b)\log(q) is between 0 and 1. auto quantize = [logStep](float value) -> float { - return std::exp(logStep * std::round(std::log(value) / logStep)); + return std::exp(logStep * std::floor(std::log(value) / logStep)); }; auto lastValue = quantize(lambda(events[0].value)); @@ -191,12 +191,12 @@ void linearModifier(const sfz::Resources& resources, absl::Span span, con { const auto events = resources.midiState.getCCEvents(ccData.cc); const auto curve = resources.curves.getCurve(ccData.data.curve); - if (ccData.data.steps == 0) { + if (ccData.data.steps < 2) { linearEnvelope(events, span, [&ccData, &curve, &lambda](float x) { return lambda(curve.evalNormalized(x) * ccData.data.value); }); } else { - const float stepSize { ccData.data.value / ccData.data.steps }; + const float stepSize { ccData.data.value / (ccData.data.steps - 1) }; linearEnvelope(events, span, [&ccData, &curve, &lambda](float x) { return lambda(curve.evalNormalized(x) * ccData.data.value); }, stepSize); @@ -208,13 +208,13 @@ void multiplicativeModifier(const sfz::Resources& resources, absl::Span s { const auto events = resources.midiState.getCCEvents(ccData.cc); const auto curve = resources.curves.getCurve(ccData.data.curve); - if (ccData.data.steps == 0) { + if (ccData.data.steps < 2) { multiplicativeEnvelope(events, span, [&ccData, &curve, &lambda](float x) { return lambda(curve.evalNormalized(x) * ccData.data.value); }); } else { // FIXME: not sure about this step size for multiplicative envelopes - const float stepSize { lambda(ccData.data.value / ccData.data.steps) }; + const float stepSize { lambda(ccData.data.value / (ccData.data.steps - 1)) }; multiplicativeEnvelope(events, span, [&ccData, &curve, &lambda](float x) { return lambda(curve.evalNormalized(x) * ccData.data.value); }, stepSize); diff --git a/tests/EventEnvelopesT.cpp b/tests/EventEnvelopesT.cpp index 71df4a79..634d98d6 100644 --- a/tests/EventEnvelopesT.cpp +++ b/tests/EventEnvelopesT.cpp @@ -137,7 +137,7 @@ TEST_CASE("[LinearEnvelope] Get quantized with unquantized targets") { 6, 1.9f } }; std::array output; - std::array expected { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f }; + std::array expected { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f); REQUIRE(output == expected); } @@ -315,7 +315,7 @@ TEST_CASE("[linearModifiers] Compare with envelopes") ccData.data.steps = 10; linearEnvelope(resources.midiState.getCCEvents(20), absl::MakeSpan(envelope), [&ccData](float x) { return ccData.data.value * (1 - x); - }, ccData.data.value / ccData.data.steps); + }, ccData.data.value / (ccData.data.steps - 1)); linearModifier(resources, absl::MakeSpan(output), ccData); REQUIRE(approxEqual(output, envelope)); } @@ -367,7 +367,7 @@ TEST_CASE("[multiplicativeModifiers] Compare with envelopes") ccData.data.steps = 10; multiplicativeEnvelope(resources.midiState.getCCEvents(20), absl::MakeSpan(envelope), [&ccData](float x) { return db2mag(ccData.data.value * (1 - x)); - }, db2mag(ccData.data.value / ccData.data.steps) ); + }, db2mag(ccData.data.value / (ccData.data.steps - 1)) ); multiplicativeModifier(resources, absl::MakeSpan(output), ccData, [](float x) { return db2mag(x); });