Dispatch between "normal"multiplicativ eenvelopes and the pitch bends

This commit is contained in:
Paul Ferrand 2020-04-14 13:52:18 +02:00 committed by Paul Fd
parent 6a7977b6c2
commit aeba9dfaab
3 changed files with 44 additions and 14 deletions

View file

@ -16,3 +16,10 @@
#define CXX11_MOVE(x) std::move(x) #define CXX11_MOVE(x) std::move(x)
#endif #endif
#if __cplusplus >= 201703L
#define IF_CONSTEXPR if constexpr
#else
#define IF_CONSTEXPR if
#endif

View file

@ -139,7 +139,7 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
fill<float>(envelope.subspan(lastDelay), lastValue); fill<float>(envelope.subspan(lastDelay), lastValue);
} }
template <class F> template <class F, bool Round = false>
void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step) void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
{ {
ASSERT(events.size() > 0); ASSERT(events.size() > 0);
@ -156,7 +156,14 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
// log q log q // log q log q
// and log(b)\log(q) is between 0 and 1. // and log(b)\log(q) is between 0 and 1.
auto quantize = [logStep](float value) -> float { 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)); auto lastValue = quantize(lambda(events[0].value));
@ -184,7 +191,19 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
fill<float>(envelope.subspan(lastDelay), lastValue); fill<float>(envelope.subspan(lastDelay), lastValue);
} }
template<class F> template <class F>
void pitchBendEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
{
multiplicativeEnvelope<F, true>(events, envelope, std::forward<F>(lambda), step);
}
template <class F>
void pitchBendEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda)
{
multiplicativeEnvelope<F>(events, envelope, std::forward<F>(lambda));
}
template <class F>
void linearModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData, F&& lambda) void linearModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData, F&& lambda)
{ {
const auto events = resources.midiState.getCCEvents(ccData.cc); const auto events = resources.midiState.getCCEvents(ccData.cc);
@ -195,13 +214,15 @@ void linearModifier(const sfz::Resources& resources, absl::Span<float> span, con
}); });
} else { } else {
const float stepSize { lambda(ccData.data.step) }; const float stepSize { lambda(ccData.data.step) };
linearEnvelope(events, span, [&ccData, &curve, &lambda](float x) { linearEnvelope(
return lambda(curve.evalNormalized(x) * ccData.data.value); events, span, [&ccData, &curve, &lambda](float x) {
}, stepSize); return lambda(curve.evalNormalized(x) * ccData.data.value);
},
stepSize);
} }
} }
template<class F> template <class F>
void multiplicativeModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData, F&& lambda) void multiplicativeModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData, F&& lambda)
{ {
const auto events = resources.midiState.getCCEvents(ccData.cc); const auto events = resources.midiState.getCCEvents(ccData.cc);
@ -212,9 +233,11 @@ void multiplicativeModifier(const sfz::Resources& resources, absl::Span<float> s
}); });
} else { } else {
const float stepSize { lambda(ccData.data.step) }; const float stepSize { lambda(ccData.data.step) };
multiplicativeEnvelope(events, span, [&ccData, &curve, &lambda](float x) { multiplicativeEnvelope(
return lambda(curve.evalNormalized(x) * ccData.data.value); events, span, [&ccData, &curve, &lambda](float x) {
}, stepSize); return lambda(curve.evalNormalized(x) * ccData.data.value);
},
stepSize);
} }
} }

View file

@ -446,9 +446,9 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
}; };
if (region->bendStep > 1) if (region->bendStep > 1)
multiplicativeEnvelope(events, *bends, bendLambda, bendStepFactor); pitchBendEnvelope(events, *bends, bendLambda, bendStepFactor);
else else
multiplicativeEnvelope(events, *bends, bendLambda); pitchBendEnvelope(events, *bends, bendLambda);
applyGain<float>(*bends, *jumps); applyGain<float>(*bends, *jumps);
for (const auto& mod : region->tuneCC) { for (const auto& mod : region->tuneCC) {
@ -549,9 +549,9 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
return centsFactor(bendInCents); return centsFactor(bendInCents);
}; };
if (region->bendStep > 1) if (region->bendStep > 1)
multiplicativeEnvelope(events, *bends, bendLambda, bendStepFactor); pitchBendEnvelope(events, *bends, bendLambda, bendStepFactor);
else else
multiplicativeEnvelope(events, *bends, bendLambda); pitchBendEnvelope(events, *bends, bendLambda);
applyGain<float>(*bends, *frequencies); applyGain<float>(*bends, *frequencies);
for (const auto& mod : region->tuneCC) { for (const auto& mod : region->tuneCC) {