diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c871114c..af4981dc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,6 +17,7 @@ set(SFIZZ_TEST_SOURCES FilesT.cpp MidiStateT.cpp OnePoleFilterT.cpp + InterpolatorsT.cpp RegionActivationT.cpp RegionValueComputationsT.cpp # If we're tweaking the curves this kind of tests does not make sense diff --git a/tests/InterpolatorsT.cpp b/tests/InterpolatorsT.cpp new file mode 100644 index 00000000..04742547 --- /dev/null +++ b/tests/InterpolatorsT.cpp @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: BSD-2-Clause + +// This code is part of the sfizz library and is licensed under a BSD 2-clause +// license. You should have receive a LICENSE.md file along with the code. +// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz + +#include "sfizz/Interpolators.h" +#include "catch2/catch.hpp" +#include +using namespace Catch::literals; + +TEST_CASE("[Interpolators] Sample at points") +{ + std::array values; + std::iota(values.begin(), values.end(), 0.0f); + for (unsigned i = 2; i < values.size() - 2; ++i) { + REQUIRE(sfz::interpolate(&values[i], 0.0f) + == Approx(values[i]).margin(1e-2)); + REQUIRE(sfz::interpolate(&values[i], 0.0f) + == Approx(values[i]).margin(1e-2)); + REQUIRE(sfz::interpolate(&values[i], 0.0f) + == Approx(values[i]).margin(1e-2)); + } +} + +TEST_CASE("[Interpolators] Sample next") +{ + std::array values; + std::iota(values.begin(), values.end(), 0.0f); + for (unsigned i = 2; i < values.size() - 2; ++i) { + REQUIRE(sfz::interpolate(&values[i], 1.0f) + == Approx(values[i + 1]).margin(1e-2)); + REQUIRE(sfz::interpolate(&values[i], 1.0f) + == Approx(values[i + 1]).margin(1e-2)); + REQUIRE(sfz::interpolate(&values[i], 1.0f) + == Approx(values[i + 1]).margin(1e-2)); + } +} + +TEST_CASE("[Interpolators] Straight line") +{ + std::array values; + std::iota(values.begin(), values.end(), 0.0f); + for (unsigned i = 2; i < values.size() - 2; ++i) { + REQUIRE(sfz::interpolate(&values[i], 0.5f) + == Approx(values[i] + 0.5f).margin(1e-2)); + REQUIRE(sfz::interpolate(&values[i], 0.5f) + == Approx(values[i] + 0.5f).margin(1e-2)); + REQUIRE(sfz::interpolate(&values[i], 0.5f) + == Approx(values[i] + 0.5f).margin(1e-2)); + } +} + +TEST_CASE("[Interpolators] Squares") +{ + std::array x; + std::array y; + for (unsigned i = 0; i < x.size(); ++i) { + x[i] = static_cast(i) / static_cast(x.size()); + y[i] = x[i] * x[i]; + } + + for (unsigned i = 2; i < x.size() - 2; ++i) { + const auto half_x = x[i] + 0.5f / static_cast(x.size()); + const auto expected = (half_x) * (half_x); + REQUIRE(sfz::interpolate(&y[i], 0.5f) + == Approx(expected).margin(1e-2)); + REQUIRE(sfz::interpolate(&y[i], 0.5f) + == Approx(expected).margin(1e-2)); + } +}