// 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 "SIMDHelpers.h" #include "OnePoleFilter.h" #include "SfzFilter.h" #include #include #include #include #include #include constexpr int blockSize { 1024 }; constexpr float sampleRate { 48000.0f }; class FilterFixture : public benchmark::Fixture { public: void SetUp(const ::benchmark::State& state) { input = std::vector(blockSize); output = std::vector(blockSize); cutoff = std::vector(blockSize); q = std::vector(blockSize); pksh = std::vector(blockSize); sfz::linearRamp(absl::MakeSpan(cutoff), 500, 1.0f); sfz::linearRamp(absl::MakeSpan(q), 0.0f, 0.001f); sfz::linearRamp(absl::MakeSpan(pksh), 0.0f, 0.001f); std::generate(input.begin(), input.end(), [&]() { return dist(gen); }); } void TearDown(const ::benchmark::State& state [[maybe_unused]]) { } std::random_device rd { }; std::mt19937 gen { rd() }; std::normal_distribution dist { 0, 0.5 }; std::vector cutoff; std::vector q; std::vector pksh; std::vector input; std::vector output; }; BENCHMARK_DEFINE_F(FilterFixture, OnePole_VA)(benchmark::State& state) { sfz::OnePoleFilter filter; for (auto _ : state) { const auto step = static_cast(state.range(0)); auto cutoffIterator = cutoff.begin(); auto inputIterator = input.begin(); auto outputIterator = output.begin(); while (cutoffIterator < cutoff.end()) { const auto gain = sfz::OnePoleFilter::normalizedGain(*cutoffIterator, sampleRate); filter.setGain(gain); filter.processLowpass({ inputIterator.base(), step }, { outputIterator.base(), step } ); cutoffIterator += step; inputIterator += step; outputIterator += step; } } } BENCHMARK_DEFINE_F(FilterFixture, OnePole_Faust)(benchmark::State& state) { sfz::Filter filter; filter.setType(sfz::FilterType::kFilterLpf1p); for (auto _ : state) { const auto step = static_cast(state.range(0)); auto cutoffIterator = cutoff.begin(); auto inputIterator = input.begin(); auto outputIterator = output.begin(); while (cutoffIterator < cutoff.end()) { filter.process(&inputIterator.base(), &outputIterator.base(), *cutoffIterator, 0.0, 0.0, step); cutoffIterator += step; inputIterator += step; outputIterator += step; } } } BENCHMARK_DEFINE_F(FilterFixture, TwoPole_Faust)(benchmark::State& state) { sfz::Filter filter; filter.setType(sfz::FilterType::kFilterLpf2p); for (auto _ : state) { const auto step = static_cast(state.range(0)); auto cutoffIterator = cutoff.begin(); auto qIterator = q.begin(); auto inputIterator = input.begin(); auto outputIterator = output.begin(); while (cutoffIterator < cutoff.end()) { filter.process(&inputIterator.base(), &outputIterator.base(), *cutoffIterator, *qIterator, 0.0, step); qIterator += step; cutoffIterator += step; inputIterator += step; outputIterator += step; } } } BENCHMARK_DEFINE_F(FilterFixture, TwoPoleShelf_Faust)(benchmark::State& state) { sfz::Filter filter; filter.setType(sfz::FilterType::kFilterLsh); for (auto _ : state) { const auto step = static_cast(state.range(0)); auto cutoffIterator = cutoff.begin(); auto qIterator = q.begin(); auto pkshIterator = pksh.begin(); auto inputIterator = input.begin(); auto outputIterator = output.begin(); while (cutoffIterator < cutoff.end()) { filter.process(&inputIterator.base(), &outputIterator.base(), *cutoffIterator, *qIterator, *pkshIterator, step); qIterator += step; cutoffIterator += step; pkshIterator += step; inputIterator += step; outputIterator += step; } } } BENCHMARK_REGISTER_F(FilterFixture, OnePole_VA)->RangeMultiplier(2)->Range(1, 1 << 8); BENCHMARK_REGISTER_F(FilterFixture, OnePole_Faust)->RangeMultiplier(2)->Range(1, 1 << 8); BENCHMARK_REGISTER_F(FilterFixture, TwoPole_Faust)->RangeMultiplier(2)->Range(1, 1 << 8); BENCHMARK_REGISTER_F(FilterFixture, TwoPoleShelf_Faust)->RangeMultiplier(2)->Range(1, 1 << 8); BENCHMARK_MAIN();