sfizz/benchmarks/BM_filterModulation.cpp
Paul Ferrand 0ed1f4cbeb Clean up the va OPF and wrap it as a linear smoother
Move modifiers and their helpers in their own files
Add an enum class for modifiers and facilities to iterate over all possible targets
Add smoothers to the voices and preallocate them
Iterate over smoothers and modifiers jointly in the voices for each target
2020-06-20 15:27:12 +02:00

149 lines
4.9 KiB
C++

// 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 "SfzHelpers.h"
#include "ScopedFTZ.h"
#include "SfzHelpers.h"
#include <benchmark/benchmark.h>
#include <random>
#include <numeric>
#include <vector>
#include <cmath>
#include <iostream>
constexpr int blockSize { 1024 };
constexpr float sampleRate { 48000.0f };
class FilterFixture : public benchmark::Fixture {
public:
void SetUp(const ::benchmark::State&) {
input = std::vector<float>(blockSize);
output = std::vector<float>(blockSize);
cutoff = std::vector<float>(blockSize);
q = std::vector<float>(blockSize);
pksh = std::vector<float>(blockSize);
sfz::linearRamp<float>(absl::MakeSpan(cutoff), 500, 1.0f);
sfz::linearRamp<float>(absl::MakeSpan(q), 0.0f, 0.001f);
sfz::linearRamp<float>(absl::MakeSpan(pksh), 0.0f, 0.001f);
std::generate(input.begin(), input.end(), [&]() { return dist(gen); });
}
void TearDown(const ::benchmark::State& /* state */) {
}
std::random_device rd { };
std::mt19937 gen { rd() };
std::normal_distribution<float> dist { 0, 0.5 };
std::vector<float> cutoff;
std::vector<float> q;
std::vector<float> pksh;
std::vector<float> input;
std::vector<float> output;
};
BENCHMARK_DEFINE_F(FilterFixture, OnePole_VA)(benchmark::State& state) {
ScopedFTZ ftz;
sfz::OnePoleFilter<float> filter;
for (auto _ : state)
{
const auto step = static_cast<size_t>(state.range(0));
auto cutoffPtr = cutoff.data();
auto inputPtr = input.data();
auto outputPtr = output.data();
const auto sentinel = cutoff.data() + blockSize;
while (cutoffPtr < sentinel)
{
const auto gain = sfz::vaGain(*cutoffPtr, sampleRate);
filter.setGain(gain);
filter.processLowpass({ inputPtr, step }, { outputPtr, step } );
cutoffPtr += step;
inputPtr += step;
outputPtr += step;
}
}
}
BENCHMARK_DEFINE_F(FilterFixture, OnePole_Faust)(benchmark::State& state) {
ScopedFTZ ftz;
sfz::Filter filter;
filter.init(sampleRate);
filter.setType(sfz::FilterType::kFilterLpf1p);
for (auto _ : state)
{
const auto step = static_cast<size_t>(state.range(0));
auto cutoffPtr = cutoff.data();
auto inputPtr = input.data();
auto outputPtr = output.data();
const auto sentinel = cutoff.data() + blockSize;
while (cutoffPtr < sentinel)
{
filter.process(&inputPtr, &outputPtr, *cutoffPtr, 0.0, 0.0, step);
cutoffPtr += step;
inputPtr += step;
outputPtr += step;
}
}
}
BENCHMARK_DEFINE_F(FilterFixture, TwoPole_Faust)(benchmark::State& state) {
ScopedFTZ ftz;
sfz::Filter filter;
filter.init(sampleRate);
filter.setType(sfz::FilterType::kFilterLpf2p);
for (auto _ : state)
{
const auto step = static_cast<size_t>(state.range(0));
auto cutoffPtr = cutoff.data();
auto qIterator = q.begin();
auto inputPtr = input.data();
auto outputPtr = output.data();
const auto sentinel = cutoff.data() + blockSize;
while (cutoffPtr < sentinel)
{
filter.process(&inputPtr, &outputPtr, *cutoffPtr, *qIterator, 0.0, step);
qIterator += step;
cutoffPtr += step;
inputPtr += step;
outputPtr += step;
}
}
}
BENCHMARK_DEFINE_F(FilterFixture, TwoPoleShelf_Faust)(benchmark::State& state) {
ScopedFTZ ftz;
sfz::Filter filter;
filter.init(sampleRate);
filter.setType(sfz::FilterType::kFilterLsh);
for (auto _ : state)
{
const auto step = static_cast<size_t>(state.range(0));
auto cutoffPtr = cutoff.data();
auto qIterator = q.begin();
auto pkshIterator = pksh.begin();
auto inputPtr = input.data();
auto outputPtr = output.data();
const auto sentinel = cutoff.data() + blockSize;
while (cutoffPtr < sentinel)
{
filter.process(&inputPtr, &outputPtr, *cutoffPtr, *qIterator, *pkshIterator, step);
qIterator += step;
cutoffPtr += step;
pkshIterator += step;
inputPtr += step;
outputPtr += 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();