diff --git a/src/sfizz/Macros.h b/src/sfizz/Macros.h index 3769b34d..024dfe24 100644 --- a/src/sfizz/Macros.h +++ b/src/sfizz/Macros.h @@ -16,3 +16,10 @@ #define CXX11_MOVE(x) std::move(x) #endif +#if __cplusplus >= 201703L +#define IF_CONSTEXPR if constexpr +#else +#define IF_CONSTEXPR if +#endif + + diff --git a/src/sfizz/ModifierHelpers.h b/src/sfizz/ModifierHelpers.h index b46bbc61..a476f6ae 100644 --- a/src/sfizz/ModifierHelpers.h +++ b/src/sfizz/ModifierHelpers.h @@ -139,7 +139,7 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span envelop fill(envelope.subspan(lastDelay), lastValue); } -template +template void multiplicativeEnvelope(const EventVector& events, absl::Span envelope, F&& lambda, float step) { ASSERT(events.size() > 0); @@ -156,7 +156,14 @@ 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::trunc(std::log(value) / logStep)); + IF_CONSTEXPR(Round) + { + return std::exp(logStep * std::round(std::log(value) / logStep)); + } + else + { + return std::exp(logStep * std::trunc(std::log(value) / logStep)); + } }; auto lastValue = quantize(lambda(events[0].value)); @@ -184,7 +191,19 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span envelop fill(envelope.subspan(lastDelay), lastValue); } -template +template +void pitchBendEnvelope(const EventVector& events, absl::Span envelope, F&& lambda, float step) +{ + multiplicativeEnvelope(events, envelope, std::forward(lambda), step); +} + +template +void pitchBendEnvelope(const EventVector& events, absl::Span envelope, F&& lambda) +{ + multiplicativeEnvelope(events, envelope, std::forward(lambda)); +} + +template void linearModifier(const sfz::Resources& resources, absl::Span span, const sfz::CCData& ccData, F&& lambda) { const auto events = resources.midiState.getCCEvents(ccData.cc); @@ -195,13 +214,15 @@ void linearModifier(const sfz::Resources& resources, absl::Span span, con }); } else { const float stepSize { lambda(ccData.data.step) }; - linearEnvelope(events, span, [&ccData, &curve, &lambda](float x) { - return lambda(curve.evalNormalized(x) * ccData.data.value); - }, stepSize); + linearEnvelope( + events, span, [&ccData, &curve, &lambda](float x) { + return lambda(curve.evalNormalized(x) * ccData.data.value); + }, + stepSize); } } -template +template void multiplicativeModifier(const sfz::Resources& resources, absl::Span span, const sfz::CCData& ccData, F&& lambda) { const auto events = resources.midiState.getCCEvents(ccData.cc); @@ -212,9 +233,11 @@ void multiplicativeModifier(const sfz::Resources& resources, absl::Span s }); } else { const float stepSize { lambda(ccData.data.step) }; - multiplicativeEnvelope(events, span, [&ccData, &curve, &lambda](float x) { - return lambda(curve.evalNormalized(x) * ccData.data.value); - }, stepSize); + multiplicativeEnvelope( + events, span, [&ccData, &curve, &lambda](float x) { + return lambda(curve.evalNormalized(x) * ccData.data.value); + }, + stepSize); } } diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index d7deb618..cfa8bfbe 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -446,9 +446,9 @@ void sfz::Voice::fillWithData(AudioSpan buffer) noexcept }; if (region->bendStep > 1) - multiplicativeEnvelope(events, *bends, bendLambda, bendStepFactor); + pitchBendEnvelope(events, *bends, bendLambda, bendStepFactor); else - multiplicativeEnvelope(events, *bends, bendLambda); + pitchBendEnvelope(events, *bends, bendLambda); applyGain(*bends, *jumps); for (const auto& mod : region->tuneCC) { @@ -549,9 +549,9 @@ void sfz::Voice::fillWithGenerator(AudioSpan buffer) noexcept return centsFactor(bendInCents); }; if (region->bendStep > 1) - multiplicativeEnvelope(events, *bends, bendLambda, bendStepFactor); + pitchBendEnvelope(events, *bends, bendLambda, bendStepFactor); else - multiplicativeEnvelope(events, *bends, bendLambda); + pitchBendEnvelope(events, *bends, bendLambda); applyGain(*bends, *frequencies); for (const auto& mod : region->tuneCC) {