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.size() > 0);
|
||||||
ASSERT(events[0].delay == 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 lastValue = lambda(events[0].value);
|
||||||
auto lastDelay = events[0].delay;
|
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 length = events[i].delay - lastDelay;
|
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||||
const auto step = (lambda(events[i].value) - lastValue)/ length;
|
const auto step = (lambda(events[i].value) - lastValue)/ length;
|
||||||
lastValue = linearRamp<float>(envelope.subspan(lastDelay, length), lastValue, step);
|
lastValue = linearRamp<float>(envelope.subspan(lastDelay, length), lastValue, step);
|
||||||
lastDelay += length;
|
lastDelay += length;
|
||||||
|
|
@ -366,16 +370,21 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
|
||||||
ASSERT(events.size() > 0);
|
ASSERT(events.size() > 0);
|
||||||
ASSERT(events[0].delay == 0);
|
ASSERT(events[0].delay == 0);
|
||||||
ASSERT(step != 0.0);
|
ASSERT(step != 0.0);
|
||||||
|
|
||||||
|
if (envelope.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
auto quantize = [step](float value) -> float {
|
auto quantize = [step](float value) -> float {
|
||||||
return std::round(value / step) * step;
|
return std::round(value / step) * step;
|
||||||
};
|
};
|
||||||
|
const auto maxDelay = static_cast<int>(envelope.size() - 1);
|
||||||
|
|
||||||
auto lastValue = quantize(lambda(events[0].value));
|
auto lastValue = quantize(lambda(events[0].value));
|
||||||
auto lastDelay = events[0].delay;
|
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 nextValue = quantize(lambda(events[i].value));
|
||||||
const auto difference = std::abs(nextValue - lastValue);
|
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) {
|
if (difference < step) {
|
||||||
fill<float>(envelope.subspan(lastDelay, length), lastValue);
|
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.size() > 0);
|
||||||
ASSERT(events[0].delay == 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 lastValue = lambda(events[0].value);
|
||||||
auto lastDelay = events[0].delay;
|
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 length = events[i].delay - lastDelay;
|
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||||
const auto nextValue = lambda(events[i].value);
|
const auto nextValue = lambda(events[i].value);
|
||||||
const auto step = std::exp((std::log(nextValue) - std::log(lastValue)) / length);
|
const auto step = std::exp((std::log(nextValue) - std::log(lastValue)) / length);
|
||||||
multiplicativeRamp<float>(envelope.subspan(lastDelay, length), lastValue, step);
|
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.size() > 0);
|
||||||
ASSERT(events[0].delay == 0);
|
ASSERT(events[0].delay == 0);
|
||||||
ASSERT(step != 0.0f);
|
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);
|
const auto logStep = std::log(step);
|
||||||
// If we assume that a = b.q^r for b in (1, q) then
|
// 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 lastValue = quantize(lambda(events[0].value));
|
||||||
auto lastDelay = events[0].delay;
|
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 length = events[i].delay - lastDelay;
|
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||||
const auto nextValue = quantize(lambda(events[i].value));
|
const auto nextValue = quantize(lambda(events[i].value));
|
||||||
const auto difference = nextValue > lastValue ? nextValue / lastValue : lastValue / nextValue;
|
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;
|
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> output;
|
||||||
std::array<float, 5> expected { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
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);
|
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;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(4, 1.0f);
|
{0, 0.0f},
|
||||||
std::array<float, 8> output;
|
{4, 1.0f}
|
||||||
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));
|
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);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[LinearEnvelope] 2 events, close")
|
TEST_CASE("[LinearEnvelope] 2 events, close")
|
||||||
{
|
{
|
||||||
sfz::LinearEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(4, 1.0f);
|
{0, 0.0f},
|
||||||
envelope.registerEvent(5, 2.0f);
|
{4, 1.0f},
|
||||||
std::array<float, 8> output;
|
{5, 2.0f}
|
||||||
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));
|
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);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("[LinearEnvelope] 2 events, far")
|
TEST_CASE("[LinearEnvelope] 2 events, far")
|
||||||
{
|
{
|
||||||
sfz::LinearEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(2, 1.0f);
|
{0, 0.0f},
|
||||||
envelope.registerEvent(6, 2.0f);
|
{2, 1.0f},
|
||||||
std::array<float, 8> output;
|
{6, 2.0f}
|
||||||
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));
|
std::array<float, 9> output;
|
||||||
REQUIRE(output == expected);
|
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);
|
||||||
|
|
||||||
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));
|
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[LinearEnvelope] 3 events, out of block")
|
TEST_CASE("[LinearEnvelope] 3 events, out of block")
|
||||||
{
|
{
|
||||||
// sfz::LinearEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
// envelope.registerEvent(2, 1.0f);
|
{0, 0.0f},
|
||||||
// envelope.registerEvent(6, 2.0f);
|
{2, 1.0f},
|
||||||
// envelope.registerEvent(10, 3.0f);
|
{6, 2.0f},
|
||||||
// std::array<float, 8> output;
|
{10, 3.0f}
|
||||||
// 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));
|
std::array<float, 9> output;
|
||||||
// REQUIRE(output == expected);
|
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);
|
||||||
|
|
||||||
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));
|
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[LinearEnvelope] 2 events, function")
|
TEST_CASE("[LinearEnvelope] 2 events, function")
|
||||||
{
|
{
|
||||||
sfz::LinearEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.setFunction([](float x) { return 2 * x; });
|
{0, 0.0f},
|
||||||
envelope.registerEvent(2, 1.0f);
|
{2, 1.0f},
|
||||||
envelope.registerEvent(6, 2.0f);
|
{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 };
|
std::array<float, 9> output;
|
||||||
envelope.getBlock(absl::MakeSpan(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);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[LinearEnvelope] Get quantized")
|
TEST_CASE("[LinearEnvelope] Get quantized")
|
||||||
{
|
{
|
||||||
sfz::LinearEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(2, 1.0f);
|
{0, 0.0f},
|
||||||
envelope.registerEvent(6, 2.0f);
|
{2, 1.0f},
|
||||||
|
{6, 2.0f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f };
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[LinearEnvelope] Get quantized with unquantized targets")
|
TEST_CASE("[LinearEnvelope] Get quantized with unquantized targets")
|
||||||
{
|
{
|
||||||
sfz::LinearEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(2, 1.1f);
|
{0, 0.0f},
|
||||||
envelope.registerEvent(6, 1.9f);
|
{2, 1.1f},
|
||||||
|
{6, 1.9f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f };
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps")
|
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps")
|
||||||
{
|
{
|
||||||
sfz::LinearEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(2, 1.0f);
|
{0, 0.0f},
|
||||||
envelope.registerEvent(6, 3.0f);
|
{2, 1.0f},
|
||||||
|
{6, 3.0f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f };
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps and an unquantized out of block step")
|
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps and an unquantized out of block step")
|
||||||
{
|
{
|
||||||
sfz::LinearEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(2, 1.0f);
|
{0, 0.0f},
|
||||||
envelope.registerEvent(6, 3.0f);
|
{2, 1.0f},
|
||||||
envelope.registerEvent(10, 4.2f);
|
{6, 3.0f},
|
||||||
|
{10, 4.2f},
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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> expected { 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 4.0f };
|
||||||
std::array<float, 8> expected2 { 4.0f, 4.0f, 4.0f,4.0f, 4.0f, 4.0f, 4.0f, 4.0f };
|
linearEnvelope(events, absl::MakeSpan(output), idModifier, 1.0f);
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
|
||||||
REQUIRE(output == expected2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("[LinearEnvelope] Going down quantized with 2 steps")
|
TEST_CASE("[LinearEnvelope] Going down quantized with 2 steps")
|
||||||
{
|
{
|
||||||
sfz::LinearEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.reset(3.0f);
|
{0, 3.0f},
|
||||||
envelope.registerEvent(2, 2.0f);
|
{2, 2.0f},
|
||||||
envelope.registerEvent(6, 0.0f);
|
{6, 0.0f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 3.0f, 3.0f, 2.0f, 2.0f, 1.0f, 1.0f, 0.0f, 0.0f };
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
linearEnvelope(events, absl::MakeSpan(output), idModifier, 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));
|
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MultiplicativeEnvelope] Basic event")
|
TEST_CASE("[MultiplicativeEnvelope] Basic event")
|
||||||
{
|
{
|
||||||
sfz::MultiplicativeEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(4, 2.0f);
|
{0, 1.0f},
|
||||||
|
{4, 2.0f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 1.0f, 1.1892f, 1.4142f, 1.68176f, 2.0f, 2.0f, 2.0f, 2.0f };
|
||||||
envelope.getBlock(absl::MakeSpan(output));
|
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||||
REQUIRE(approxEqual<float>(output, expected));
|
REQUIRE(approxEqual<float>(output, expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MultiplicativeEnvelope] 2 events")
|
TEST_CASE("[MultiplicativeEnvelope] 2 events")
|
||||||
{
|
{
|
||||||
sfz::MultiplicativeEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(4, 2.0f);
|
{0, 1.0f},
|
||||||
envelope.registerEvent(5, 4.0f);
|
{4, 2.0f},
|
||||||
|
{5, 4.0f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 1.0f, 1.1892f, 1.4142f, 1.68176f, 2.0f, 4.0f, 4.0f, 4.0f};
|
||||||
envelope.getBlock(absl::MakeSpan(output));
|
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||||
REQUIRE(approxEqual<float>(output, expected));
|
REQUIRE(approxEqual<float>(output, expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MultiplicativeEnvelope] 2 events, far")
|
TEST_CASE("[MultiplicativeEnvelope] 2 events, far")
|
||||||
{
|
{
|
||||||
sfz::MultiplicativeEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(2, 2.0f);
|
{0, 1.0f},
|
||||||
envelope.registerEvent(6, 4.0f);
|
{2, 2.0f},
|
||||||
|
{6, 4.0f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 1.0f, 1.4142f, 2.0f, 2.37841f, 2.82843f, 3.36358f, 4.0f, 4.0f};
|
||||||
envelope.getBlock(absl::MakeSpan(output));
|
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||||
REQUIRE(approxEqual<float>(output, expected));
|
REQUIRE(approxEqual<float>(output, expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with 2 steps")
|
TEST_CASE("[MultiplicativeEnvelope] Get quantized with 2 steps")
|
||||||
{
|
{
|
||||||
sfz::MultiplicativeEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(2, 2.0f);
|
{0, 1.0f},
|
||||||
envelope.registerEvent(6, 4.0f);
|
{2, 2.0f},
|
||||||
|
{6, 4.0f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 4.0f};
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier, 2.0f);
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with an unquantized out of range step")
|
TEST_CASE("[MultiplicativeEnvelope] Get quantized with an unquantized out of range step")
|
||||||
{
|
{
|
||||||
sfz::MultiplicativeEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(2, 2.0f);
|
{0, 1.0f},
|
||||||
envelope.registerEvent(6, 4.0f);
|
{2, 2.0f},
|
||||||
envelope.registerEvent(10, 8.2f);
|
{6, 4.0f},
|
||||||
|
{10, 8.2f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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> expected { 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 8.0f };
|
||||||
std::array<float, 8> expected2 { 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, 8.0f };
|
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier, 2.0f);
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
|
||||||
REQUIRE(output == expected2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MultiplicativeEnvelope] Going down quantized with 2 steps")
|
TEST_CASE("[MultiplicativeEnvelope] Going down quantized with 2 steps")
|
||||||
{
|
{
|
||||||
sfz::MultiplicativeEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.reset(4.0f);
|
{0, 4.0f},
|
||||||
envelope.registerEvent(2, 2.0f);
|
{2, 2.0f},
|
||||||
envelope.registerEvent(6, 0.5f);
|
{6, 0.5f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 4.0f, 4.0f, 2.0f, 2.0f, 1.0f, 1.0f, 0.5f, 0.5f };
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier, 2.0f);
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with unclean events")
|
TEST_CASE("[MultiplicativeEnvelope] Get quantized with unclean events")
|
||||||
{
|
{
|
||||||
sfz::MultiplicativeEnvelope<float> envelope;
|
sfz::EventVector events {
|
||||||
envelope.registerEvent(2, 1.2f);
|
{0, 1.0f},
|
||||||
envelope.registerEvent(6, 2.5f);
|
{2, 1.2f},
|
||||||
|
{6, 2.5f}
|
||||||
|
};
|
||||||
std::array<float, 8> output;
|
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 };
|
std::array<float, 8> expected { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f };
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier, 2.0f);
|
||||||
REQUIRE(output == expected);
|
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