#include "../sources/OnePoleFilter.h" #include "catch2/catch.hpp" #include "cnpy.h" #include "gsl/gsl-lite.hpp" #include #include using namespace Catch::literals; template void testInputOutput(const std::filesystem::path& inputNumpyFile, const std::filesystem::path& outputNumpyFile, Type gain) { const auto input = cnpy::npy_load(inputNumpyFile.string()); REQUIRE( input.word_size == 8 ); const auto inputSpan = gsl::make_span(input.data(), input.shape[0]); const auto output = cnpy::npy_load(outputNumpyFile.string()); REQUIRE( output.word_size == 8 ); const auto outputSpan = gsl::make_span(output.data(), output.shape[0]); auto size = std::min(outputSpan.size(), inputSpan.size()); REQUIRE( size > 0 ); std::vector inputData; std::vector expectedData; inputData.reserve(size); expectedData.reserve(size); for (auto& data: inputSpan) inputData.push_back(static_cast(data)); for (auto& data: outputSpan) expectedData.push_back(static_cast(data)); OnePoleFilter filter { gain }; std::vector outputData (size); filter.processLowpass(inputData, outputData); for (size_t i = 0; i < size; ++i) REQUIRE( outputData[i] == Approx(expectedData[i]) ); filter.reset(); std::fill(outputData.begin(), outputData.end(), 0.0); std::vector gains(size); std::fill(gains.begin(), gains.end(), gain); filter.processLowpassVariableGain(inputData, outputData, gains); for (size_t i = 0; i < size; ++i) REQUIRE( outputData[i] == Approx(expectedData[i]) ); } TEST_CASE("[OnePoleFilter] Float") { testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.1.npy", 0.1f ); testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.3.npy", 0.3f ); testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.5.npy", 0.5f ); testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.7.npy", 0.7f ); testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.9.npy", 0.9f ); } TEST_CASE("[OnePoleFilter] Double") { testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.1.npy", 0.1f ); testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.3.npy", 0.3f ); testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.5.npy", 0.5f ); testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.7.npy", 0.7f ); testInputOutput( std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_output_gain_0.9.npy", 0.9f ); }