Ported the old envelope tests to the new free functions
This commit is contained in:
parent
5412593da9
commit
bc60b19c4b
2 changed files with 168 additions and 264 deletions
|
|
@ -348,11 +348,15 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
|
|||
{
|
||||
ASSERT(events.size() > 0);
|
||||
ASSERT(events[0].delay == 0);
|
||||
if (envelope.size() == 0)
|
||||
return;
|
||||
|
||||
const auto maxDelay = static_cast<int>(envelope.size() - 1);
|
||||
|
||||
auto lastValue = lambda(events[0].value);
|
||||
auto lastDelay = events[0].delay;
|
||||
for (unsigned i = 1; i < events.size(); ++ i) {
|
||||
const auto length = events[i].delay - lastDelay;
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++ i) {
|
||||
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||
const auto step = (lambda(events[i].value) - lastValue)/ length;
|
||||
lastValue = linearRamp<float>(envelope.subspan(lastDelay, length), lastValue, step);
|
||||
lastDelay += length;
|
||||
|
|
@ -366,16 +370,21 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
|
|||
ASSERT(events.size() > 0);
|
||||
ASSERT(events[0].delay == 0);
|
||||
ASSERT(step != 0.0);
|
||||
|
||||
if (envelope.size() == 0)
|
||||
return;
|
||||
|
||||
auto quantize = [step](float value) -> float {
|
||||
return std::round(value / step) * step;
|
||||
};
|
||||
const auto maxDelay = static_cast<int>(envelope.size() - 1);
|
||||
|
||||
auto lastValue = quantize(lambda(events[0].value));
|
||||
auto lastDelay = events[0].delay;
|
||||
for (unsigned i = 1; i < events.size(); ++ i) {
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++ i) {
|
||||
const auto nextValue = quantize(lambda(events[i].value));
|
||||
const auto difference = std::abs(nextValue - lastValue);
|
||||
const auto length = events[i].delay - lastDelay;
|
||||
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||
|
||||
if (difference < step) {
|
||||
fill<float>(envelope.subspan(lastDelay, length), lastValue);
|
||||
|
|
@ -401,10 +410,14 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
|
|||
ASSERT(events.size() > 0);
|
||||
ASSERT(events[0].delay == 0);
|
||||
|
||||
if (envelope.size() == 0)
|
||||
return;
|
||||
const auto maxDelay = static_cast<int>(envelope.size() - 1);
|
||||
|
||||
auto lastValue = lambda(events[0].value);
|
||||
auto lastDelay = events[0].delay;
|
||||
for (unsigned i = 1; i < events.size(); ++ i) {
|
||||
const auto length = events[i].delay - lastDelay;
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++ i) {
|
||||
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||
const auto nextValue = lambda(events[i].value);
|
||||
const auto step = std::exp((std::log(nextValue) - std::log(lastValue)) / length);
|
||||
multiplicativeRamp<float>(envelope.subspan(lastDelay, length), lastValue, step);
|
||||
|
|
@ -420,7 +433,10 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
|
|||
ASSERT(events.size() > 0);
|
||||
ASSERT(events[0].delay == 0);
|
||||
ASSERT(step != 0.0f);
|
||||
DBG("Called the quantized version with step " << step);
|
||||
|
||||
if (envelope.size() == 0)
|
||||
return;
|
||||
const auto maxDelay = static_cast<int>(envelope.size() - 1);
|
||||
|
||||
const auto logStep = std::log(step);
|
||||
// If we assume that a = b.q^r for b in (1, q) then
|
||||
|
|
@ -434,8 +450,8 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
|
|||
|
||||
auto lastValue = quantize(lambda(events[0].value));
|
||||
auto lastDelay = events[0].delay;
|
||||
for (unsigned i = 1; i < events.size(); ++ i) {
|
||||
const auto length = events[i].delay - lastDelay;
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++ i) {
|
||||
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||
const auto nextValue = quantize(lambda(events[i].value));
|
||||
const auto difference = nextValue > lastValue ? nextValue / lastValue : lastValue / nextValue;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,360 +30,248 @@ inline bool approxEqual(absl::Span<const Type> lhs, absl::Span<const Type> rhs,
|
|||
return true;
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Basic state")
|
||||
const auto idModifier = [] (float x) { return x; };
|
||||
const auto twiceModifier = [] (float x) { return 2 * x; };
|
||||
const auto expModifier = [] (float x) { return std::exp(x); };
|
||||
|
||||
TEST_CASE("[Envelopes] Empty")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f}
|
||||
};
|
||||
std::array<float, 5> output;
|
||||
std::array<float, 5> expected { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
std::array<float, 5> expectedMul { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(output == expected);
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), expModifier);
|
||||
REQUIRE(output == expectedMul);
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), expModifier, 2.0f);
|
||||
REQUIRE(output == expectedMul);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Basic event")
|
||||
TEST_CASE("[Envelopes] Linear basic")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(4, 1.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.25f, 0.5f, 0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{4, 1.0f}
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 0.25f, 0.5f, 0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] 2 events, close")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(4, 1.0f);
|
||||
envelope.registerEvent(5, 2.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.25f, 0.5f, 0.75f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{4, 1.0f},
|
||||
{5, 2.0f}
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 0.25f, 0.5f, 0.75f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("[LinearEnvelope] 2 events, far")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
envelope.registerEvent(6, 2.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.5f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.0f, 2.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] 2 events, reversed")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(6, 2.0f);
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.5f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.0f, 2.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] 3 events, overlapping")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
envelope.registerEvent(6, 2.0f);
|
||||
envelope.registerEvent(6, 3.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.0f, 3.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 2.0f}
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 0.5f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.0f, 2.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] 3 events, out of block")
|
||||
{
|
||||
// sfz::LinearEnvelope<float> envelope;
|
||||
// envelope.registerEvent(2, 1.0f);
|
||||
// envelope.registerEvent(6, 2.0f);
|
||||
// envelope.registerEvent(10, 3.0f);
|
||||
// std::array<float, 8> output;
|
||||
// std::array<float, 8> expected { 0.5f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 3.0f, 3.0f }; // TODO: this one is a bit strange
|
||||
// envelope.getBlock(absl::MakeSpan(output));
|
||||
// REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] 3 events, out of block, with another block call")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
envelope.registerEvent(6, 2.0f);
|
||||
envelope.registerEvent(10, 3.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] 2 events, with another block call")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
envelope.registerEvent(6, 2.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 2.0f},
|
||||
{10, 3.0f}
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 0.5f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.5f, 3.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] 2 events, function")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.setFunction([](float x) { return 2 * x; });
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
envelope.registerEvent(6, 2.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.0f, 4.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 2.0f}
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 1.0f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.0f, 4.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), twiceModifier);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
envelope.registerEvent(6, 2.0f);
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 2.0f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized with unquantized targets")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.1f);
|
||||
envelope.registerEvent(6, 1.9f);
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.1f},
|
||||
{6, 1.9f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
envelope.registerEvent(6, 3.0f);
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 3.0f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps and an unquantized out of block step")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
envelope.registerEvent(6, 3.0f);
|
||||
envelope.registerEvent(10, 4.2f);
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 3.0f},
|
||||
{10, 4.2f},
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 4.0f, 4.0f };
|
||||
std::array<float, 8> expected2 { 4.0f, 4.0f, 4.0f,4.0f, 4.0f, 4.0f, 4.0f, 4.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 4.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected2);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Going down quantized with 2 steps")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.reset(3.0f);
|
||||
envelope.registerEvent(2, 2.0f);
|
||||
envelope.registerEvent(6, 0.0f);
|
||||
sfz::EventVector events {
|
||||
{0, 3.0f},
|
||||
{2, 2.0f},
|
||||
{6, 0.0f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 3.0f, 2.0f, 2.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps and starting unquantized")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.reset(0.1f);
|
||||
envelope.registerEvent(3, 1.0f);
|
||||
envelope.registerEvent(7, 3.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.1f, 0.1f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Going down quantized with 2 steps and starting unquantized")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.reset(3.6f);
|
||||
envelope.registerEvent(4, 1.0f);
|
||||
envelope.registerEvent(7, 0.0);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 3.6f, 3.0f, 2.0f, 2.0f, 1.0f, 1.0f, 0.0f, 0.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized with unclean events")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.2f);
|
||||
envelope.registerEvent(6, 2.5f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized 3 events, one out of block")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0f);
|
||||
envelope.registerEvent(6, 2.0f);
|
||||
envelope.registerEvent(10, 3.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 3.0f, 3.0f };
|
||||
std::array<float, 8> expected2 { 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected2);
|
||||
}
|
||||
|
||||
//
|
||||
TEST_CASE("[MultiplicativeEnvelope] Basic state")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
std::array<float, 5> output;
|
||||
std::array<float, 5> expected { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
std::array<float, 8> expected { 3.0f, 3.0f, 2.0f, 2.0f, 1.0f, 1.0f, 0.0f, 0.0f };
|
||||
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] Basic event")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.registerEvent(4, 2.0f);
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{4, 2.0f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.1892f, 1.4142f, 1.68176f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
std::array<float, 8> expected { 1.0f, 1.1892f, 1.4142f, 1.68176f, 2.0f, 2.0f, 2.0f, 2.0f };
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(approxEqual<float>(output, expected));
|
||||
}
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] 2 events")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.registerEvent(4, 2.0f);
|
||||
envelope.registerEvent(5, 4.0f);
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{4, 2.0f},
|
||||
{5, 4.0f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.1892f, 1.4142f, 1.68176f, 2.0f, 4.0f, 4.0f, 4.0f, 4.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
std::array<float, 8> expected { 1.0f, 1.1892f, 1.4142f, 1.68176f, 2.0f, 4.0f, 4.0f, 4.0f};
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(approxEqual<float>(output, expected));
|
||||
}
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] 2 events, far")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 2.0f);
|
||||
envelope.registerEvent(6, 4.0f);
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{2, 2.0f},
|
||||
{6, 4.0f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.4142f, 2.0f, 2.37841f, 2.82843f, 3.36358f, 4.0f, 4.0f, 4.0f };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
std::array<float, 8> expected { 1.0f, 1.4142f, 2.0f, 2.37841f, 2.82843f, 3.36358f, 4.0f, 4.0f};
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(approxEqual<float>(output, expected));
|
||||
}
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with 2 steps")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 2.0f);
|
||||
envelope.registerEvent(6, 4.0f);
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{2, 2.0f},
|
||||
{6, 4.0f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 4.0f, 4.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
||||
std::array<float, 8> expected { 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 4.0f};
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier, 2.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with an unquantized out of range step")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 2.0f);
|
||||
envelope.registerEvent(6, 4.0f);
|
||||
envelope.registerEvent(10, 8.2f);
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{2, 2.0f},
|
||||
{6, 4.0f},
|
||||
{10, 8.2f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 8.0f, 8.0f };
|
||||
std::array<float, 8> expected2 { 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, 8.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
||||
std::array<float, 8> expected { 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 8.0f };
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier, 2.0f);
|
||||
REQUIRE(output == expected);
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
||||
REQUIRE(output == expected2);
|
||||
}
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] Going down quantized with 2 steps")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.reset(4.0f);
|
||||
envelope.registerEvent(2, 2.0f);
|
||||
envelope.registerEvent(6, 0.5f);
|
||||
sfz::EventVector events {
|
||||
{0, 4.0f},
|
||||
{2, 2.0f},
|
||||
{6, 0.5f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 4.0f, 2.0f, 2.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
||||
std::array<float, 8> expected { 4.0f, 4.0f, 2.0f, 2.0f, 1.0f, 1.0f, 0.5f, 0.5f };
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier, 2.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with unclean events")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.2f);
|
||||
envelope.registerEvent(6, 2.5f);
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{2, 1.2f},
|
||||
{6, 2.5f}
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
||||
std::array<float, 8> expected { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f };
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier, 2.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with 2 steps and starting unquantized")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.reset(0.9f);
|
||||
envelope.registerEvent(3, 1.0f);
|
||||
envelope.registerEvent(7, 4.0f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.9f, 0.9f, 1.0f, 1.0f, 2.0f, 2.0f, 4.0f, 4.0f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] Going down quantized with 2 steps and starting unquantized")
|
||||
{
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.reset(4.6f);
|
||||
envelope.registerEvent(4, 1.0f);
|
||||
envelope.registerEvent(7, 0.25f);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 4.6f, 2.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.25f, 0.25f };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[MultiplicativeEnvelope] Pitch envelope basic function")
|
||||
{
|
||||
sfz::Buffer<float> output { 256 };
|
||||
sfz::MultiplicativeEnvelope<float> envelope;
|
||||
envelope.setFunction([](float pitchValue){
|
||||
const auto normalizedBend = sfz::normalizeBend(pitchValue);
|
||||
const auto bendInCents = normalizedBend * 200.0f;
|
||||
return sfz::centsFactor(bendInCents);
|
||||
});
|
||||
envelope.reset(0.0f);
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
REQUIRE(output[255] == 1.0_a);
|
||||
envelope.registerEvent(252, -6020.0f);
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
REQUIRE(output[255] == Approx(0.9168).epsilon(0.01));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue