Merge branch 'hotfix/namespaces'

This commit is contained in:
paulfd 2019-09-25 23:49:00 +02:00
commit c19b055085
40 changed files with 407 additions and 970 deletions

View file

@ -52,56 +52,56 @@ public:
BENCHMARK_DEFINE_F(AddArray, Value_Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(AddArray, Value_Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
add<float, false>(1.1f, absl::MakeSpan(output)); sfz::add<float, false>(1.1f, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(AddArray, Value_SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(AddArray, Value_SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
add<float, true>(1.1f, absl::MakeSpan(output)); sfz::add<float, true>(1.1f, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(AddArray, Value_Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(AddArray, Value_Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
add<float, false>(1.1f, absl::MakeSpan(output).subspan(1)); sfz::add<float, false>(1.1f, absl::MakeSpan(output).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(AddArray, Value_SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(AddArray, Value_SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
add<float, true>(1.1f, absl::MakeSpan(output).subspan(1)); sfz::add<float, true>(1.1f, absl::MakeSpan(output).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(AddArray, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(AddArray, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
add<float, false>(input, absl::MakeSpan(output)); sfz::add<float, false>(input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(AddArray, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(AddArray, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
add<float, true>(input, absl::MakeSpan(output)); sfz::add<float, true>(input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(AddArray, Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(AddArray, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
add<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::add<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(AddArray, SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(AddArray, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
add<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::add<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }

View file

@ -60,14 +60,14 @@ BENCHMARK_DEFINE_F(CopyArray, StdCopy)(benchmark::State& state) {
BENCHMARK_DEFINE_F(CopyArray, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(CopyArray, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
copy<float, false>(input, absl::MakeSpan(output)); sfz::copy<float, false>(input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(CopyArray, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(CopyArray, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
copy<float, true>(input, absl::MakeSpan(output)); sfz::copy<float, true>(input, absl::MakeSpan(output));
} }
} }
@ -81,14 +81,14 @@ BENCHMARK_DEFINE_F(CopyArray, StdCopy_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(CopyArray, Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(CopyArray, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
copy<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::copy<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(CopyArray, SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(CopyArray, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
copy<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::copy<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }

View file

@ -52,28 +52,28 @@ public:
BENCHMARK_DEFINE_F(CumArray, Sum_Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(CumArray, Sum_Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
cumsum<float, false>(input, absl::MakeSpan(output)); sfz::cumsum<float, false>(input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(CumArray, Sum_SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(CumArray, Sum_SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
cumsum<float, true>(input, absl::MakeSpan(output)); sfz::cumsum<float, true>(input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(CumArray, Sum_Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(CumArray, Sum_Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
cumsum<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::cumsum<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(CumArray, Sum_SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(CumArray, Sum_SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
cumsum<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::cumsum<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }

View file

@ -39,7 +39,7 @@ public:
input = std::vector<float>(state.range(0)); input = std::vector<float>(state.range(0));
output = std::vector<float>(state.range(0)); output = std::vector<float>(state.range(0));
std::generate(input.begin(), input.end(), [&]() { return dist(gen); }); std::generate(input.begin(), input.end(), [&]() { return dist(gen); });
cumsum<float, false>(input, absl::MakeSpan(input)); sfz::cumsum<float, false>(input, absl::MakeSpan(input));
} }
void TearDown(const ::benchmark::State& state [[maybe_unused]]) { void TearDown(const ::benchmark::State& state [[maybe_unused]]) {
@ -54,28 +54,28 @@ public:
BENCHMARK_DEFINE_F(DiffArray, Diff_Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(DiffArray, Diff_Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
diff<float, false>(input, absl::MakeSpan(output)); sfz::diff<float, false>(input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(DiffArray, Diff_SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(DiffArray, Diff_SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
diff<float, true>(input, absl::MakeSpan(output)); sfz::diff<float, true>(input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(DiffArray, Diff_Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(DiffArray, Diff_Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
diff<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::diff<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(DiffArray, Diff_SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(DiffArray, Diff_SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
diff<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::diff<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }

View file

@ -29,7 +29,7 @@
#include <numeric> #include <numeric>
static void Dummy(benchmark::State& state) { static void Dummy(benchmark::State& state) {
Buffer<float> buffer (state.range(0)); sfz::Buffer<float> buffer (state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
@ -40,42 +40,42 @@ static void Dummy(benchmark::State& state) {
} }
static void FillScalar(benchmark::State& state) { static void FillScalar(benchmark::State& state) {
Buffer<float> buffer (state.range(0)); sfz::Buffer<float> buffer (state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) { for (auto _ : state) {
fill<float, false>(absl::MakeSpan(buffer), dist(gen)); sfz::fill<float, false>(absl::MakeSpan(buffer), dist(gen));
} }
} }
static void FillScalar_unaligned(benchmark::State& state) { static void FillScalar_unaligned(benchmark::State& state) {
Buffer<float> buffer (state.range(0)); sfz::Buffer<float> buffer (state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) { for (auto _ : state) {
fill<float, false>(absl::MakeSpan(buffer).subspan(1), dist(gen)); sfz::fill<float, false>(absl::MakeSpan(buffer).subspan(1), dist(gen));
} }
} }
static void FillSIMD(benchmark::State& state) { static void FillSIMD(benchmark::State& state) {
Buffer<float> buffer (state.range(0)); sfz::Buffer<float> buffer (state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) { for (auto _ : state) {
fill<float, true>(absl::MakeSpan(buffer), dist(gen)); sfz::fill<float, true>(absl::MakeSpan(buffer), dist(gen));
} }
} }
static void FillSIMD_unaligned(benchmark::State& state) { static void FillSIMD_unaligned(benchmark::State& state) {
Buffer<float> buffer (state.range(0)); sfz::Buffer<float> buffer (state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) { for (auto _ : state) {
fill<float, true>(absl::MakeSpan(buffer).subspan(1), dist(gen)); sfz::fill<float, true>(absl::MakeSpan(buffer).subspan(1), dist(gen));
} }
} }

View file

@ -83,14 +83,14 @@ BENCHMARK_DEFINE_F(GainSingle, Straight)(benchmark::State& state) {
BENCHMARK_DEFINE_F(GainSingle, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(GainSingle, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
applyGain<float, false>(gain, input, absl::MakeSpan(output)); sfz::applyGain<float, false>(gain, input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(GainSingle, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(GainSingle, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
applyGain<float, true>(gain, input, absl::MakeSpan(output)); sfz::applyGain<float, true>(gain, input, absl::MakeSpan(output));
} }
} }
@ -105,28 +105,28 @@ BENCHMARK_DEFINE_F(GainArray, Straight)(benchmark::State& state) {
BENCHMARK_DEFINE_F(GainArray, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(GainArray, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
applyGain<float, false>(gain, input, absl::MakeSpan(output)); sfz::applyGain<float, false>(gain, input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(GainArray, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(GainArray, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
applyGain<float, true>(gain, input, absl::MakeSpan(output)); sfz::applyGain<float, true>(gain, input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(GainArray, Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(GainArray, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
applyGain<float, false>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::applyGain<float, false>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(GainArray, SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(GainArray, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
applyGain<float, true>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::applyGain<float, true>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }

View file

@ -59,28 +59,28 @@ public:
BENCHMARK_DEFINE_F(InterpolationCast, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(InterpolationCast, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
sfzInterpolationCast<float, false>(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs)); sfz::sfzInterpolationCast<float, false>(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs));
} }
} }
BENCHMARK_DEFINE_F(InterpolationCast, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(InterpolationCast, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
sfzInterpolationCast<float, true>(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs)); sfz::sfzInterpolationCast<float, true>(floatJumps, absl::MakeSpan(jumps), absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs));
} }
} }
BENCHMARK_DEFINE_F(InterpolationCast, Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(InterpolationCast, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
sfzInterpolationCast<float, false>(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1)); sfz::sfzInterpolationCast<float, false>(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(InterpolationCast, SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(InterpolationCast, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
sfzInterpolationCast<float, true>(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1)); sfz::sfzInterpolationCast<float, true>(absl::MakeSpan(floatJumps).subspan(1), absl::MakeSpan(jumps).subspan(3), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1));
} }
} }

View file

@ -61,28 +61,28 @@ public:
BENCHMARK_DEFINE_F(LoopingFixture, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(LoopingFixture, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
loopingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 2.5f, loopEnd, loopStart); sfz::loopingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 2.5f, loopEnd, loopStart);
} }
} }
BENCHMARK_DEFINE_F(LoopingFixture, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(LoopingFixture, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
loopingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 2.5f, loopEnd, loopStart); sfz::loopingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 2.5f, loopEnd, loopStart);
} }
} }
BENCHMARK_DEFINE_F(LoopingFixture, Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(LoopingFixture, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
loopingSFZIndex<float, false>(absl::MakeSpan(jumps).subspan(1), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1), absl::MakeSpan(indices).subspan(3), 2.5f, loopEnd, loopStart); sfz::loopingSFZIndex<float, false>(absl::MakeSpan(jumps).subspan(1), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1), absl::MakeSpan(indices).subspan(3), 2.5f, loopEnd, loopStart);
} }
} }
BENCHMARK_DEFINE_F(LoopingFixture, SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(LoopingFixture, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
loopingSFZIndex<float, true>(absl::MakeSpan(jumps).subspan(1), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1), absl::MakeSpan(indices).subspan(3), 2.5f, loopEnd, loopStart); sfz::loopingSFZIndex<float, true>(absl::MakeSpan(jumps).subspan(1), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1), absl::MakeSpan(indices).subspan(3), 2.5f, loopEnd, loopStart);
} }
} }

View file

@ -64,7 +64,7 @@ BENCHMARK_DEFINE_F(MyFixture, ScalarExp)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
exp<float, false>(source, absl::MakeSpan(result)); sfz::exp<float, false>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -73,7 +73,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDExp)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
exp<float, true>(source, absl::MakeSpan(result)); sfz::exp<float, true>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -82,7 +82,7 @@ BENCHMARK_DEFINE_F(MyFixture, ScalarExp_Unaligned)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
exp<float, false>(absl::MakeSpan(source).subspan(1), absl::MakeSpan(result).subspan(1)); sfz::exp<float, false>(absl::MakeSpan(source).subspan(1), absl::MakeSpan(result).subspan(1));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -91,7 +91,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDExp_Unaligned)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
exp<float, true>(absl::MakeSpan(source).subspan(1), absl::MakeSpan(result).subspan(1)); sfz::exp<float, true>(absl::MakeSpan(source).subspan(1), absl::MakeSpan(result).subspan(1));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -100,7 +100,7 @@ BENCHMARK_DEFINE_F(MyFixture, ScalarLog)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
log<float, false>(source, absl::MakeSpan(result)); sfz::log<float, false>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -109,7 +109,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDLog)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
log<float, true>(source, absl::MakeSpan(result)); sfz::log<float, true>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -118,7 +118,7 @@ BENCHMARK_DEFINE_F(MyFixture, ScalarSin)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
sin<float, false>(source, absl::MakeSpan(result)); sfz::sin<float, false>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -127,7 +127,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDSin)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
sin<float, true>(source, absl::MakeSpan(result)); sfz::sin<float, true>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -136,7 +136,7 @@ BENCHMARK_DEFINE_F(MyFixture, ScalarCos)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
cos<float, false>(source, absl::MakeSpan(result)); sfz::cos<float, false>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -145,7 +145,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDCos)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
cos<float, true>(source, absl::MakeSpan(result)); sfz::cos<float, true>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }

View file

@ -51,7 +51,7 @@ BENCHMARK_DEFINE_F(MeanArray, Scalar)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
auto result = mean<float, false>(input); auto result = sfz::mean<float, false>(input);
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -60,7 +60,7 @@ BENCHMARK_DEFINE_F(MeanArray, SIMD)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
auto result = mean<float, true>(input); auto result = sfz::mean<float, true>(input);
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -69,7 +69,7 @@ BENCHMARK_DEFINE_F(MeanArray, Scalar_Unaligned)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
auto result = mean<float, false>(absl::MakeSpan(input).subspan(1)); auto result = sfz::mean<float, false>(absl::MakeSpan(input).subspan(1));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -78,7 +78,7 @@ BENCHMARK_DEFINE_F(MeanArray, SIMD_Unaligned)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
auto result = mean<float, true>(absl::MakeSpan(input).subspan(1)); auto result = sfz::mean<float, true>(absl::MakeSpan(input).subspan(1));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }

View file

@ -51,7 +51,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, Scalar)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
auto result = meanSquared<float, false>(input); auto result = sfz::meanSquared<float, false>(input);
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -60,7 +60,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, SIMD)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
auto result = meanSquared<float, true>(input); auto result = sfz::meanSquared<float, true>(input);
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -69,7 +69,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, Scalar_Unaligned)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
auto result = meanSquared<float, false>(absl::MakeSpan(input).subspan(1)); auto result = sfz::meanSquared<float, false>(absl::MakeSpan(input).subspan(1));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }
@ -78,7 +78,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, SIMD_Unaligned)
(benchmark::State& state) (benchmark::State& state)
{ {
for (auto _ : state) { for (auto _ : state) {
auto result = meanSquared<float, true>(absl::MakeSpan(input).subspan(1)); auto result = sfz::meanSquared<float, true>(absl::MakeSpan(input).subspan(1));
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
} }

View file

@ -63,28 +63,28 @@ BENCHMARK_DEFINE_F(MultiplyAdd, Straight)(benchmark::State& state) {
BENCHMARK_DEFINE_F(MultiplyAdd, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(MultiplyAdd, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
multiplyAdd<float, false>(gain, input, absl::MakeSpan(output)); sfz::multiplyAdd<float, false>(gain, input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(MultiplyAdd, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(MultiplyAdd, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
multiplyAdd<float, true>(gain, input, absl::MakeSpan(output)); sfz::multiplyAdd<float, true>(gain, input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(MultiplyAdd, Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(MultiplyAdd, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
multiplyAdd<float, false>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::multiplyAdd<float, false>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(MultiplyAdd, SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(MultiplyAdd, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
multiplyAdd<float, true>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::multiplyAdd<float, true>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }

View file

@ -66,27 +66,27 @@ public:
BENCHMARK_DEFINE_F(PanArray, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(PanArray, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
::pan<float, false>(pan, absl::MakeSpan(left), absl::MakeSpan(right)); sfz::pan<float, false>(pan, absl::MakeSpan(left), absl::MakeSpan(right));
} }
} }
BENCHMARK_DEFINE_F(PanArray, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(PanArray, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
::pan<float, true>(pan, absl::MakeSpan(left), absl::MakeSpan(right)); sfz::pan<float, true>(pan, absl::MakeSpan(left), absl::MakeSpan(right));
} }
} }
BENCHMARK_DEFINE_F(PanArray, BlockOps)(benchmark::State& state) { BENCHMARK_DEFINE_F(PanArray, BlockOps)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
::fill<float>(span2, 1.0f); sfz::fill<float>(span2, 1.0f);
::add<float>(span1, span2); sfz::add<float>(span1, span2);
::applyGain<float>(piFour<float>, span2); sfz::applyGain<float>(piFour<float>, span2);
::cos<float>(span2, span1); sfz::cos<float>(span2, span1);
::sin<float>(span2, span2); sfz::sin<float>(span2, span2);
::applyGain<float>(span1, absl::MakeSpan(left)); sfz::applyGain<float>(span1, absl::MakeSpan(left));
::applyGain<float>(span2, absl::MakeSpan(right)); sfz::applyGain<float>(span2, absl::MakeSpan(right));
} }
} }

View file

@ -42,7 +42,7 @@ public:
jumps.resize(state.range(0)); jumps.resize(state.range(0));
offsets.resize(state.range(0)); offsets.resize(state.range(0));
absl::c_generate(jumps, [&]() { return jumpDist(gen); }); absl::c_generate(jumps, [&]() { return jumpDist(gen); });
cumsum<int>(jumps, absl::MakeSpan(offsets)); sfz::cumsum<int>(jumps, absl::MakeSpan(offsets));
} }
void TearDown(const ::benchmark::State& state [[maybe_unused]]) { void TearDown(const ::benchmark::State& state [[maybe_unused]]) {
@ -58,7 +58,7 @@ public:
BENCHMARK_DEFINE_F(IterOffset, Pointers)(benchmark::State& state) { BENCHMARK_DEFINE_F(IterOffset, Pointers)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
diff<int>(offsets, absl::MakeSpan(jumps)); sfz::diff<int>(offsets, absl::MakeSpan(jumps));
auto jump = jumps.begin(); auto jump = jumps.begin();
auto in = source.begin(); auto in = source.begin();
auto out = result.begin(); auto out = result.begin();

View file

@ -28,7 +28,7 @@
static void Dummy(benchmark::State& state) { static void Dummy(benchmark::State& state) {
Buffer<float> output(state.range(0)); sfz::Buffer<float> output(state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
@ -40,96 +40,96 @@ static void Dummy(benchmark::State& state) {
} }
static void LinearScalar(benchmark::State& state) { static void LinearScalar(benchmark::State& state) {
Buffer<float> output(state.range(0)); sfz::Buffer<float> output(state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) for (auto _ : state)
{ {
auto value = dist(gen); auto value = dist(gen);
linearRamp<float, false>(absl::MakeSpan(output), 0.0f, value); sfz::linearRamp<float, false>(absl::MakeSpan(output), 0.0f, value);
} }
} }
static void LinearSIMD(benchmark::State& state) { static void LinearSIMD(benchmark::State& state) {
Buffer<float> output(state.range(0)); sfz::Buffer<float> output(state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) for (auto _ : state)
{ {
auto value = dist(gen); auto value = dist(gen);
linearRamp<float, true>(absl::MakeSpan(output), 0.0f, value); sfz::linearRamp<float, true>(absl::MakeSpan(output), 0.0f, value);
} }
} }
static void LinearScalarUnaligned(benchmark::State& state) { static void LinearScalarUnaligned(benchmark::State& state) {
Buffer<float> output(state.range(0)); sfz::Buffer<float> output(state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) for (auto _ : state)
{ {
auto value = dist(gen); auto value = dist(gen);
linearRamp<float, false>(absl::MakeSpan(output).subspan(1), 0.0f, value); sfz::linearRamp<float, false>(absl::MakeSpan(output).subspan(1), 0.0f, value);
} }
} }
static void LinearSIMDUnaligned(benchmark::State& state) { static void LinearSIMDUnaligned(benchmark::State& state) {
Buffer<float> output(state.range(0)); sfz::Buffer<float> output(state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) for (auto _ : state)
{ {
auto value = dist(gen); auto value = dist(gen);
linearRamp<float, true>(absl::MakeSpan(output).subspan(1), 0.0f, value); sfz::linearRamp<float, true>(absl::MakeSpan(output).subspan(1), 0.0f, value);
} }
} }
static void MulScalar(benchmark::State& state) { static void MulScalar(benchmark::State& state) {
Buffer<float> output(state.range(0)); sfz::Buffer<float> output(state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) for (auto _ : state)
{ {
auto value = dist(gen); auto value = dist(gen);
multiplicativeRamp<float, false>(absl::MakeSpan(output), 1.0f, value); sfz::multiplicativeRamp<float, false>(absl::MakeSpan(output), 1.0f, value);
} }
} }
static void MulSIMD(benchmark::State& state) { static void MulSIMD(benchmark::State& state) {
Buffer<float> output(state.range(0)); sfz::Buffer<float> output(state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) for (auto _ : state)
{ {
auto value = dist(gen); auto value = dist(gen);
multiplicativeRamp<float, true>(absl::MakeSpan(output), 1.0f, value); sfz::multiplicativeRamp<float, true>(absl::MakeSpan(output), 1.0f, value);
} }
} }
static void MulScalarUnaligned(benchmark::State& state) { static void MulScalarUnaligned(benchmark::State& state) {
Buffer<float> output(state.range(0)); sfz::Buffer<float> output(state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) for (auto _ : state)
{ {
auto value = dist(gen); auto value = dist(gen);
multiplicativeRamp<float, false>(absl::MakeSpan(output).subspan(1), 1.0f, value); sfz::multiplicativeRamp<float, false>(absl::MakeSpan(output).subspan(1), 1.0f, value);
} }
} }
static void MulSIMDUnaligned(benchmark::State& state) { static void MulSIMDUnaligned(benchmark::State& state) {
Buffer<float> output(state.range(0)); sfz::Buffer<float> output(state.range(0));
std::random_device rd { }; std::random_device rd { };
std::mt19937 gen { rd() }; std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 }; std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state) for (auto _ : state)
{ {
auto value = dist(gen); auto value = dist(gen);
multiplicativeRamp<float, true>(absl::MakeSpan(output).subspan(1), 1.0f, value); sfz::multiplicativeRamp<float, true>(absl::MakeSpan(output).subspan(1), 1.0f, value);
} }
} }

View file

@ -29,64 +29,64 @@
#include <absl/types/span.h> #include <absl/types/span.h>
static void Scalar(benchmark::State& state) { static void Scalar(benchmark::State& state) {
Buffer<float> input (state.range(0) * 2); sfz::Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0)); sfz::Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0)); sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f); std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
readInterleaved<float, false>(input, absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight)); sfz::readInterleaved<float, false>(input, absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight));
} }
} }
static void SSE(benchmark::State& state) { static void SSE(benchmark::State& state) {
Buffer<float> input (state.range(0) * 2); sfz::Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0)); sfz::Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0)); sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f); std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
readInterleaved<float, true>(input, absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight)); sfz::readInterleaved<float, true>(input, absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight));
} }
} }
static void Scalar_Unaligned(benchmark::State& state) { static void Scalar_Unaligned(benchmark::State& state) {
Buffer<float> input (state.range(0) * 2); sfz::Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0)); sfz::Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0)); sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f); std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
readInterleaved<float, false>(absl::MakeSpan(input).subspan(2), absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight)); sfz::readInterleaved<float, false>(absl::MakeSpan(input).subspan(2), absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight));
} }
} }
static void SSE_Unaligned(benchmark::State& state) { static void SSE_Unaligned(benchmark::State& state) {
Buffer<float> input (state.range(0) * 2); sfz::Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0)); sfz::Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0)); sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f); std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
readInterleaved<float, true>(absl::MakeSpan(input).subspan(2), absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight)); sfz::readInterleaved<float, true>(absl::MakeSpan(input).subspan(2), absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight));
} }
} }
static void Scalar_Unaligned_2(benchmark::State& state) { static void Scalar_Unaligned_2(benchmark::State& state) {
Buffer<float> input (state.range(0) * 2); sfz::Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0)); sfz::Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0)); sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f); std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
readInterleaved<float, false>(absl::MakeSpan(input).subspan(2), absl::MakeSpan(outputLeft).subspan(1), absl::MakeSpan(outputRight).subspan(3)); sfz::readInterleaved<float, false>(absl::MakeSpan(input).subspan(2), absl::MakeSpan(outputLeft).subspan(1), absl::MakeSpan(outputRight).subspan(3));
} }
} }
static void SSE_Unaligned_2(benchmark::State& state) { static void SSE_Unaligned_2(benchmark::State& state) {
Buffer<float> input (state.range(0) * 2); sfz::Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0)); sfz::Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0)); sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f); std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
readInterleaved<float, true>(absl::MakeSpan(input).subspan(2), absl::MakeSpan(outputLeft).subspan(1), absl::MakeSpan(outputRight).subspan(3)); sfz::readInterleaved<float, true>(absl::MakeSpan(input).subspan(2), absl::MakeSpan(outputLeft).subspan(1), absl::MakeSpan(outputRight).subspan(3));
} }
} }

View file

@ -60,28 +60,28 @@ public:
BENCHMARK_DEFINE_F(SaturatingFixture, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(SaturatingFixture, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
saturatingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 2.5f, loopEnd); sfz::saturatingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 2.5f, loopEnd);
} }
} }
BENCHMARK_DEFINE_F(SaturatingFixture, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(SaturatingFixture, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
saturatingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 2.5f, loopEnd); sfz::saturatingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 2.5f, loopEnd);
} }
} }
BENCHMARK_DEFINE_F(SaturatingFixture, Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(SaturatingFixture, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
saturatingSFZIndex<float, false>(absl::MakeSpan(jumps).subspan(1), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1), absl::MakeSpan(indices).subspan(3), 2.5f, loopEnd); sfz::saturatingSFZIndex<float, false>(absl::MakeSpan(jumps).subspan(1), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1), absl::MakeSpan(indices).subspan(3), 2.5f, loopEnd);
} }
} }
BENCHMARK_DEFINE_F(SaturatingFixture, SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(SaturatingFixture, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
saturatingSFZIndex<float, true>(absl::MakeSpan(jumps).subspan(1), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1), absl::MakeSpan(indices).subspan(3), 2.5f, loopEnd); sfz::saturatingSFZIndex<float, true>(absl::MakeSpan(jumps).subspan(1), absl::MakeSpan(leftCoeffs).subspan(2), absl::MakeSpan(rightCoeffs).subspan(1), absl::MakeSpan(indices).subspan(3), 2.5f, loopEnd);
} }
} }

View file

@ -53,28 +53,28 @@ public:
BENCHMARK_DEFINE_F(SubArray, Scalar)(benchmark::State& state) { BENCHMARK_DEFINE_F(SubArray, Scalar)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
subtract<float, false>(input, absl::MakeSpan(output)); sfz::subtract<float, false>(input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(SubArray, SIMD)(benchmark::State& state) { BENCHMARK_DEFINE_F(SubArray, SIMD)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
subtract<float, true>(input, absl::MakeSpan(output)); sfz::subtract<float, true>(input, absl::MakeSpan(output));
} }
} }
BENCHMARK_DEFINE_F(SubArray, Scalar_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(SubArray, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
subtract<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::subtract<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }
BENCHMARK_DEFINE_F(SubArray, SIMD_Unaligned)(benchmark::State& state) { BENCHMARK_DEFINE_F(SubArray, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state) for (auto _ : state)
{ {
subtract<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1)); sfz::subtract<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
} }
} }

View file

@ -29,73 +29,73 @@
#include <absl/types/span.h> #include <absl/types/span.h>
static void Interleaved_Write(benchmark::State& state) { static void Interleaved_Write(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0)); sfz::Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0)); sfz::Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2); sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f); std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f); std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
writeInterleaved<float, false>(inputLeft, inputRight, absl::MakeSpan(output)); sfz::writeInterleaved<float, false>(inputLeft, inputRight, absl::MakeSpan(output));
} }
} }
static void Interleaved_Write_SSE(benchmark::State& state) { static void Interleaved_Write_SSE(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0)); sfz::Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0)); sfz::Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2); sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f); std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f); std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
writeInterleaved<float, true>(inputLeft, inputRight, absl::MakeSpan(output)); sfz::writeInterleaved<float, true>(inputLeft, inputRight, absl::MakeSpan(output));
benchmark::DoNotOptimize(output); benchmark::DoNotOptimize(output);
} }
} }
static void Unaligned_Interleaved_Write(benchmark::State& state) { static void Unaligned_Interleaved_Write(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0)); sfz::Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0)); sfz::Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2); sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f); std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f); std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
writeInterleaved<float, false>(absl::MakeSpan(inputLeft).subspan(1) , absl::MakeSpan(inputRight).subspan(1), absl::MakeSpan(output).subspan(2)); sfz::writeInterleaved<float, false>(absl::MakeSpan(inputLeft).subspan(1) , absl::MakeSpan(inputRight).subspan(1), absl::MakeSpan(output).subspan(2));
benchmark::DoNotOptimize(output); benchmark::DoNotOptimize(output);
} }
} }
static void Unaligned_Interleaved_Write_SSE(benchmark::State& state) { static void Unaligned_Interleaved_Write_SSE(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0)); sfz::Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0)); sfz::Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2); sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f); std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f); std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
writeInterleaved<float, true>(absl::MakeSpan(inputLeft).subspan(1) , absl::MakeSpan(inputRight).subspan(1), absl::MakeSpan(output).subspan(2)); sfz::writeInterleaved<float, true>(absl::MakeSpan(inputLeft).subspan(1) , absl::MakeSpan(inputRight).subspan(1), absl::MakeSpan(output).subspan(2));
benchmark::DoNotOptimize(output); benchmark::DoNotOptimize(output);
} }
} }
static void Unaligned_Interleaved_Write_2(benchmark::State& state) { static void Unaligned_Interleaved_Write_2(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0)); sfz::Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0)); sfz::Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2); sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f); std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f); std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
writeInterleaved<float, false>(absl::MakeSpan(inputLeft) , absl::MakeSpan(inputRight).subspan(1), absl::MakeSpan(output).subspan(2)); sfz::writeInterleaved<float, false>(absl::MakeSpan(inputLeft) , absl::MakeSpan(inputRight).subspan(1), absl::MakeSpan(output).subspan(2));
benchmark::DoNotOptimize(output); benchmark::DoNotOptimize(output);
} }
} }
static void Unaligned_Interleaved_Write_SSE_2(benchmark::State& state) { static void Unaligned_Interleaved_Write_SSE_2(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0)); sfz::Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0)); sfz::Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2); sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f); std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f); std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) { for (auto _ : state) {
writeInterleaved<float, true>(absl::MakeSpan(inputLeft) , absl::MakeSpan(inputRight).subspan(1), absl::MakeSpan(output).subspan(2)); sfz::writeInterleaved<float, true>(absl::MakeSpan(inputLeft) , absl::MakeSpan(inputRight).subspan(1), absl::MakeSpan(output).subspan(2));
benchmark::DoNotOptimize(output); benchmark::DoNotOptimize(output);
} }
} }

View file

@ -119,7 +119,7 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
switch (currentState) { switch (currentState) {
case State::Delay: case State::Delay:
length = min(remainingSamples, delay); length = min(remainingSamples, delay);
::fill<Type>(output, currentValue); fill<Type>(output, currentValue);
output.remove_prefix(length); output.remove_prefix(length);
remainingSamples -= length; remainingSamples -= length;
delay -= length; delay -= length;
@ -131,7 +131,7 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
[[fallthrough]]; [[fallthrough]];
case State::Attack: case State::Attack:
length = min(remainingSamples, attack); length = min(remainingSamples, attack);
currentValue = ::linearRamp<Type>(output, currentValue, step); currentValue = linearRamp<Type>(output, currentValue, step);
output.remove_prefix(length); output.remove_prefix(length);
remainingSamples -= length; remainingSamples -= length;
attack -= length; attack -= length;
@ -143,7 +143,7 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
[[fallthrough]]; [[fallthrough]];
case State::Hold: case State::Hold:
length = min(remainingSamples, hold); length = min(remainingSamples, hold);
::fill<Type>(output, currentValue); fill<Type>(output, currentValue);
output.remove_prefix(length); output.remove_prefix(length);
remainingSamples -= length; remainingSamples -= length;
hold -= length; hold -= length;
@ -155,7 +155,7 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
[[fallthrough]]; [[fallthrough]];
case State::Decay: case State::Decay:
length = min(remainingSamples, decay); length = min(remainingSamples, decay);
currentValue = ::multiplicativeRamp<Type>(output, currentValue, step); currentValue = multiplicativeRamp<Type>(output, currentValue, step);
output.remove_prefix(length); output.remove_prefix(length);
remainingSamples -= length; remainingSamples -= length;
decay -= length; decay -= length;
@ -169,7 +169,7 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
break; break;
case State::Release: case State::Release:
length = min(remainingSamples, release); length = min(remainingSamples, release);
currentValue = ::multiplicativeRamp<Type>(output, currentValue, step); currentValue = multiplicativeRamp<Type>(output, currentValue, step);
output.remove_prefix(length); output.remove_prefix(length);
remainingSamples -= length; remainingSamples -= length;
release -= length; release -= length;
@ -184,7 +184,7 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
default: default:
break; break;
} }
::fill<Type>(output, currentValue); fill<Type>(output, currentValue);
if (shouldRelease) { if (shouldRelease) {
remainingSamples = static_cast<int>(originalSpan.size()); remainingSamples = static_cast<int>(originalSpan.size());
@ -200,14 +200,14 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
remainingSamples -= releaseDelay; remainingSamples -= releaseDelay;
length = min(remainingSamples, release); length = min(remainingSamples, release);
currentState = State::Release; currentState = State::Release;
currentValue = ::multiplicativeRamp<Type>(originalSpan, currentValue, step); currentValue = multiplicativeRamp<Type>(originalSpan, currentValue, step);
originalSpan.remove_prefix(length); originalSpan.remove_prefix(length);
release -= length; release -= length;
if (release == 0) { if (release == 0) {
currentValue = 0.0; currentValue = 0.0;
currentState = State::Done; currentState = State::Done;
::fill<Type>(originalSpan, 0.0); fill<Type>(originalSpan, 0.0);
} }
} }
} }

View file

@ -30,6 +30,9 @@
#include <memory> #include <memory>
#include <array> #include <array>
namespace sfz
{
template <class Type, unsigned int MaxChannels = sfz::config::numChannels, unsigned int Alignment = SIMDConfig::defaultAlignment> template <class Type, unsigned int MaxChannels = sfz::config::numChannels, unsigned int Alignment = SIMDConfig::defaultAlignment>
class AudioBuffer { class AudioBuffer {
public: public:
@ -151,3 +154,4 @@ private:
int numChannels { 0 }; int numChannels { 0 };
size_type numFrames { 0 }; size_type numFrames { 0 };
}; };
}

View file

@ -32,6 +32,8 @@
#include <initializer_list> #include <initializer_list>
#include <type_traits> #include <type_traits>
namespace sfz
{
template <class Type, unsigned int MaxChannels = sfz::config::numChannels> template <class Type, unsigned int MaxChannels = sfz::config::numChannels>
class AudioSpan { class AudioSpan {
public: public:
@ -137,26 +139,26 @@ public:
return 0.0; return 0.0;
Type result = 0.0; Type result = 0.0;
for (int i = 0; i < numChannels; ++i) for (int i = 0; i < numChannels; ++i)
result += ::meanSquared<Type>(getConstSpan(i)); result += sfz::meanSquared<Type>(getConstSpan(i));
return result / numChannels; return result / numChannels;
} }
void fill(Type value) noexcept void fill(Type value) noexcept
{ {
for (int i = 0; i < numChannels; ++i) for (int i = 0; i < numChannels; ++i)
::fill<Type>(getSpan(i), value); sfz::fill<Type>(getSpan(i), value);
} }
void applyGain(absl::Span<const Type> gain) noexcept void applyGain(absl::Span<const Type> gain) noexcept
{ {
for (int i = 0; i < numChannels; ++i) for (int i = 0; i < numChannels; ++i)
::applyGain<Type>(gain, getSpan(i)); sfz::applyGain<Type>(gain, getSpan(i));
} }
void applyGain(Type gain) noexcept void applyGain(Type gain) noexcept
{ {
for (int i = 0; i < numChannels; ++i) for (int i = 0; i < numChannels; ++i)
::applyGain<Type>(gain, getSpan(i)); sfz::applyGain<Type>(gain, getSpan(i));
} }
template <class U, unsigned int N, typename = std::enable_if<N <= MaxChannels>> template <class U, unsigned int N, typename = std::enable_if<N <= MaxChannels>>
@ -165,7 +167,7 @@ public:
ASSERT(other.getNumChannels() == numChannels); ASSERT(other.getNumChannels() == numChannels);
if (other.getNumChannels() == numChannels) { if (other.getNumChannels() == numChannels) {
for (int i = 0; i < numChannels; ++i) for (int i = 0; i < numChannels; ++i)
::add<Type>(other.getConstSpan(i), getSpan(i)); sfz::add<Type>(other.getConstSpan(i), getSpan(i));
} }
} }
@ -175,7 +177,7 @@ public:
ASSERT(other.getNumChannels() == numChannels); ASSERT(other.getNumChannels() == numChannels);
if (other.getNumChannels() == numChannels) { if (other.getNumChannels() == numChannels) {
for (int i = 0; i < numChannels; ++i) for (int i = 0; i < numChannels; ++i)
::copy<Type>(other.getConstSpan(i), getSpan(i)); sfz::copy<Type>(other.getConstSpan(i), getSpan(i));
} }
} }
@ -218,3 +220,4 @@ private:
size_type numFrames { 0 }; size_type numFrames { 0 };
int numChannels { 0 }; int numChannels { 0 };
}; };
}

View file

@ -29,6 +29,9 @@
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
namespace sfz
{
template <class Type, unsigned int Alignment = SIMDConfig::defaultAlignment> template <class Type, unsigned int Alignment = SIMDConfig::defaultAlignment>
class Buffer { class Buffer {
public: public:
@ -157,3 +160,4 @@ private:
pointer _alignedEnd { nullptr }; pointer _alignedEnd { nullptr };
LEAK_DETECTOR(Buffer); LEAK_DETECTOR(Buffer);
}; };
}

View file

@ -43,7 +43,6 @@ namespace config {
constexpr float voiceStealingThreshold { 0.00001 }; constexpr float voiceStealingThreshold { 0.00001 };
} // namespace config } // namespace config
} // namespace sfz
namespace SIMDConfig { namespace SIMDConfig {
constexpr unsigned int defaultAlignment { 16 }; constexpr unsigned int defaultAlignment { 16 };
@ -67,3 +66,4 @@ namespace SIMDConfig {
constexpr bool mean { false }; constexpr bool mean { false };
constexpr bool meanSquared { false }; constexpr bool meanSquared { false };
} }
} // namespace sfz

View file

@ -35,15 +35,15 @@
using namespace std::chrono_literals; using namespace std::chrono_literals;
template <class T> template <class T>
std::unique_ptr<AudioBuffer<T>> readFromFile(SndfileHandle& sndFile, int numFrames) std::unique_ptr<sfz::AudioBuffer<T>> readFromFile(SndfileHandle& sndFile, int numFrames)
{ {
auto returnedBuffer = std::make_unique<AudioBuffer<T>>(sndFile.channels(), numFrames); auto returnedBuffer = std::make_unique<sfz::AudioBuffer<T>>(sndFile.channels(), numFrames);
if (sndFile.channels() == 1) { if (sndFile.channels() == 1) {
sndFile.readf(returnedBuffer->channelWriter(0), numFrames); sndFile.readf(returnedBuffer->channelWriter(0), numFrames);
} else if (sndFile.channels() == 2) { } else if (sndFile.channels() == 2) {
auto tempReadBuffer = std::make_unique<AudioBuffer<float>>(1, 2 * numFrames); auto tempReadBuffer = std::make_unique<sfz::AudioBuffer<float>>(1, 2 * numFrames);
sndFile.readf(tempReadBuffer->channelWriter(0), numFrames); sndFile.readf(tempReadBuffer->channelWriter(0), numFrames);
::readInterleaved<float>(tempReadBuffer->getSpan(0), returnedBuffer->getSpan(0), returnedBuffer->getSpan(1)); sfz::readInterleaved<float>(tempReadBuffer->getSpan(0), returnedBuffer->getSpan(0), returnedBuffer->getSpan(1));
} }
return returnedBuffer; return returnedBuffer;
} }
@ -90,7 +90,7 @@ absl::optional<sfz::FilePool::FileInformation> sfz::FilePool::getFileInformation
// By resetting the filepool data to a new, longer audiobuffer, we are creating 2 copies of the same audio data. // By resetting the filepool data to a new, longer audiobuffer, we are creating 2 copies of the same audio data.
// The filepool and the new regions have the longer copy, and the older regions have the shorter copy. // The filepool and the new regions have the longer copy, and the older regions have the shorter copy.
// This is not entirely optimal, but is it better to write a double shared pointer ? // This is not entirely optimal, but is it better to write a double shared pointer ?
// std::shared_ptr<std::shared_ptr<AudioBuffer>>> is a bit ugly... // std::shared_ptr<std::shared_ptr<sfz::AudioBuffer>>> is a bit ugly...
alreadyPreloaded.reset(readFromFile<float>(sndFile, preloadedSize).release()); alreadyPreloaded.reset(readFromFile<float>(sndFile, preloadedSize).release());
} }
returnedValue.preloadedData = alreadyPreloaded; returnedValue.preloadedData = alreadyPreloaded;

View file

@ -2,6 +2,8 @@
#include "SIMDHelpers.h" #include "SIMDHelpers.h"
#include "absl/types/span.h" #include "absl/types/span.h"
namespace sfz
{
template<class ValueType> template<class ValueType>
class HistoricalBuffer { class HistoricalBuffer {
public: public:
@ -15,7 +17,7 @@ public:
void resize(int size) void resize(int size)
{ {
buffer.resize(size); buffer.resize(size);
::fill<ValueType>(absl::MakeSpan(buffer), 0.0); fill<ValueType>(absl::MakeSpan(buffer), 0.0);
index = 0; index = 0;
} }
@ -30,10 +32,11 @@ public:
ValueType getAverage() const ValueType getAverage() const
{ {
return ::mean<ValueType>(buffer); return mean<ValueType>(buffer);
} }
private: private:
std::vector<ValueType> buffer; std::vector<ValueType> buffer;
size_t size { 0 }; size_t size { 0 };
size_t index { 0 }; size_t index { 0 };
}; };
}

View file

@ -90,12 +90,12 @@ void LinearEnvelope<Type>::getBlock(absl::Span<Type> output)
} }
const auto step = (event.second - currentValue) / length; const auto step = (event.second - currentValue) / length;
currentValue = ::linearRamp<Type>(output.subspan(index, length), currentValue, step); currentValue = linearRamp<Type>(output.subspan(index, length), currentValue, step);
index += length; index += length;
} }
if (index < static_cast<int>(output.size())) if (index < static_cast<int>(output.size()))
::fill<Type>(output.subspan(index), currentValue); fill<Type>(output.subspan(index), currentValue);
clear(); clear();
} }

View file

@ -27,6 +27,8 @@
#include <absl/types/span.h> #include <absl/types/span.h>
#include <cmath> #include <cmath>
namespace sfz
{
template <class Type = float> template <class Type = float>
class OnePoleFilter { class OnePoleFilter {
public: public:
@ -135,3 +137,4 @@ private:
state += 2 * intermediate; state += 2 * intermediate;
} }
}; };
}

View file

@ -24,153 +24,153 @@
#include "SIMDHelpers.h" #include "SIMDHelpers.h"
template <> template <>
void readInterleaved<float, true>(absl::Span<const float> input, absl::Span<float> outputLeft, absl::Span<float> outputRight) noexcept void sfz::readInterleaved<float, true>(absl::Span<const float> input, absl::Span<float> outputLeft, absl::Span<float> outputRight) noexcept
{ {
readInterleaved<float, false>(input, outputLeft, outputRight); readInterleaved<float, false>(input, outputLeft, outputRight);
} }
template <> template <>
void writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span<const float> inputRight, absl::Span<float> output) noexcept void sfz::writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span<const float> inputRight, absl::Span<float> output) noexcept
{ {
writeInterleaved<float, false>(inputLeft, inputRight, output); writeInterleaved<float, false>(inputLeft, inputRight, output);
} }
template <> template <>
void fill<float, true>(absl::Span<float> output, float value) noexcept void sfz::fill<float, true>(absl::Span<float> output, float value) noexcept
{ {
fill<float, false>(output, value); fill<float, false>(output, value);
} }
template <> template <>
void exp<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::exp<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
exp<float, false>(input, output); exp<float, false>(input, output);
} }
template <> template <>
void log<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::log<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
log<float, false>(input, output); log<float, false>(input, output);
} }
template <> template <>
void sin<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::sin<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
sin<float, false>(input, output); sin<float, false>(input, output);
} }
template <> template <>
void cos<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::cos<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
cos<float, false>(input, output); cos<float, false>(input, output);
} }
template <> template <>
void applyGain<float, true>(float gain, absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::applyGain<float, true>(float gain, absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
applyGain<float, false>(gain, input, output); applyGain<float, false>(gain, input, output);
} }
template <> template <>
void applyGain<float, true>(absl::Span<const float> gain, absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::applyGain<float, true>(absl::Span<const float> gain, absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
applyGain<float, false>(gain, input, output); applyGain<float, false>(gain, input, output);
} }
template <> template <>
void multiplyAdd<float, true>(absl::Span<const float> gain, absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::multiplyAdd<float, true>(absl::Span<const float> gain, absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
multiplyAdd<float, false>(gain, input, output); multiplyAdd<float, false>(gain, input, output);
} }
template <> template <>
float loopingSFZIndex<float, true>(absl::Span<const float> jumps, absl::Span<float> leftCoeff, absl::Span<float> rightCoeff, absl::Span<int> indices, float floatIndex, float loopEnd, float loopStart) noexcept float sfz::loopingSFZIndex<float, true>(absl::Span<const float> jumps, absl::Span<float> leftCoeff, absl::Span<float> rightCoeff, absl::Span<int> indices, float floatIndex, float loopEnd, float loopStart) noexcept
{ {
return loopingSFZIndex<float, false>(jumps, leftCoeff, rightCoeff, indices, floatIndex, loopEnd, loopStart); return loopingSFZIndex<float, false>(jumps, leftCoeff, rightCoeff, indices, floatIndex, loopEnd, loopStart);
} }
template <> template <>
float saturatingSFZIndex<float, true>(absl::Span<const float> jumps, absl::Span<float> leftCoeff, absl::Span<float> rightCoeff, absl::Span<int> indices, float floatIndex, float loopEnd) noexcept float sfz::saturatingSFZIndex<float, true>(absl::Span<const float> jumps, absl::Span<float> leftCoeff, absl::Span<float> rightCoeff, absl::Span<int> indices, float floatIndex, float loopEnd) noexcept
{ {
return saturatingSFZIndex<float, false>(jumps, leftCoeff, rightCoeff, indices, floatIndex, loopEnd); return saturatingSFZIndex<float, false>(jumps, leftCoeff, rightCoeff, indices, floatIndex, loopEnd);
} }
template <> template <>
float linearRamp<float, true>(absl::Span<float> output, float start, float step) noexcept float sfz::linearRamp<float, true>(absl::Span<float> output, float start, float step) noexcept
{ {
return linearRamp<float, false>(output, start, step); return linearRamp<float, false>(output, start, step);
} }
template <> template <>
float multiplicativeRamp<float, true>(absl::Span<float> output, float start, float step) noexcept float sfz::multiplicativeRamp<float, true>(absl::Span<float> output, float start, float step) noexcept
{ {
return multiplicativeRamp<float, false>(output, start, step); return multiplicativeRamp<float, false>(output, start, step);
} }
template <> template <>
void add<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::add<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
add<float, false>(input, output); add<float, false>(input, output);
} }
template <> template <>
void add<float, true>(float value, absl::Span<float> output) noexcept void sfz::add<float, true>(float value, absl::Span<float> output) noexcept
{ {
add<float, false>(value, output); add<float, false>(value, output);
} }
template <> template <>
void subtract<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::subtract<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
subtract<float, false>(input, output); subtract<float, false>(input, output);
} }
template <> template <>
void subtract<float, true>(const float value, absl::Span<float> output) noexcept void sfz::subtract<float, true>(const float value, absl::Span<float> output) noexcept
{ {
subtract<float, false>(value, output); subtract<float, false>(value, output);
} }
template <> template <>
void copy<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::copy<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
copy<float, false>(input, output); copy<float, false>(input, output);
} }
template <> template <>
void pan<float, true>(absl::Span<const float> panEnvelope, absl::Span<float> leftBuffer, absl::Span<float> rightBuffer) noexcept void sfz::pan<float, true>(absl::Span<const float> panEnvelope, absl::Span<float> leftBuffer, absl::Span<float> rightBuffer) noexcept
{ {
pan<float, false>(panEnvelope, leftBuffer, rightBuffer); pan<float, false>(panEnvelope, leftBuffer, rightBuffer);
} }
template <> template <>
float mean<float, true>(absl::Span<const float> vector) noexcept float sfz::mean<float, true>(absl::Span<const float> vector) noexcept
{ {
return mean<float, false>(vector); return mean<float, false>(vector);
} }
template <> template <>
float meanSquared<float, true>(absl::Span<const float> vector) noexcept float sfz::meanSquared<float, true>(absl::Span<const float> vector) noexcept
{ {
return meanSquared<float, false>(vector); return meanSquared<float, false>(vector);
} }
template <> template <>
void cumsum<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::cumsum<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
cumsum<float, false>(input, output); cumsum<float, false>(input, output);
} }
template<> template<>
void sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> leftCoeffs, absl::Span<float> rightCoeffs) noexcept void sfz::sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> leftCoeffs, absl::Span<float> rightCoeffs) noexcept
{ {
sfzInterpolationCast<float, false>(floatJumps, jumps, leftCoeffs, rightCoeffs); sfzInterpolationCast<float, false>(floatJumps, jumps, leftCoeffs, rightCoeffs);
} }
template <> template <>
void diff<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::diff<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
diff<float, false>(input, output); diff<float, false>(input, output);
} }

View file

@ -29,6 +29,8 @@
#include <absl/types/span.h> #include <absl/types/span.h>
#include <cmath> #include <cmath>
namespace sfz
{
template <class T> template <class T>
inline void snippetRead(const T*& input, T*& outputLeft, T*& outputRight) inline void snippetRead(const T*& input, T*& outputLeft, T*& outputRight)
{ {
@ -570,3 +572,5 @@ void diff(absl::Span<const T> input, absl::Span<T> output) noexcept
template <> template <>
void cumsum<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept; void cumsum<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept;
} // namespace sfz

View file

@ -76,7 +76,7 @@ bool unaligned(const float* ptr1, const float* ptr2, const float* ptr3, const fl
} }
template <> template <>
void readInterleaved<float, true>(absl::Span<const float> input, absl::Span<float> outputLeft, absl::Span<float> outputRight) noexcept void sfz::readInterleaved<float, true>(absl::Span<const float> input, absl::Span<float> outputLeft, absl::Span<float> outputRight) noexcept
{ {
// The size of the outputs is not big enough for the input... // The size of the outputs is not big enough for the input...
ASSERT(outputLeft.size() >= input.size() / 2); ASSERT(outputLeft.size() >= input.size() / 2);
@ -116,7 +116,7 @@ void readInterleaved<float, true>(absl::Span<const float> input, absl::Span<floa
} }
template <> template <>
void writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span<const float> inputRight, absl::Span<float> output) noexcept void sfz::writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span<const float> inputRight, absl::Span<float> output) noexcept
{ {
// The size of the output is not big enough for the inputs... // The size of the output is not big enough for the inputs...
ASSERT(inputLeft.size() <= output.size() / 2); ASSERT(inputLeft.size() <= output.size() / 2);
@ -153,7 +153,7 @@ void writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span
} }
template <> template <>
void fill<float, true>(absl::Span<float> output, float value) noexcept void sfz::fill<float, true>(absl::Span<float> output, float value) noexcept
{ {
const auto mmValue = _mm_set_ps1(value); const auto mmValue = _mm_set_ps1(value);
auto* out = output.begin(); auto* out = output.begin();
@ -173,7 +173,7 @@ void fill<float, true>(absl::Span<float> output, float value) noexcept
} }
template <> template <>
void exp<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::exp<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
ASSERT(output.size() >= input.size()); ASSERT(output.size() >= input.size());
auto* in = input.begin(); auto* in = input.begin();
@ -195,7 +195,7 @@ void exp<float, true>(absl::Span<const float> input, absl::Span<float> output) n
} }
template <> template <>
void cos<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::cos<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
ASSERT(output.size() >= input.size()); ASSERT(output.size() >= input.size());
auto* in = input.begin(); auto* in = input.begin();
@ -217,7 +217,7 @@ void cos<float, true>(absl::Span<const float> input, absl::Span<float> output) n
} }
template <> template <>
void log<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::log<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
ASSERT(output.size() >= input.size()); ASSERT(output.size() >= input.size());
auto* in = input.begin(); auto* in = input.begin();
@ -239,7 +239,7 @@ void log<float, true>(absl::Span<const float> input, absl::Span<float> output) n
} }
template <> template <>
void sin<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::sin<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
ASSERT(output.size() >= input.size()); ASSERT(output.size() >= input.size());
auto* in = input.begin(); auto* in = input.begin();
@ -261,7 +261,7 @@ void sin<float, true>(absl::Span<const float> input, absl::Span<float> output) n
} }
template <> template <>
void applyGain<float, true>(float gain, absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::applyGain<float, true>(float gain, absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
auto* in = input.begin(); auto* in = input.begin();
auto* out = output.begin(); auto* out = output.begin();
@ -283,7 +283,7 @@ void applyGain<float, true>(float gain, absl::Span<const float> input, absl::Spa
} }
template <> template <>
void applyGain<float, true>(absl::Span<const float> gain, absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::applyGain<float, true>(absl::Span<const float> gain, absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
auto* in = input.begin(); auto* in = input.begin();
auto* out = output.begin(); auto* out = output.begin();
@ -306,7 +306,7 @@ void applyGain<float, true>(absl::Span<const float> gain, absl::Span<const float
} }
template <> template <>
void multiplyAdd<float, true>(absl::Span<const float> gain, absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::multiplyAdd<float, true>(absl::Span<const float> gain, absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
auto* in = input.begin(); auto* in = input.begin();
auto* out = output.begin(); auto* out = output.begin();
@ -331,7 +331,7 @@ void multiplyAdd<float, true>(absl::Span<const float> gain, absl::Span<const flo
} }
template <> template <>
float loopingSFZIndex<float, true>(absl::Span<const float> jumps, float sfz::loopingSFZIndex<float, true>(absl::Span<const float> jumps,
absl::Span<float> leftCoeffs, absl::Span<float> leftCoeffs,
absl::Span<float> rightCoeffs, absl::Span<float> rightCoeffs,
absl::Span<int> indices, absl::Span<int> indices,
@ -393,7 +393,7 @@ float loopingSFZIndex<float, true>(absl::Span<const float> jumps,
} }
template <> template <>
float saturatingSFZIndex<float, true>(absl::Span<const float> jumps, float sfz::saturatingSFZIndex<float, true>(absl::Span<const float> jumps,
absl::Span<float> leftCoeffs, absl::Span<float> leftCoeffs,
absl::Span<float> rightCoeffs, absl::Span<float> rightCoeffs,
absl::Span<int> indices, absl::Span<int> indices,
@ -451,7 +451,7 @@ float saturatingSFZIndex<float, true>(absl::Span<const float> jumps,
} }
template <> template <>
float linearRamp<float, true>(absl::Span<float> output, float value, float step) noexcept float sfz::linearRamp<float, true>(absl::Span<float> output, float value, float step) noexcept
{ {
auto* out = output.begin(); auto* out = output.begin();
const auto* lastAligned = prevAligned(output.end()); const auto* lastAligned = prevAligned(output.end());
@ -476,7 +476,7 @@ float linearRamp<float, true>(absl::Span<float> output, float value, float step)
} }
template <> template <>
float multiplicativeRamp<float, true>(absl::Span<float> output, float value, float step) noexcept float sfz::multiplicativeRamp<float, true>(absl::Span<float> output, float value, float step) noexcept
{ {
auto* out = output.begin(); auto* out = output.begin();
const auto* lastAligned = prevAligned(output.end()); const auto* lastAligned = prevAligned(output.end());
@ -501,7 +501,7 @@ float multiplicativeRamp<float, true>(absl::Span<float> output, float value, flo
} }
template <> template <>
void add<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::add<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
ASSERT(output.size() >= input.size()); ASSERT(output.size() >= input.size());
auto* in = input.begin(); auto* in = input.begin();
@ -523,7 +523,7 @@ void add<float, true>(absl::Span<const float> input, absl::Span<float> output) n
} }
template <> template <>
void add<float, true>(float value, absl::Span<float> output) noexcept void sfz::add<float, true>(float value, absl::Span<float> output) noexcept
{ {
auto* out = output.begin(); auto* out = output.begin();
auto* sentinel = output.end(); auto* sentinel = output.end();
@ -543,7 +543,7 @@ void add<float, true>(float value, absl::Span<float> output) noexcept
} }
template <> template <>
void subtract<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::subtract<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
ASSERT(output.size() >= input.size()); ASSERT(output.size() >= input.size());
auto* in = input.begin(); auto* in = input.begin();
@ -565,7 +565,7 @@ void subtract<float, true>(absl::Span<const float> input, absl::Span<float> outp
} }
template <> template <>
void subtract<float, true>(const float value, absl::Span<float> output) noexcept void sfz::subtract<float, true>(const float value, absl::Span<float> output) noexcept
{ {
auto* out = output.begin(); auto* out = output.begin();
auto* sentinel = output.end(); auto* sentinel = output.end();
@ -585,7 +585,7 @@ void subtract<float, true>(const float value, absl::Span<float> output) noexcept
} }
template <> template <>
void copy<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::copy<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
ASSERT(output.size() >= input.size()); ASSERT(output.size() >= input.size());
auto* in = input.begin(); auto* in = input.begin();
@ -607,7 +607,7 @@ void copy<float, true>(absl::Span<const float> input, absl::Span<float> output)
} }
template <> template <>
void pan<float, true>(absl::Span<const float> panEnvelope, absl::Span<float> leftBuffer, absl::Span<float> rightBuffer) noexcept void sfz::pan<float, true>(absl::Span<const float> panEnvelope, absl::Span<float> leftBuffer, absl::Span<float> rightBuffer) noexcept
{ {
ASSERT(leftBuffer.size() >= panEnvelope.size()); ASSERT(leftBuffer.size() >= panEnvelope.size());
ASSERT(rightBuffer.size() >= panEnvelope.size()); ASSERT(rightBuffer.size() >= panEnvelope.size());
@ -643,7 +643,7 @@ void pan<float, true>(absl::Span<const float> panEnvelope, absl::Span<float> lef
} }
template <> template <>
float mean<float, true>(absl::Span<const float> vector) noexcept float sfz::mean<float, true>(absl::Span<const float> vector) noexcept
{ {
float result { 0.0 }; float result { 0.0 };
if (vector.size() == 0) if (vector.size() == 0)
@ -675,7 +675,7 @@ float mean<float, true>(absl::Span<const float> vector) noexcept
} }
template <> template <>
float meanSquared<float, true>(absl::Span<const float> vector) noexcept float sfz::meanSquared<float, true>(absl::Span<const float> vector) noexcept
{ {
float result { 0.0 }; float result { 0.0 };
if (vector.size() == 0) if (vector.size() == 0)
@ -712,7 +712,7 @@ float meanSquared<float, true>(absl::Span<const float> vector) noexcept
} }
template <> template <>
void cumsum<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::cumsum<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
ASSERT(output.size() >= input.size()); ASSERT(output.size() >= input.size());
if (input.size() == 0) if (input.size() == 0)
@ -744,7 +744,7 @@ void cumsum<float, true>(absl::Span<const float> input, absl::Span<float> output
} }
template <> template <>
void sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> leftCoeffs, absl::Span<float> rightCoeffs) noexcept void sfz::sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl::Span<int> jumps, absl::Span<float> leftCoeffs, absl::Span<float> rightCoeffs) noexcept
{ {
ASSERT(jumps.size() >= floatJumps.size()); ASSERT(jumps.size() >= floatJumps.size());
ASSERT(jumps.size() == leftCoeffs.size()); ASSERT(jumps.size() == leftCoeffs.size());
@ -780,7 +780,7 @@ void sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl:
} }
template <> template <>
void diff<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept void sfz::diff<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{ {
ASSERT(output.size() >= input.size()); ASSERT(output.size() >= input.size());
if (input.size() == 0) if (input.size() == 0)

View file

@ -1,186 +0,0 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "Buffer.h"
#include "Config.h"
#include "Debug.h"
#include "LeakDetector.h"
#include "SIMDHelpers.h"
#include <array>
#include <iostream>
#include <type_traits>
enum class Channel { left, right };
template <class Type, unsigned int Alignment = SIMDConfig::defaultAlignment>
class StereoBuffer {
public:
static constexpr int numChannels { 2 };
StereoBuffer() = default;
StereoBuffer(int numFrames)
{
resize(numFrames);
}
bool resize(int numFrames)
{
// should have a positive number of frames...
ASSERT(numFrames >= 0);
if (leftBuffer.resize(static_cast<size_t>(numFrames)) && rightBuffer.resize(static_cast<size_t>(numFrames))) {
this->numFrames = numFrames;
return true;
}
return false;
}
absl::Span<const Type> getConstSpan(Channel channel) const
{
switch (channel) {
case Channel::left:
return leftBuffer;
case Channel::right:
return rightBuffer;
}
}
absl::Span<Type> getSpan(Channel channel)
{
switch (channel) {
default:
[[fallthrough]];
case Channel::left:
return absl::MakeSpan(leftBuffer);
case Channel::right:
return absl::MakeSpan(rightBuffer);
}
}
Type& getSample(Channel channel, int sampleIndex) noexcept
{
ASSERT(sampleIndex >= 0);
switch (channel) {
default:
[[fallthrough]];
case Channel::left:
return leftBuffer[sampleIndex];
case Channel::right:
return rightBuffer[sampleIndex];
}
}
void fill(Type value) noexcept
{
::fill<Type>(absl::MakeSpan(leftBuffer), value);
::fill<Type>(absl::MakeSpan(rightBuffer), value);
}
void readInterleaved(absl::Span<const Type> input) noexcept
{
ASSERT(input.size() <= static_cast<size_t>(numChannels * numFrames));
::readInterleaved<Type>(input, absl::MakeSpan(leftBuffer), absl::MakeSpan(rightBuffer));
}
void writeInterleaved(absl::Span<Type> output) noexcept
{
ASSERT(output.size() >= static_cast<size_t>(numChannels * numFrames));
::writeInterleaved<Type>(leftBuffer, rightBuffer, output);
}
void add(const StereoBuffer<Type>& buffer)
{
::add<Type>(buffer.getSpan(Channel::left), absl::MakeSpan(leftBuffer));
::add<Type>(buffer.getSpan(Channel::right), absl::MakeSpan(rightBuffer));
}
Type* getChannel(Channel channel) noexcept
{
switch (channel) {
case Channel::left:
return leftBuffer.data();
case Channel::right:
return rightBuffer.data();
default:
return {};
}
}
Type* begin(Channel channel) noexcept
{
switch (channel) {
case Channel::left:
return leftBuffer.data();
case Channel::right:
return rightBuffer.data();
default:
return {};
}
}
std::pair<Type*, Type*> getChannels() noexcept { return { leftBuffer.data(), rightBuffer.data() }; }
std::pair<Type*, Type*> begins() noexcept { return { leftBuffer.data(), rightBuffer.data() }; }
Type* end(Channel channel) noexcept
{
switch (channel) {
case Channel::left:
return leftBuffer.end();
case Channel::right:
return rightBuffer.end();
default:
return {};
}
}
std::pair<Type*, Type*> ends() { return { leftBuffer.end(), rightBuffer.end() }; }
Type* alignedEnd(Channel channel) noexcept
{
switch (channel) {
case Channel::left:
return leftBuffer.alignedEnd();
case Channel::right:
return rightBuffer.alignedEnd();
default:
return {};
}
}
std::pair<Type*, Type*> alignedEnds() { return { leftBuffer.alignedEnd(), rightBuffer.alignedEnd() }; }
Type& operator()(Channel channel, int sampleIndex) noexcept
{
return getSample(channel, sampleIndex);
}
int getNumFrames() const noexcept { return numFrames; }
int getNumChannels() const noexcept { return numChannels; }
bool empty() const noexcept { return numFrames == 0; }
private:
static constexpr auto TypeAlignment { Alignment / sizeof(Type) };
static constexpr auto TypeAlignmentMask { TypeAlignment - 1 };
static_assert(TypeAlignment * sizeof(Type) == Alignment, "The alignment does not appear to be divided by the size of the Type");
int numFrames { 0 };
Buffer<Type, Alignment> leftBuffer {};
Buffer<Type, Alignment> rightBuffer {};
LEAK_DETECTOR(StereoBuffer);
};

View file

@ -1,189 +0,0 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "LeakDetector.h"
#include "SIMDHelpers.h"
#include "StereoBuffer.h"
#include <absl/types/span.h>
#include <type_traits>
template <class Type>
class StereoSpan {
public:
using ValueType = std::remove_cv_t<Type>;
template <typename U>
StereoSpan() = delete;
StereoSpan(Type* leftBuffer, Type* rightBuffer, size_t numFrames)
: numFrames(numFrames)
, leftBuffer(leftBuffer, numFrames)
, rightBuffer(rightBuffer, numFrames)
{
}
StereoSpan(void* leftBuffer, void* rightBuffer, size_t numFrames)
: numFrames(numFrames)
, leftBuffer(static_cast<Type*>(leftBuffer), numFrames)
, rightBuffer(static_cast<Type*>(rightBuffer), numFrames)
{
}
StereoSpan(absl::Span<Type> leftBuffer, absl::Span<Type> rightBuffer)
: numFrames(std::min(leftBuffer.size(), rightBuffer.size()))
, leftBuffer(leftBuffer.first(numFrames))
, rightBuffer(rightBuffer.first(numFrames))
{
// Buffer really should be the same size here
ASSERT(leftBuffer.size() == rightBuffer.size());
}
StereoSpan(StereoBuffer<ValueType>&& buffer)
: numFrames(buffer.getNumFrames())
, leftBuffer(buffer.getSpan(Channel::left))
, rightBuffer(buffer.getSpan(Channel::right))
{
}
StereoSpan(StereoBuffer<const ValueType>&& buffer)
: leftBuffer(buffer.getConstSpan(Channel::left))
, rightBuffer(buffer.getConstSpan(Channel::right))
, numFrames(buffer.getNumFrames())
{
}
StereoSpan(StereoBuffer<ValueType>& buffer)
: numFrames(buffer.getNumFrames())
, leftBuffer(buffer.getSpan(Channel::left))
, rightBuffer(buffer.getSpan(Channel::right))
{
}
StereoSpan(StereoBuffer<const ValueType>& buffer)
: leftBuffer(buffer.getConstSpan(Channel::left))
, rightBuffer(buffer.getConstSpan(Channel::right))
, numFrames(buffer.getNumFrames())
{
}
StereoSpan(StereoBuffer<ValueType>& buffer, size_t numFrames)
: numFrames(numFrames)
, leftBuffer(buffer.getSpan(Channel::left).first(numFrames))
, rightBuffer(buffer.getSpan(Channel::right).first(numFrames))
{
}
StereoSpan(const StereoBuffer<const ValueType>& buffer, size_t numFrames)
: numFrames(numFrames)
, leftBuffer(buffer.getConstSpan(Channel::left).first(numFrames))
, rightBuffer(buffer.getConstSpan(Channel::right).first(numFrames))
{
}
StereoSpan(const StereoSpan<ValueType>& span)
: numFrames(span.size())
, leftBuffer(span.left())
, rightBuffer(span.right())
{
}
StereoSpan(const StereoSpan<const ValueType>& span)
: numFrames(span.size())
, leftBuffer(span.left())
, rightBuffer(span.right())
{
}
void fill(Type value) noexcept
{
::fill<Type>(leftBuffer, value);
::fill<Type>(rightBuffer, value);
}
void applyGain(absl::Span<const Type> gain) noexcept
{
::applyGain<Type>(gain, leftBuffer);
::applyGain<Type>(gain, rightBuffer);
}
void applyGain(Type gain) noexcept
{
::applyGain<Type>(gain, leftBuffer);
::applyGain<Type>(gain, rightBuffer);
}
void readInterleaved(absl::Span<const Type> input) noexcept
{
ASSERT(input.size() <= static_cast<size_t>(numChannels * numFrames));
::readInterleaved<Type>(input, absl::MakeSpan(leftBuffer), absl::MakeSpan(rightBuffer));
}
void writeInterleaved(absl::Span<Type> output) noexcept
{
ASSERT(output.size() >= static_cast<size_t>(numChannels * numFrames));
::writeInterleaved<Type>(leftBuffer, rightBuffer, output);
}
void add(StereoSpan<const Type> buffer)
{
::add<Type>(buffer.left(), leftBuffer);
::add<Type>(buffer.right(), rightBuffer);
}
absl::Span<Type> left() const
{
return leftBuffer;
}
absl::Span<Type> right() const
{
return rightBuffer;
}
StereoSpan<Type> first(size_t length) const
{
return { leftBuffer.first(length), rightBuffer.first(length) };
}
StereoSpan<Type> last(size_t length) const
{
return { leftBuffer.last(length), rightBuffer.last(length) };
}
StereoSpan<Type> subspan(size_t pos, size_t length = absl::Span<Type>::npos) const
{
return { leftBuffer.subspan(pos, length), rightBuffer.subspan(pos, length) };
}
size_t size() const
{
return numFrames;
}
private:
static constexpr int numChannels { 2 };
size_t numFrames { 0 };
absl::Span<Type> leftBuffer;
absl::Span<Type> rightBuffer;
LEAK_DETECTOR(StereoSpan);
};

View file

@ -263,29 +263,29 @@ void sfz::Voice::processMono(AudioSpan<float> buffer) noexcept
// Amplitude envelope // Amplitude envelope
amplitudeEnvelope.getBlock(span1); amplitudeEnvelope.getBlock(span1);
::applyGain<float>(span1, leftBuffer); applyGain<float>(span1, leftBuffer);
// AmpEG envelope // AmpEG envelope
egEnvelope.getBlock(span1); egEnvelope.getBlock(span1);
::applyGain<float>(span1, leftBuffer); applyGain<float>(span1, leftBuffer);
// Volume envelope // Volume envelope
volumeEnvelope.getBlock(span1); volumeEnvelope.getBlock(span1);
::applyGain<float>(span1, leftBuffer); applyGain<float>(span1, leftBuffer);
// Prepare for stereo output // Prepare for stereo output
::copy<float>(leftBuffer, rightBuffer); copy<float>(leftBuffer, rightBuffer);
panEnvelope.getBlock(span1); panEnvelope.getBlock(span1);
// We assume that the pan envelope is already normalized between -1 and 1 // We assume that the pan envelope is already normalized between -1 and 1
// Check bm_pan for your architecture to check if it's interesting to use the pan helper instead // Check bm_pan for your architecture to check if it's interesting to use the pan helper instead
::fill<float>(span2, 1.0f); fill<float>(span2, 1.0f);
::add<float>(span1, span2); add<float>(span1, span2);
::applyGain<float>(piFour<float>, span2); applyGain<float>(piFour<float>, span2);
::cos<float>(span2, span1); cos<float>(span2, span1);
::sin<float>(span2, span2); sin<float>(span2, span2);
::applyGain<float>(span1, leftBuffer); applyGain<float>(span1, leftBuffer);
::applyGain<float>(span2, rightBuffer); applyGain<float>(span2, rightBuffer);
} }
void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept
@ -310,36 +310,36 @@ void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept
buffer.applyGain(span1); buffer.applyGain(span1);
// Create mid/side from left/right in the output buffer // Create mid/side from left/right in the output buffer
::copy<float>(rightBuffer, span1); copy<float>(rightBuffer, span1);
::add<float>(leftBuffer, rightBuffer); add<float>(leftBuffer, rightBuffer);
::subtract<float>(span1, leftBuffer); subtract<float>(span1, leftBuffer);
::applyGain<float>(sqrtTwoInv<float>, leftBuffer); applyGain<float>(sqrtTwoInv<float>, leftBuffer);
::applyGain<float>(sqrtTwoInv<float>, rightBuffer); applyGain<float>(sqrtTwoInv<float>, rightBuffer);
// Apply the width process // Apply the width process
widthEnvelope.getBlock(span1); widthEnvelope.getBlock(span1);
::fill<float>(span2, 1.0f); fill<float>(span2, 1.0f);
::add<float>(span1, span2); add<float>(span1, span2);
::applyGain<float>(piFour<float>, span2); applyGain<float>(piFour<float>, span2);
::cos<float>(span2, span1); cos<float>(span2, span1);
::sin<float>(span2, span2); sin<float>(span2, span2);
::applyGain<float>(span1, leftBuffer); applyGain<float>(span1, leftBuffer);
::applyGain<float>(span2, rightBuffer); applyGain<float>(span2, rightBuffer);
// Apply a position to the "left" channel which is supposed to be our mid channel // Apply a position to the "left" channel which is supposed to be our mid channel
// TODO: add panning here too? // TODO: add panning here too?
positionEnvelope.getBlock(span1); positionEnvelope.getBlock(span1);
::fill<float>(span2, 1.0f); fill<float>(span2, 1.0f);
::add<float>(span1, span2); add<float>(span1, span2);
::applyGain<float>(piFour<float>, span2); applyGain<float>(piFour<float>, span2);
::cos<float>(span2, span1); cos<float>(span2, span1);
::sin<float>(span2, span2); sin<float>(span2, span2);
::copy<float>(leftBuffer, span3); copy<float>(leftBuffer, span3);
::copy<float>(rightBuffer, leftBuffer); copy<float>(rightBuffer, leftBuffer);
::multiplyAdd<float>(span1, span3, leftBuffer); multiplyAdd<float>(span1, span3, leftBuffer);
::multiplyAdd<float>(span2, span3, rightBuffer); multiplyAdd<float>(span2, span3, rightBuffer);
::applyGain<float>(sqrtTwoInv<float>, leftBuffer); applyGain<float>(sqrtTwoInv<float>, leftBuffer);
::applyGain<float>(sqrtTwoInv<float>, rightBuffer); applyGain<float>(sqrtTwoInv<float>, rightBuffer);
} }
void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
@ -358,11 +358,11 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
auto leftCoeffs = tempSpan1.first(buffer.getNumFrames()); auto leftCoeffs = tempSpan1.first(buffer.getNumFrames());
auto rightCoeffs = tempSpan2.first(buffer.getNumFrames()); auto rightCoeffs = tempSpan2.first(buffer.getNumFrames());
::fill<float>(jumps, pitchRatio * speedRatio); fill<float>(jumps, pitchRatio * speedRatio);
jumps[0] += floatPositionOffset; jumps[0] += floatPositionOffset;
::cumsum<float>(jumps, jumps); cumsum<float>(jumps, jumps);
::sfzInterpolationCast<float>(jumps, indices, leftCoeffs, rightCoeffs); sfzInterpolationCast<float>(jumps, indices, leftCoeffs, rightCoeffs);
::add<int>(sourcePosition, indices); add<int>(sourcePosition, indices);
//FIXME : all this casting is driving me crazy //FIXME : all this casting is driving me crazy
const auto sampleEnd = min(static_cast<int>(region->trueSampleEnd()), static_cast<int>(source.getNumFrames())) - 1; const auto sampleEnd = min(static_cast<int>(region->trueSampleEnd()), static_cast<int>(source.getNumFrames())) - 1;
@ -371,16 +371,16 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
for (auto* index = indices.begin(); index < indices.end(); ++index) { for (auto* index = indices.begin(); index < indices.end(); ++index) {
if (*index > sampleEnd) { if (*index > sampleEnd) {
const auto remainingElements = static_cast<size_t>(std::distance(index, indices.end())); const auto remainingElements = static_cast<size_t>(std::distance(index, indices.end()));
::subtract<int>(offset, { index, remainingElements }); subtract<int>(offset, { index, remainingElements });
} }
} }
} else { } else {
for (auto* index = indices.begin(); index < indices.end(); ++index) { for (auto* index = indices.begin(); index < indices.end(); ++index) {
if (*index > sampleEnd) { if (*index > sampleEnd) {
const auto remainingElements = static_cast<size_t>(std::distance(index, indices.end())); const auto remainingElements = static_cast<size_t>(std::distance(index, indices.end()));
::fill<int>(indices.last(remainingElements), sampleEnd); fill<int>(indices.last(remainingElements), sampleEnd);
::fill<float>(leftCoeffs.last(remainingElements), 0.0f); fill<float>(leftCoeffs.last(remainingElements), 0.0f);
::fill<float>(rightCoeffs.last(remainingElements), 1.0f); fill<float>(rightCoeffs.last(remainingElements), 1.0f);
break; break;
} }
} }
@ -430,10 +430,10 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
return; return;
float step = baseFrequency * twoPi<float> / sampleRate; float step = baseFrequency * twoPi<float> / sampleRate;
phase = ::linearRamp<float>(tempSpan1, phase, step); phase = linearRamp<float>(tempSpan1, phase, step);
::sin<float>(tempSpan1.first(buffer.getNumFrames()), buffer.getSpan(0)); sin<float>(tempSpan1.first(buffer.getNumFrames()), buffer.getSpan(0));
::copy<float>(buffer.getSpan(0), buffer.getSpan(1)); copy<float>(buffer.getSpan(0), buffer.getSpan(1));
// Wrap the phase so we don't loose too much precision on longer notes // Wrap the phase so we don't loose too much precision on longer notes
const auto numTwoPiWraps = static_cast<int>(phase / twoPi<float>); const auto numTwoPiWraps = static_cast<int>(phase / twoPi<float>);

View file

@ -29,28 +29,28 @@ using namespace Catch::literals;
TEST_CASE("[AudioBuffer] Empty buffers") TEST_CASE("[AudioBuffer] Empty buffers")
{ {
AudioBuffer<float> floatBuffer; sfz::AudioBuffer<float> floatBuffer;
REQUIRE(floatBuffer.empty()); REQUIRE(floatBuffer.empty());
REQUIRE(floatBuffer.getNumFrames() == 0); REQUIRE(floatBuffer.getNumFrames() == 0);
AudioBuffer<double> doubleBuffer; sfz::AudioBuffer<double> doubleBuffer;
REQUIRE(doubleBuffer.empty()); REQUIRE(doubleBuffer.empty());
REQUIRE(doubleBuffer.getNumFrames() == 0); REQUIRE(doubleBuffer.getNumFrames() == 0);
AudioBuffer<int> intBuffer; sfz::AudioBuffer<int> intBuffer;
REQUIRE(intBuffer.empty()); REQUIRE(intBuffer.empty());
REQUIRE(intBuffer.getNumFrames() == 0); REQUIRE(intBuffer.getNumFrames() == 0);
} }
TEST_CASE("[AudioBuffer] Non-empty") TEST_CASE("[AudioBuffer] Non-empty")
{ {
AudioBuffer<float> floatBuffer(1, 10); sfz::AudioBuffer<float> floatBuffer(1, 10);
REQUIRE(!floatBuffer.empty()); REQUIRE(!floatBuffer.empty());
REQUIRE(floatBuffer.getNumFrames() == 10); REQUIRE(floatBuffer.getNumFrames() == 10);
REQUIRE(floatBuffer.getNumChannels() == 1); REQUIRE(floatBuffer.getNumChannels() == 1);
AudioBuffer<double> doubleBuffer(2, 10); sfz::AudioBuffer<double> doubleBuffer(2, 10);
REQUIRE(!doubleBuffer.empty()); REQUIRE(!doubleBuffer.empty());
REQUIRE(doubleBuffer.getNumFrames() == 10); REQUIRE(doubleBuffer.getNumFrames() == 10);
REQUIRE(doubleBuffer.getNumChannels() == 2); REQUIRE(doubleBuffer.getNumChannels() == 2);
AudioBuffer<int> intBuffer(1, 10); sfz::AudioBuffer<int> intBuffer(1, 10);
REQUIRE(!intBuffer.empty()); REQUIRE(!intBuffer.empty());
REQUIRE(intBuffer.getNumFrames() == 10); REQUIRE(intBuffer.getNumFrames() == 10);
REQUIRE(intBuffer.getNumChannels() == 1); REQUIRE(intBuffer.getNumChannels() == 1);
@ -59,7 +59,7 @@ TEST_CASE("[AudioBuffer] Non-empty")
TEST_CASE("[AudioBuffer] Access") TEST_CASE("[AudioBuffer] Access")
{ {
const int size { 5 }; const int size { 5 };
AudioBuffer<float> buffer(2, size); sfz::AudioBuffer<float> buffer(2, size);
for (size_t frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx) { for (size_t frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx) {
buffer.getSample(0, frameIdx) = static_cast<double>(buffer.getNumFrames()) + frameIdx; buffer.getSample(0, frameIdx) = static_cast<double>(buffer.getNumFrames()) + frameIdx;
buffer.getSample(1, frameIdx) = static_cast<double>(buffer.getNumFrames()) - frameIdx; buffer.getSample(1, frameIdx) = static_cast<double>(buffer.getNumFrames()) - frameIdx;
@ -77,7 +77,7 @@ TEST_CASE("[AudioBuffer] Iterators")
{ {
const int size { 256 }; const int size { 256 };
const float fillValue { 2.0f }; const float fillValue { 2.0f };
AudioBuffer<float> buffer(2, size); sfz::AudioBuffer<float> buffer(2, size);
std::fill(buffer.channelWriter(0), buffer.channelWriterEnd(0), fillValue); std::fill(buffer.channelWriter(0), buffer.channelWriterEnd(0), fillValue);
std::fill(buffer.channelWriter(1), buffer.channelWriterEnd(1), fillValue); std::fill(buffer.channelWriter(1), buffer.channelWriterEnd(1), fillValue);
@ -89,14 +89,14 @@ TEST_CASE("[AudioSpan] Constructions")
{ {
const int size { 256 }; const int size { 256 };
const float fillValue { 2.0f }; const float fillValue { 2.0f };
AudioBuffer<float> buffer(2, size); sfz::AudioBuffer<float> buffer(2, size);
std::fill(buffer.channelWriter(0), buffer.channelWriterEnd(0), fillValue); std::fill(buffer.channelWriter(0), buffer.channelWriterEnd(0), fillValue);
std::fill(buffer.channelWriter(1), buffer.channelWriterEnd(1), fillValue); std::fill(buffer.channelWriter(1), buffer.channelWriterEnd(1), fillValue);
AudioSpan<float> span { buffer }; sfz::AudioSpan<float> span { buffer };
AudioSpan<const float> constSpan { buffer }; sfz::AudioSpan<const float> constSpan { buffer };
AudioSpan<float> manualSpan { { buffer.channelWriter(0), buffer.channelWriter(1) }, buffer.getNumFrames() }; sfz::AudioSpan<float> manualSpan { { buffer.channelWriter(0), buffer.channelWriter(1) }, buffer.getNumFrames() };
AudioSpan<const float> manualConstSpan { { buffer.channelReader(0), buffer.channelReader(1) }, buffer.getNumFrames() }; sfz::AudioSpan<const float> manualConstSpan { { buffer.channelReader(0), buffer.channelReader(1) }, buffer.getNumFrames() };
AudioSpan<float> manualSpan2 { {buffer.getSpan(0), buffer.getSpan(1) } }; sfz::AudioSpan<float> manualSpan2 { {buffer.getSpan(0), buffer.getSpan(1) } };
AudioSpan<const float> manualConstSpan2 { {buffer.getConstSpan(0), buffer.getConstSpan(1) } }; sfz::AudioSpan<const float> manualConstSpan2 { {buffer.getConstSpan(0), buffer.getConstSpan(1) } };
} }

View file

@ -28,38 +28,38 @@ using namespace Catch::literals;
TEST_CASE("[Buffer] Empty (float)") TEST_CASE("[Buffer] Empty (float)")
{ {
Buffer<float> emptyBuffer; sfz::Buffer<float> emptyBuffer;
REQUIRE(emptyBuffer.empty()); REQUIRE(emptyBuffer.empty());
REQUIRE(emptyBuffer.size() == 0); REQUIRE(emptyBuffer.size() == 0);
} }
TEST_CASE("[Buffer] Empty (int)") TEST_CASE("[Buffer] Empty (int)")
{ {
Buffer<int> emptyBuffer; sfz::Buffer<int> emptyBuffer;
REQUIRE(emptyBuffer.empty()); REQUIRE(emptyBuffer.empty());
REQUIRE(emptyBuffer.size() == 0); REQUIRE(emptyBuffer.size() == 0);
} }
TEST_CASE("[Buffer] Empty (double)") TEST_CASE("[Buffer] Empty (double)")
{ {
Buffer<double> emptyBuffer; sfz::Buffer<double> emptyBuffer;
REQUIRE(emptyBuffer.empty()); REQUIRE(emptyBuffer.empty());
REQUIRE(emptyBuffer.size() == 0); REQUIRE(emptyBuffer.size() == 0);
} }
TEST_CASE("[Buffer] Empty (uint8_t)") TEST_CASE("[Buffer] Empty (uint8_t)")
{ {
Buffer<uint8_t> emptyBuffer; sfz::Buffer<uint8_t> emptyBuffer;
REQUIRE(emptyBuffer.empty()); REQUIRE(emptyBuffer.empty());
REQUIRE(emptyBuffer.size() == 0); REQUIRE(emptyBuffer.size() == 0);
} }
template <class Type> template <class Type>
void checkBoundaries(Buffer<Type>& buffer, int expectedSize) void checkBoundaries(sfz::Buffer<Type>& buffer, int expectedSize)
{ {
REQUIRE((int)buffer.size() == expectedSize); REQUIRE((int)buffer.size() == expectedSize);
REQUIRE(((size_t)buffer.data() & (SIMDConfig::defaultAlignment - 1)) == 0); REQUIRE(((size_t)buffer.data() & (sfz::SIMDConfig::defaultAlignment - 1)) == 0);
REQUIRE(((size_t)buffer.alignedEnd() & (SIMDConfig::defaultAlignment - 1)) == 0); REQUIRE(((size_t)buffer.alignedEnd() & (sfz::SIMDConfig::defaultAlignment - 1)) == 0);
REQUIRE(std::distance(buffer.begin(), buffer.end()) == expectedSize); REQUIRE(std::distance(buffer.begin(), buffer.end()) == expectedSize);
REQUIRE(std::distance(buffer.begin(), buffer.alignedEnd()) >= expectedSize); REQUIRE(std::distance(buffer.begin(), buffer.alignedEnd()) >= expectedSize);
} }
@ -67,7 +67,7 @@ void checkBoundaries(Buffer<Type>& buffer, int expectedSize)
TEST_CASE("[Buffer] 10 floats ") TEST_CASE("[Buffer] 10 floats ")
{ {
const int baseSize { 10 }; const int baseSize { 10 };
Buffer<float> buffer(baseSize); sfz::Buffer<float> buffer(baseSize);
checkBoundaries(buffer, baseSize); checkBoundaries(buffer, baseSize);
for (auto& element : buffer) for (auto& element : buffer)
@ -81,7 +81,7 @@ TEST_CASE("[Buffer] Resize 10 floats ")
const int baseSize { 10 }; const int baseSize { 10 };
const int smallSize { baseSize / 2 }; const int smallSize { baseSize / 2 };
const int bigSize { baseSize * 2 }; const int bigSize { baseSize * 2 };
Buffer<float> buffer(baseSize); sfz::Buffer<float> buffer(baseSize);
REQUIRE(!buffer.empty()); REQUIRE(!buffer.empty());
checkBoundaries(buffer, baseSize); checkBoundaries(buffer, baseSize);
@ -103,7 +103,7 @@ TEST_CASE("[Buffer] Resize 4096 floats ")
const int baseSize { 4096 }; const int baseSize { 4096 };
const int smallSize { baseSize / 2 }; const int smallSize { baseSize / 2 };
const int bigSize { baseSize * 2 }; const int bigSize { baseSize * 2 };
Buffer<float> buffer(baseSize); sfz::Buffer<float> buffer(baseSize);
REQUIRE(!buffer.empty()); REQUIRE(!buffer.empty());
checkBoundaries(buffer, baseSize); checkBoundaries(buffer, baseSize);
@ -125,7 +125,7 @@ TEST_CASE("[Buffer] Resize 65536 floats ")
const int baseSize { 10 }; const int baseSize { 10 };
const int smallSize { baseSize / 2 }; const int smallSize { baseSize / 2 };
const int bigSize { baseSize * 2 }; const int bigSize { baseSize * 2 };
Buffer<float> buffer(baseSize); sfz::Buffer<float> buffer(baseSize);
REQUIRE(!buffer.empty()); REQUIRE(!buffer.empty());
checkBoundaries(buffer, baseSize); checkBoundaries(buffer, baseSize);
@ -145,19 +145,19 @@ TEST_CASE("[Buffer] Resize 65536 floats ")
TEST_CASE("[Buffer] Copy and move") TEST_CASE("[Buffer] Copy and move")
{ {
const int baseSize { 128 }; const int baseSize { 128 };
Buffer<float> buffer(baseSize); sfz::Buffer<float> buffer(baseSize);
Buffer<float> copied { baseSize - 4 }; sfz::Buffer<float> copied { baseSize - 4 };
std::fill(buffer.begin(), buffer.end(), 1.0f); std::fill(buffer.begin(), buffer.end(), 1.0f);
std::fill(copied.begin(), copied.end(), 2.0f); std::fill(copied.begin(), copied.end(), 2.0f);
copied = buffer; copied = buffer;
checkBoundaries(copied, baseSize); checkBoundaries(copied, baseSize);
REQUIRE(std::all_of(copied.begin(), copied.end(), [](auto value) { return value == 1.0f; })); REQUIRE(std::all_of(copied.begin(), copied.end(), [](auto value) { return value == 1.0f; }));
Buffer<float> copyConstructed { buffer }; sfz::Buffer<float> copyConstructed { buffer };
checkBoundaries(copyConstructed, baseSize); checkBoundaries(copyConstructed, baseSize);
REQUIRE(std::all_of(copyConstructed.begin(), copyConstructed.end(), [](auto value) { return value == 1.0f; })); REQUIRE(std::all_of(copyConstructed.begin(), copyConstructed.end(), [](auto value) { return value == 1.0f; }));
Buffer<float> moveConstructed { std::move(buffer) }; sfz::Buffer<float> moveConstructed { std::move(buffer) };
REQUIRE(buffer.empty()); REQUIRE(buffer.empty());
checkBoundaries(moveConstructed, baseSize); checkBoundaries(moveConstructed, baseSize);
REQUIRE(std::all_of(moveConstructed.begin(), moveConstructed.end(), [](auto value) { return value == 1.0f; })); REQUIRE(std::all_of(moveConstructed.begin(), moveConstructed.end(), [](auto value) { return value == 1.0f; }));

View file

@ -12,7 +12,6 @@ set(SFIZZ_TEST_SOURCES
RangeT.cpp RangeT.cpp
OpcodeT.cpp OpcodeT.cpp
BufferT.cpp BufferT.cpp
StereoBufferT.cpp
SIMDHelpersT.cpp SIMDHelpersT.cpp
FilesT.cpp FilesT.cpp
OnePoleFilterT.cpp OnePoleFilterT.cpp

View file

@ -67,7 +67,7 @@ void testLowpass(const fs::path& inputNumpyFile, const fs::path& outputNumpyFile
for (auto& data : outputSpan) for (auto& data : outputSpan)
expectedData.push_back(static_cast<Type>(data)); expectedData.push_back(static_cast<Type>(data));
OnePoleFilter<Type> filter { gain }; sfz::OnePoleFilter<Type> filter { gain };
std::vector<Type> outputData(size); std::vector<Type> outputData(size);
filter.processLowpass(inputData, absl::MakeSpan(outputData)); filter.processLowpass(inputData, absl::MakeSpan(outputData));
REQUIRE(approxEqual(outputData, expectedData)); REQUIRE(approxEqual(outputData, expectedData));
@ -102,7 +102,7 @@ void testHighpass(const fs::path& inputNumpyFile, const fs::path& outputNumpyFil
for (auto& data : outputSpan) for (auto& data : outputSpan)
expectedData.push_back(static_cast<Type>(data)); expectedData.push_back(static_cast<Type>(data));
OnePoleFilter<Type> filter { gain }; sfz::OnePoleFilter<Type> filter { gain };
std::vector<Type> outputData(size); std::vector<Type> outputData(size);
filter.processHighpass(inputData, absl::MakeSpan(outputData)); filter.processHighpass(inputData, absl::MakeSpan(outputData));
REQUIRE(approxEqual(outputData, expectedData)); REQUIRE(approxEqual(outputData, expectedData));

View file

@ -69,7 +69,7 @@ TEST_CASE("[Helpers] fill() - Manual buffer")
{ {
std::vector<float> buffer(5); std::vector<float> buffer(5);
std::vector<float> expected { fillValue, fillValue, fillValue, fillValue, fillValue }; std::vector<float> expected { fillValue, fillValue, fillValue, fillValue, fillValue };
fill<float, false>(absl::MakeSpan(buffer), fillValue); sfz::fill<float, false>(absl::MakeSpan(buffer), fillValue);
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -79,7 +79,7 @@ TEST_CASE("[Helpers] fill() - Small buffer")
std::vector<float> expected(smallBufferSize); std::vector<float> expected(smallBufferSize);
std::fill(expected.begin(), expected.end(), fillValue); std::fill(expected.begin(), expected.end(), fillValue);
fill<float, false>(absl::MakeSpan(buffer), fillValue); sfz::fill<float, false>(absl::MakeSpan(buffer), fillValue);
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -89,7 +89,7 @@ TEST_CASE("[Helpers] fill() - Big buffer")
std::vector<float> expected(bigBufferSize); std::vector<float> expected(bigBufferSize);
std::fill(expected.begin(), expected.end(), fillValue); std::fill(expected.begin(), expected.end(), fillValue);
fill<float, false>(absl::MakeSpan(buffer), fillValue); sfz::fill<float, false>(absl::MakeSpan(buffer), fillValue);
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -99,7 +99,7 @@ TEST_CASE("[Helpers] fill() - Small buffer -- SIMD")
std::vector<float> expected(smallBufferSize); std::vector<float> expected(smallBufferSize);
std::fill(expected.begin(), expected.end(), fillValue); std::fill(expected.begin(), expected.end(), fillValue);
fill<float, true>(absl::MakeSpan(buffer), fillValue); sfz::fill<float, true>(absl::MakeSpan(buffer), fillValue);
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -109,7 +109,7 @@ TEST_CASE("[Helpers] fill() - Big buffer -- SIMD")
std::vector<float> expected(bigBufferSize); std::vector<float> expected(bigBufferSize);
std::fill(expected.begin(), expected.end(), fillValue); std::fill(expected.begin(), expected.end(), fillValue);
fill<float, true>(absl::MakeSpan(buffer), fillValue); sfz::fill<float, true>(absl::MakeSpan(buffer), fillValue);
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -119,7 +119,7 @@ TEST_CASE("[Helpers] fill() - Small buffer -- doubles")
std::vector<double> expected(smallBufferSize); std::vector<double> expected(smallBufferSize);
std::fill(expected.begin(), expected.end(), fillValue); std::fill(expected.begin(), expected.end(), fillValue);
fill<double, false>(absl::MakeSpan(buffer), fillValue); sfz::fill<double, false>(absl::MakeSpan(buffer), fillValue);
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -129,7 +129,7 @@ TEST_CASE("[Helpers] fill() - Big buffer -- doubles")
std::vector<double> expected(bigBufferSize); std::vector<double> expected(bigBufferSize);
std::fill(expected.begin(), expected.end(), fillValue); std::fill(expected.begin(), expected.end(), fillValue);
fill<double, false>(absl::MakeSpan(buffer), fillValue); sfz::fill<double, false>(absl::MakeSpan(buffer), fillValue);
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -139,7 +139,7 @@ TEST_CASE("[Helpers] Interleaved read")
std::array<float, 16> expected { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f }; std::array<float, 16> expected { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 8> leftOutput; std::array<float, 8> leftOutput;
std::array<float, 8> rightOutput; std::array<float, 8> rightOutput;
readInterleaved<float, false>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput)); sfz::readInterleaved<float, false>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 16> real; std::array<float, 16> real;
auto realIdx = 0; auto realIdx = 0;
@ -156,7 +156,7 @@ TEST_CASE("[Helpers] Interleaved read unaligned end")
std::array<float, 20> expected { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f }; std::array<float, 20> expected { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f };
std::array<float, 10> leftOutput; std::array<float, 10> leftOutput;
std::array<float, 10> rightOutput; std::array<float, 10> rightOutput;
readInterleaved<float, false>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput)); sfz::readInterleaved<float, false>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 20> real; std::array<float, 20> real;
auto realIdx = 0; auto realIdx = 0;
@ -173,7 +173,7 @@ TEST_CASE("[Helpers] Small interleaved read unaligned end")
std::array<float, 6> expected { 0.0f, 1.0f, 2.0f, 10.0f, 11.0f, 12.0f }; std::array<float, 6> expected { 0.0f, 1.0f, 2.0f, 10.0f, 11.0f, 12.0f };
std::array<float, 3> leftOutput; std::array<float, 3> leftOutput;
std::array<float, 3> rightOutput; std::array<float, 3> rightOutput;
readInterleaved<float, false>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput)); sfz::readInterleaved<float, false>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 6> real; std::array<float, 6> real;
auto realIdx = 0; auto realIdx = 0;
@ -190,7 +190,7 @@ TEST_CASE("[Helpers] Interleaved read -- SIMD")
std::array<float, 16> expected = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f }; std::array<float, 16> expected = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 8> leftOutput; std::array<float, 8> leftOutput;
std::array<float, 8> rightOutput; std::array<float, 8> rightOutput;
readInterleaved<float, true>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput)); sfz::readInterleaved<float, true>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 16> real; std::array<float, 16> real;
auto realIdx = 0; auto realIdx = 0;
@ -207,7 +207,7 @@ TEST_CASE("[Helpers] Interleaved read unaligned end -- SIMD")
std::array<float, 20> expected = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f }; std::array<float, 20> expected = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f };
std::array<float, 10> leftOutput; std::array<float, 10> leftOutput;
std::array<float, 10> rightOutput; std::array<float, 10> rightOutput;
readInterleaved<float, true>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput)); sfz::readInterleaved<float, true>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 20> real; std::array<float, 20> real;
auto realIdx = 0; auto realIdx = 0;
@ -224,7 +224,7 @@ TEST_CASE("[Helpers] Small interleaved read unaligned end -- SIMD")
std::array<float, 6> expected { 0.0f, 1.0f, 2.0f, 10.0f, 11.0f, 12.0f }; std::array<float, 6> expected { 0.0f, 1.0f, 2.0f, 10.0f, 11.0f, 12.0f };
std::array<float, 3> leftOutput; std::array<float, 3> leftOutput;
std::array<float, 3> rightOutput; std::array<float, 3> rightOutput;
readInterleaved<float, true>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput)); sfz::readInterleaved<float, true>(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 6> real; std::array<float, 6> real;
auto realIdx = 0; auto realIdx = 0;
@ -243,8 +243,8 @@ TEST_CASE("[Helpers] Interleaved read SIMD vs Scalar")
std::array<float, medBufferSize> leftOutputSIMD; std::array<float, medBufferSize> leftOutputSIMD;
std::array<float, medBufferSize> rightOutputSIMD; std::array<float, medBufferSize> rightOutputSIMD;
std::iota(input.begin(), input.end(), 0.0f); std::iota(input.begin(), input.end(), 0.0f);
readInterleaved<float, false>(input, absl::MakeSpan(leftOutputScalar), absl::MakeSpan(rightOutputScalar)); sfz::readInterleaved<float, false>(input, absl::MakeSpan(leftOutputScalar), absl::MakeSpan(rightOutputScalar));
readInterleaved<float, true>(input, absl::MakeSpan(leftOutputSIMD), absl::MakeSpan(rightOutputSIMD)); sfz::readInterleaved<float, true>(input, absl::MakeSpan(leftOutputSIMD), absl::MakeSpan(rightOutputSIMD));
REQUIRE(leftOutputScalar == leftOutputSIMD); REQUIRE(leftOutputScalar == leftOutputSIMD);
REQUIRE(rightOutputScalar == rightOutputSIMD); REQUIRE(rightOutputScalar == rightOutputSIMD);
} }
@ -264,7 +264,7 @@ TEST_CASE("[Helpers] Interleaved write")
std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f }; std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 16> output; std::array<float, 16> output;
std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f }; std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f };
writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output)); sfz::writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -274,7 +274,7 @@ TEST_CASE("[Helpers] Interleaved write unaligned end")
std::array<float, 10> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f }; std::array<float, 10> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f };
std::array<float, 20> output; std::array<float, 20> output;
std::array<float, 20> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f, 8.0f, 18.0f, 9.0f, 19.0f }; std::array<float, 20> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f, 8.0f, 18.0f, 9.0f, 19.0f };
writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output)); sfz::writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -284,7 +284,7 @@ TEST_CASE("[Helpers] Small interleaved write unaligned end")
std::array<float, 3> rightInput { 10.0f, 11.0f, 12.0f }; std::array<float, 3> rightInput { 10.0f, 11.0f, 12.0f };
std::array<float, 6> output; std::array<float, 6> output;
std::array<float, 6> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f }; std::array<float, 6> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f };
writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output)); sfz::writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -303,7 +303,7 @@ TEST_CASE("[Helpers] Interleaved write -- SIMD")
std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f }; std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 16> output; std::array<float, 16> output;
std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f }; std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f };
writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output)); sfz::writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -313,7 +313,7 @@ TEST_CASE("[Helpers] Interleaved write unaligned end -- SIMD")
std::array<float, 10> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f }; std::array<float, 10> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f };
std::array<float, 20> output; std::array<float, 20> output;
std::array<float, 20> expected = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f, 8.0f, 18.0f, 9.0f, 19.0f }; std::array<float, 20> expected = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f, 8.0f, 18.0f, 9.0f, 19.0f };
writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output)); sfz::writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -323,7 +323,7 @@ TEST_CASE("[Helpers] Small interleaved write unaligned end -- SIMD")
std::array<float, 3> rightInput { 10.0f, 11.0f, 12.0f }; std::array<float, 3> rightInput { 10.0f, 11.0f, 12.0f };
std::array<float, 6> output; std::array<float, 6> output;
std::array<float, 6> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f }; std::array<float, 6> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f };
writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output)); sfz::writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -335,8 +335,8 @@ TEST_CASE("[Helpers] Interleaved write SIMD vs Scalar")
std::array<float, medBufferSize * 2> outputSIMD; std::array<float, medBufferSize * 2> outputSIMD;
std::iota(leftInput.begin(), leftInput.end(), 0.0f); std::iota(leftInput.begin(), leftInput.end(), 0.0f);
std::iota(rightInput.begin(), rightInput.end(), medBufferSize); std::iota(rightInput.begin(), rightInput.end(), medBufferSize);
writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(outputScalar)); sfz::writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(outputScalar));
writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(outputSIMD)); sfz::writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(outputSIMD));
REQUIRE(outputScalar == outputSIMD); REQUIRE(outputScalar == outputSIMD);
} }
@ -345,7 +345,7 @@ TEST_CASE("[Helpers] Gain, single")
std::array<float, 5> input { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> input { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue }; std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue };
applyGain<float, false>(fillValue, input, absl::MakeSpan(output)); sfz::applyGain<float, false>(fillValue, input, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -353,7 +353,7 @@ TEST_CASE("[Helpers] Gain, single and inplace")
{ {
std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue }; std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue };
applyGain<float, false>(fillValue, buffer, absl::MakeSpan(buffer)); sfz::applyGain<float, false>(fillValue, buffer, absl::MakeSpan(buffer));
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -363,7 +363,7 @@ TEST_CASE("[Helpers] Gain, spans")
std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
applyGain<float, false>(gain, input, absl::MakeSpan(output)); sfz::applyGain<float, false>(gain, input, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -372,7 +372,7 @@ TEST_CASE("[Helpers] Gain, spans and inplace")
std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
applyGain<float, false>(gain, buffer, absl::MakeSpan(buffer)); sfz::applyGain<float, false>(gain, buffer, absl::MakeSpan(buffer));
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -381,7 +381,7 @@ TEST_CASE("[Helpers] Gain, single (SIMD)")
std::array<float, 5> input { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> input { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue }; std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue };
applyGain<float, true>(fillValue, input, absl::MakeSpan(output)); sfz::applyGain<float, true>(fillValue, input, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -389,7 +389,7 @@ TEST_CASE("[Helpers] Gain, single and inplace (SIMD)")
{ {
std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue }; std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue };
applyGain<float, true>(fillValue, buffer, absl::MakeSpan(buffer)); sfz::applyGain<float, true>(fillValue, buffer, absl::MakeSpan(buffer));
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -399,7 +399,7 @@ TEST_CASE("[Helpers] Gain, spans (SIMD)")
std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
applyGain<float, true>(gain, input, absl::MakeSpan(output)); sfz::applyGain<float, true>(gain, input, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -408,7 +408,7 @@ TEST_CASE("[Helpers] Gain, spans and inplace (SIMD)")
std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
applyGain<float, true>(gain, buffer, absl::MakeSpan(buffer)); sfz::applyGain<float, true>(gain, buffer, absl::MakeSpan(buffer));
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
@ -421,7 +421,7 @@ TEST_CASE("[Helpers] SFZ looping index")
std::array<int, 6> expectedIndices { 2, 3, 4, 1, 2, 4 }; std::array<int, 6> expectedIndices { 2, 3, 4, 1, 2, 4 };
std::array<float, 6> expectedLeft { 0.9f, 0.7f, 0.4f, 1.0f, 0.5f, 0.9f }; std::array<float, 6> expectedLeft { 0.9f, 0.7f, 0.4f, 1.0f, 0.5f, 0.9f };
std::array<float, 6> expectedRight { 0.1f, 0.3f, 0.6f, 0.0f, 0.5f, 0.1f }; std::array<float, 6> expectedRight { 0.1f, 0.3f, 0.6f, 0.0f, 0.5f, 0.1f };
loopingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 6, 1); sfz::loopingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 6, 1);
REQUIRE(indices == expectedIndices); REQUIRE(indices == expectedIndices);
REQUIRE(approxEqual<float>(leftCoeffs, expectedLeft)); REQUIRE(approxEqual<float>(leftCoeffs, expectedLeft));
REQUIRE(approxEqual<float>(rightCoeffs, expectedRight)); REQUIRE(approxEqual<float>(rightCoeffs, expectedRight));
@ -436,7 +436,7 @@ TEST_CASE("[Helpers] SFZ looping index (SIMD)")
std::array<int, 6> expectedIndices { 2, 3, 4, 1, 2, 4 }; std::array<int, 6> expectedIndices { 2, 3, 4, 1, 2, 4 };
std::array<float, 6> expectedLeft { 0.9f, 0.7f, 0.4f, 1.0f, 0.5f, 0.9f }; std::array<float, 6> expectedLeft { 0.9f, 0.7f, 0.4f, 1.0f, 0.5f, 0.9f };
std::array<float, 6> expectedRight { 0.1f, 0.3f, 0.6f, 0.0f, 0.5f, 0.1f }; std::array<float, 6> expectedRight { 0.1f, 0.3f, 0.6f, 0.0f, 0.5f, 0.1f };
loopingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 6, 1); sfz::loopingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 6, 1);
REQUIRE(indices == expectedIndices); REQUIRE(indices == expectedIndices);
REQUIRE(approxEqual<float>(leftCoeffs, expectedLeft)); REQUIRE(approxEqual<float>(leftCoeffs, expectedLeft));
REQUIRE(approxEqual<float>(rightCoeffs, expectedRight)); REQUIRE(approxEqual<float>(rightCoeffs, expectedRight));
@ -455,8 +455,8 @@ TEST_CASE("[Helpers] SFZ looping index (SIMD)")
// std::vector<int> indicesSIMD(bigBufferSize); // std::vector<int> indicesSIMD(bigBufferSize);
// std::vector<float> leftCoeffsSIMD(bigBufferSize); // std::vector<float> leftCoeffsSIMD(bigBufferSize);
// std::vector<float> rightCoeffsSIMD(bigBufferSize); // std::vector<float> rightCoeffsSIMD(bigBufferSize);
// loopingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, medBufferSize, 1); // sfz::loopingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, medBufferSize, 1);
// loopingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffsSIMD), absl::MakeSpan(rightCoeffsSIMD), absl::MakeSpan(indicesSIMD), 1.0f, medBufferSize, 1); // sfz::loopingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffsSIMD), absl::MakeSpan(rightCoeffsSIMD), absl::MakeSpan(indicesSIMD), 1.0f, medBufferSize, 1);
// for (int i = 0; i < bigBufferSize; ++i) // for (int i = 0; i < bigBufferSize; ++i)
// REQUIRE( ((static_cast<float>(indices[i]) + rightCoeffs[i] == Approx(static_cast<float>(indicesSIMD[i]) + rightCoeffsSIMD[i]).margin(1e-2)) // REQUIRE( ((static_cast<float>(indices[i]) + rightCoeffs[i] == Approx(static_cast<float>(indicesSIMD[i]) + rightCoeffsSIMD[i]).margin(1e-2))
// || (static_cast<float>(indices[i]) + rightCoeffs[i] == Approx(static_cast<float>(indicesSIMD[i]) + rightCoeffsSIMD[i] - static_cast<float>(medBufferSize)).margin(2e-2))) ); // || (static_cast<float>(indices[i]) + rightCoeffs[i] == Approx(static_cast<float>(indicesSIMD[i]) + rightCoeffsSIMD[i] - static_cast<float>(medBufferSize)).margin(2e-2))) );
@ -471,7 +471,7 @@ TEST_CASE("[Helpers] SFZ saturating index")
std::array<int, 6> expectedIndices { 2, 3, 4, 5, 5, 5 }; std::array<int, 6> expectedIndices { 2, 3, 4, 5, 5, 5 };
std::array<float, 6> expectedLeft { 0.9f, 0.7f, 0.4f, 0.0f, 0.0f, 0.0f }; std::array<float, 6> expectedLeft { 0.9f, 0.7f, 0.4f, 0.0f, 0.0f, 0.0f };
std::array<float, 6> expectedRight { 0.1f, 0.3f, 0.6f, 1.0f, 1.0f, 1.0f }; std::array<float, 6> expectedRight { 0.1f, 0.3f, 0.6f, 1.0f, 1.0f, 1.0f };
saturatingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 6); sfz::saturatingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 6);
REQUIRE(indices == expectedIndices); REQUIRE(indices == expectedIndices);
REQUIRE(approxEqual<float>(leftCoeffs, expectedLeft)); REQUIRE(approxEqual<float>(leftCoeffs, expectedLeft));
REQUIRE(approxEqual<float>(rightCoeffs, expectedRight)); REQUIRE(approxEqual<float>(rightCoeffs, expectedRight));
@ -486,7 +486,7 @@ TEST_CASE("[Helpers] SFZ saturating index (SIMD)")
std::array<int, 6> expectedIndices { 2, 3, 4, 5, 5, 5 }; std::array<int, 6> expectedIndices { 2, 3, 4, 5, 5, 5 };
std::array<float, 6> expectedLeft { 0.9f, 0.7f, 0.4f, 0.0f, 0.0f, 0.0f }; std::array<float, 6> expectedLeft { 0.9f, 0.7f, 0.4f, 0.0f, 0.0f, 0.0f };
std::array<float, 6> expectedRight { 0.1f, 0.3f, 0.6f, 1.0f, 1.0f, 1.0f }; std::array<float, 6> expectedRight { 0.1f, 0.3f, 0.6f, 1.0f, 1.0f, 1.0f };
saturatingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 6); sfz::saturatingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 6);
REQUIRE(indices == expectedIndices); REQUIRE(indices == expectedIndices);
REQUIRE(approxEqualMargin<float>(leftCoeffs, expectedLeft)); REQUIRE(approxEqualMargin<float>(leftCoeffs, expectedLeft));
REQUIRE(approxEqualMargin<float>(rightCoeffs, expectedRight)); REQUIRE(approxEqualMargin<float>(rightCoeffs, expectedRight));
@ -505,8 +505,8 @@ TEST_CASE("[Helpers] SFZ saturating index (SIMD vs Scalar)")
std::vector<int> indicesSIMD(medBufferSize); std::vector<int> indicesSIMD(medBufferSize);
std::vector<float> leftCoeffsSIMD(medBufferSize); std::vector<float> leftCoeffsSIMD(medBufferSize);
std::vector<float> rightCoeffsSIMD(medBufferSize); std::vector<float> rightCoeffsSIMD(medBufferSize);
saturatingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 78); sfz::saturatingSFZIndex<float, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 1.0f, 78);
saturatingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffsSIMD), absl::MakeSpan(rightCoeffsSIMD), absl::MakeSpan(indicesSIMD), 1.0f, 78); sfz::saturatingSFZIndex<float, true>(jumps, absl::MakeSpan(leftCoeffsSIMD), absl::MakeSpan(rightCoeffsSIMD), absl::MakeSpan(indicesSIMD), 1.0f, 78);
for (int i = 0; i < medBufferSize; ++i) for (int i = 0; i < medBufferSize; ++i)
REQUIRE( static_cast<float>(indices[i]) + rightCoeffs[i] == Approx(static_cast<float>(indicesSIMD[i]) + rightCoeffsSIMD[i])); REQUIRE( static_cast<float>(indices[i]) + rightCoeffs[i] == Approx(static_cast<float>(indicesSIMD[i]) + rightCoeffsSIMD[i]));
} }
@ -517,7 +517,7 @@ TEST_CASE("[Helpers] Linear Ramp")
const float v { fillValue }; const float v { fillValue };
std::array<float, 6> output; std::array<float, 6> output;
std::array<float, 6> expected { v, v + v, v + v + v, v + v + v + v, v + v + v + v + v, v + v + v + v + v + v }; std::array<float, 6> expected { v, v + v, v + v + v, v + v + v + v, v + v + v + v + v, v + v + v + v + v + v };
linearRamp<float, false>(absl::MakeSpan(output), start, v); sfz::linearRamp<float, false>(absl::MakeSpan(output), start, v);
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -527,7 +527,7 @@ TEST_CASE("[Helpers] Linear Ramp (SIMD)")
const float v { fillValue }; const float v { fillValue };
std::array<float, 6> output; std::array<float, 6> output;
std::array<float, 6> expected { v, v + v, v + v + v, v + v + v + v, v + v + v + v + v, v + v + v + v + v + v }; std::array<float, 6> expected { v, v + v, v + v + v, v + v + v + v, v + v + v + v + v, v + v + v + v + v + v };
linearRamp<float, true>(absl::MakeSpan(output), start, v); sfz::linearRamp<float, true>(absl::MakeSpan(output), start, v);
REQUIRE(approxEqual<float>(output, expected)); REQUIRE(approxEqual<float>(output, expected));
} }
@ -536,8 +536,8 @@ TEST_CASE("[Helpers] Linear Ramp (SIMD vs scalar)")
const float start { 0.0f }; const float start { 0.0f };
std::vector<float> outputScalar(bigBufferSize); std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize); std::vector<float> outputSIMD(bigBufferSize);
linearRamp<float, false>(absl::MakeSpan(outputScalar), start, fillValue); sfz::linearRamp<float, false>(absl::MakeSpan(outputScalar), start, fillValue);
linearRamp<float, true>(absl::MakeSpan(outputSIMD), start, fillValue); sfz::linearRamp<float, true>(absl::MakeSpan(outputSIMD), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }
@ -546,8 +546,8 @@ TEST_CASE("[Helpers] Linear Ramp unaligned (SIMD vs scalar)")
const float start { 0.0f }; const float start { 0.0f };
std::vector<float> outputScalar(bigBufferSize); std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize); std::vector<float> outputSIMD(bigBufferSize);
linearRamp<float, false>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue); sfz::linearRamp<float, false>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue);
linearRamp<float, true>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue); sfz::linearRamp<float, true>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }
@ -557,7 +557,7 @@ TEST_CASE("[Helpers] Multiplicative Ramp")
const float v { fillValue }; const float v { fillValue };
std::array<float, 6> output; std::array<float, 6> output;
std::array<float, 6> expected { v, v * v, v * v * v, v * v * v * v, v * v * v * v * v, v * v * v * v * v * v }; std::array<float, 6> expected { v, v * v, v * v * v, v * v * v * v, v * v * v * v * v, v * v * v * v * v * v };
multiplicativeRamp<float, false>(absl::MakeSpan(output), start, v); sfz::multiplicativeRamp<float, false>(absl::MakeSpan(output), start, v);
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -567,7 +567,7 @@ TEST_CASE("[Helpers] Multiplicative Ramp (SIMD)")
const float v { fillValue }; const float v { fillValue };
std::array<float, 6> output; std::array<float, 6> output;
std::array<float, 6> expected { v, v * v, v * v * v, v * v * v * v, v * v * v * v * v, v * v * v * v * v * v }; std::array<float, 6> expected { v, v * v, v * v * v, v * v * v * v, v * v * v * v * v, v * v * v * v * v * v };
multiplicativeRamp<float, true>(absl::MakeSpan(output), start, v); sfz::multiplicativeRamp<float, true>(absl::MakeSpan(output), start, v);
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -576,8 +576,8 @@ TEST_CASE("[Helpers] Multiplicative Ramp (SIMD vs scalar)")
const float start { 1.0f }; const float start { 1.0f };
std::vector<float> outputScalar(bigBufferSize); std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize); std::vector<float> outputSIMD(bigBufferSize);
multiplicativeRamp<float, false>(absl::MakeSpan(outputScalar), start, fillValue); sfz::multiplicativeRamp<float, false>(absl::MakeSpan(outputScalar), start, fillValue);
multiplicativeRamp<float, true>(absl::MakeSpan(outputSIMD), start, fillValue); sfz::multiplicativeRamp<float, true>(absl::MakeSpan(outputSIMD), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }
@ -586,8 +586,8 @@ TEST_CASE("[Helpers] Multiplicative Ramp unaligned (SIMD vs scalar)")
const float start { 1.0f }; const float start { 1.0f };
std::vector<float> outputScalar(bigBufferSize); std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize); std::vector<float> outputSIMD(bigBufferSize);
multiplicativeRamp<float, false>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue); sfz::multiplicativeRamp<float, false>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue);
multiplicativeRamp<float, true>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue); sfz::multiplicativeRamp<float, true>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }
@ -596,7 +596,7 @@ TEST_CASE("[Helpers] Add")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> expected { 2.0, 3.0, 4.0, 5.0, 6.0 }; std::array<float, 5> expected { 2.0, 3.0, 4.0, 5.0, 6.0 };
add<float, false>(input, absl::MakeSpan(output)); sfz::add<float, false>(input, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -605,7 +605,7 @@ TEST_CASE("[Helpers] Add (SIMD)")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> expected { 2.0, 3.0, 4.0, 5.0, 6.0 }; std::array<float, 5> expected { 2.0, 3.0, 4.0, 5.0, 6.0 };
add<float, true>(input, absl::MakeSpan(output)); sfz::add<float, true>(input, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -618,8 +618,8 @@ TEST_CASE("[Helpers] Add (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0); absl::c_fill(outputScalar, 0.0);
absl::c_fill(outputSIMD, 0.0); absl::c_fill(outputSIMD, 0.0);
add<float, false>(input, absl::MakeSpan(outputScalar)); sfz::add<float, false>(input, absl::MakeSpan(outputScalar));
add<float, true>(input, absl::MakeSpan(outputSIMD)); sfz::add<float, true>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }
@ -628,7 +628,7 @@ TEST_CASE("[Helpers] Subtract")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> expected { 0.0, -1.0, -2.0, -3.0, -4.0 }; std::array<float, 5> expected { 0.0, -1.0, -2.0, -3.0, -4.0 };
subtract<float, false>(input, absl::MakeSpan(output)); sfz::subtract<float, false>(input, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -636,7 +636,7 @@ TEST_CASE("[Helpers] Subtract 2")
{ {
std::array<float, 5> output { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> output { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> expected { 0.0, 1.0, 2.0, 3.0, 4.0 }; std::array<float, 5> expected { 0.0, 1.0, 2.0, 3.0, 4.0 };
subtract<float, false>(1.0f, absl::MakeSpan(output)); sfz::subtract<float, false>(1.0f, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -646,7 +646,7 @@ TEST_CASE("[Helpers] Subtract (SIMD)")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> expected { 0.0, -1.0, -2.0, -3.0, -4.0 }; std::array<float, 5> expected { 0.0, -1.0, -2.0, -3.0, -4.0 };
subtract<float, true>(input, absl::MakeSpan(output)); sfz::subtract<float, true>(input, absl::MakeSpan(output));
REQUIRE(output == expected); REQUIRE(output == expected);
} }
@ -659,8 +659,8 @@ TEST_CASE("[Helpers] Subtract (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0); absl::c_fill(outputScalar, 0.0);
absl::c_fill(outputSIMD, 0.0); absl::c_fill(outputSIMD, 0.0);
subtract<float, false>(input, absl::MakeSpan(outputScalar)); sfz::subtract<float, false>(input, absl::MakeSpan(outputScalar));
subtract<float, true>(input, absl::MakeSpan(outputSIMD)); sfz::subtract<float, true>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }
@ -671,8 +671,8 @@ TEST_CASE("[Helpers] Subtract 2 (SIMD vs scalar)")
absl::c_iota(outputScalar, 0.0); absl::c_iota(outputScalar, 0.0);
absl::c_iota(outputSIMD, 0.0); absl::c_iota(outputSIMD, 0.0);
subtract<float, false>(1.2f, absl::MakeSpan(outputScalar)); sfz::subtract<float, false>(1.2f, absl::MakeSpan(outputScalar));
subtract<float, true>(1.2f, absl::MakeSpan(outputSIMD)); sfz::subtract<float, true>(1.2f, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }
@ -680,7 +680,7 @@ TEST_CASE("[Helpers] copy")
{ {
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
copy<float, false>(input, absl::MakeSpan(output)); sfz::copy<float, false>(input, absl::MakeSpan(output));
REQUIRE(output == input); REQUIRE(output == input);
} }
@ -688,7 +688,7 @@ TEST_CASE("[Helpers] copy (SIMD)")
{ {
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
copy<float, true>(input, absl::MakeSpan(output)); sfz::copy<float, true>(input, absl::MakeSpan(output));
REQUIRE(output == input); REQUIRE(output == input);
} }
@ -701,37 +701,37 @@ TEST_CASE("[Helpers] copy (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0); absl::c_fill(outputScalar, 0.0);
absl::c_fill(outputSIMD, 0.0); absl::c_fill(outputSIMD, 0.0);
add<float, false>(input, absl::MakeSpan(outputScalar)); sfz::add<float, false>(input, absl::MakeSpan(outputScalar));
add<float, true>(input, absl::MakeSpan(outputSIMD)); sfz::add<float, true>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }
TEST_CASE("[Helpers] Mean") TEST_CASE("[Helpers] Mean")
{ {
std::array<float, 10> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f }; std::array<float, 10> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f };
REQUIRE(mean<float, false>(input) == 5.5f); REQUIRE(sfz::mean<float, false>(input) == 5.5f);
REQUIRE(mean<float, true>(input) == 5.5f); REQUIRE(sfz::mean<float, true>(input) == 5.5f);
} }
TEST_CASE("[Helpers] Mean (SIMD vs scalar)") TEST_CASE("[Helpers] Mean (SIMD vs scalar)")
{ {
std::vector<float> input(bigBufferSize); std::vector<float> input(bigBufferSize);
absl::c_iota(input, 0.0); absl::c_iota(input, 0.0);
REQUIRE(mean<float, false>(input) == Approx(mean<float, true>(input)).margin(0.001)); REQUIRE(sfz::mean<float, false>(input) == Approx(sfz::mean<float, true>(input)).margin(0.001));
} }
TEST_CASE("[Helpers] Mean Squared") TEST_CASE("[Helpers] Mean Squared")
{ {
std::array<float, 10> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f }; std::array<float, 10> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f };
REQUIRE(meanSquared<float, false>(input) == 38.5f); REQUIRE(sfz::meanSquared<float, false>(input) == 38.5f);
REQUIRE(meanSquared<float, true>(input) == 38.5f); REQUIRE(sfz::meanSquared<float, true>(input) == 38.5f);
} }
TEST_CASE("[Helpers] Mean Squared (SIMD vs scalar)") TEST_CASE("[Helpers] Mean Squared (SIMD vs scalar)")
{ {
std::vector<float> input(medBufferSize); std::vector<float> input(medBufferSize);
absl::c_iota(input, 0.0); absl::c_iota(input, 0.0);
REQUIRE(meanSquared<float, false>(input) == meanSquared<float, true>(input)); REQUIRE(sfz::meanSquared<float, false>(input) == sfz::meanSquared<float, true>(input));
} }
TEST_CASE("[Helpers] Cumulative sum ") TEST_CASE("[Helpers] Cumulative sum ")
@ -739,7 +739,7 @@ TEST_CASE("[Helpers] Cumulative sum ")
std::array<float, 6> input { 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f }; // 1.1 2.3 3.6 5.0 6.5 8.1 std::array<float, 6> input { 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f }; // 1.1 2.3 3.6 5.0 6.5 8.1
std::array<float, 6> output; std::array<float, 6> output;
std::array<float, 6> expected { 1.1f, 2.3f, 3.6f, 5.0f, 6.5f, 8.1f }; std::array<float, 6> expected { 1.1f, 2.3f, 3.6f, 5.0f, 6.5f, 8.1f };
cumsum<float, false>(input, absl::MakeSpan(output)); sfz::cumsum<float, false>(input, absl::MakeSpan(output));
REQUIRE(approxEqual<float>(output, expected)); REQUIRE(approxEqual<float>(output, expected));
} }
@ -748,9 +748,9 @@ TEST_CASE("[Helpers] Cumulative sum (SIMD vs Scalar)")
std::vector<float> input(bigBufferSize); std::vector<float> input(bigBufferSize);
std::vector<float> outputScalar(bigBufferSize); std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize); std::vector<float> outputSIMD(bigBufferSize);
linearRamp<float>(absl::MakeSpan(input), 0.0, 0.1); sfz::linearRamp<float>(absl::MakeSpan(input), 0.0, 0.1);
cumsum<float, false>(input, absl::MakeSpan(outputScalar)); sfz::cumsum<float, false>(input, absl::MakeSpan(outputScalar));
cumsum<float, true>(input, absl::MakeSpan(outputSIMD)); sfz::cumsum<float, true>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }
@ -759,7 +759,7 @@ TEST_CASE("[Helpers] Diff ")
std::array<float, 6> input { 1.1f, 2.3f, 3.6f, 5.0f, 6.5f, 8.1f }; std::array<float, 6> input { 1.1f, 2.3f, 3.6f, 5.0f, 6.5f, 8.1f };
std::array<float, 6> output; std::array<float, 6> output;
std::array<float, 6> expected { 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f }; std::array<float, 6> expected { 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f };
diff<float, false>(input, absl::MakeSpan(output)); sfz::diff<float, false>(input, absl::MakeSpan(output));
REQUIRE(approxEqual<float>(output, expected)); REQUIRE(approxEqual<float>(output, expected));
} }
@ -768,8 +768,8 @@ TEST_CASE("[Helpers] Diff (SIMD vs Scalar)")
std::vector<float> input(bigBufferSize); std::vector<float> input(bigBufferSize);
std::vector<float> outputScalar(bigBufferSize); std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize); std::vector<float> outputSIMD(bigBufferSize);
linearRamp<float>(absl::MakeSpan(input), 0.0, 0.1); sfz::linearRamp<float>(absl::MakeSpan(input), 0.0, 0.1);
diff<float, false>(input, absl::MakeSpan(outputScalar)); sfz::diff<float, false>(input, absl::MakeSpan(outputScalar));
diff<float, true>(input, absl::MakeSpan(outputSIMD)); sfz::diff<float, true>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD)); REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
} }

View file

@ -1,208 +0,0 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "StereoBuffer.h"
#include "catch2/catch.hpp"
#include <algorithm>
using namespace Catch::literals;
TEST_CASE("[StereoBuffer] Empty buffers")
{
StereoBuffer<float> floatBuffer;
REQUIRE(floatBuffer.empty());
REQUIRE(floatBuffer.getNumFrames() == 0);
StereoBuffer<double> doubleBuffer;
REQUIRE(doubleBuffer.empty());
REQUIRE(doubleBuffer.getNumFrames() == 0);
StereoBuffer<int> intBuffer;
REQUIRE(intBuffer.empty());
REQUIRE(intBuffer.getNumFrames() == 0);
}
TEST_CASE("[StereoBuffer] Non-empty")
{
StereoBuffer<float> floatBuffer(10);
REQUIRE(!floatBuffer.empty());
REQUIRE(floatBuffer.getNumFrames() == 10);
StereoBuffer<double> doubleBuffer(10);
REQUIRE(!doubleBuffer.empty());
REQUIRE(doubleBuffer.getNumFrames() == 10);
StereoBuffer<int> intBuffer(10);
REQUIRE(!intBuffer.empty());
REQUIRE(intBuffer.getNumFrames() == 10);
}
TEST_CASE("[StereoBuffer] Access")
{
const int size { 5 };
StereoBuffer<double> doubleBuffer(size);
for (auto frameIdx = 0; frameIdx < doubleBuffer.getNumFrames(); ++frameIdx) {
doubleBuffer.getSample(Channel::left, frameIdx) = static_cast<double>(doubleBuffer.getNumFrames()) + frameIdx;
doubleBuffer.getSample(Channel::right, frameIdx) = static_cast<double>(doubleBuffer.getNumFrames()) - frameIdx;
}
for (auto frameIdx = 0; frameIdx < doubleBuffer.getNumFrames(); ++frameIdx) {
REQUIRE(doubleBuffer.getSample(Channel::left, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) + frameIdx);
REQUIRE(doubleBuffer(Channel::left, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) + frameIdx);
REQUIRE(doubleBuffer.getSample(Channel::right, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) - frameIdx);
REQUIRE(doubleBuffer(Channel::right, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) - frameIdx);
}
}
TEST_CASE("[StereoBuffer] Iterators")
{
const int size { 256 };
const float fillValue { 2.0f };
StereoBuffer<float> buffer(size);
std::fill(buffer.begin(Channel::left), buffer.end(Channel::left), fillValue);
std::fill(buffer.begin(Channel::right), buffer.end(Channel::right), fillValue);
REQUIRE(std::all_of(buffer.begin(Channel::left), buffer.end(Channel::left), [fillValue](auto value) { return value == fillValue; }));
REQUIRE(std::all_of(buffer.begin(Channel::right), buffer.end(Channel::right), [fillValue](auto value) { return value == fillValue; }));
}
template <class Type, unsigned int Alignment = 16>
void channelAlignmentTest(int size)
{
static constexpr auto AlignmentMask { Alignment - 1 };
StereoBuffer<Type, Alignment> buffer(size);
REQUIRE(((size_t)buffer.getChannel(Channel::left) & AlignmentMask) == 0);
REQUIRE(((size_t)buffer.getChannel(Channel::right) & AlignmentMask) == 0);
}
TEST_CASE("[StereoBuffer] Channel alignments (floats)")
{
channelAlignmentTest<float>(4);
channelAlignmentTest<float>(5);
channelAlignmentTest<float>(8);
channelAlignmentTest<float>(256);
channelAlignmentTest<float>(257);
channelAlignmentTest<float>(1023);
channelAlignmentTest<float>(1024);
channelAlignmentTest<float>(65537);
channelAlignmentTest<float>(65536);
channelAlignmentTest<float>(65535);
channelAlignmentTest<float, 4>(4);
channelAlignmentTest<float, 4>(5);
channelAlignmentTest<float, 4>(8);
channelAlignmentTest<float, 4>(256);
channelAlignmentTest<float, 4>(257);
channelAlignmentTest<float, 4>(1023);
channelAlignmentTest<float, 4>(1024);
channelAlignmentTest<float, 4>(65537);
channelAlignmentTest<float, 4>(65536);
channelAlignmentTest<float, 4>(65535);
channelAlignmentTest<float, 8>(4);
channelAlignmentTest<float, 8>(5);
channelAlignmentTest<float, 8>(8);
channelAlignmentTest<float, 8>(256);
channelAlignmentTest<float, 8>(257);
channelAlignmentTest<float, 8>(1023);
channelAlignmentTest<float, 8>(1024);
channelAlignmentTest<float, 8>(65537);
channelAlignmentTest<float, 8>(65536);
channelAlignmentTest<float, 8>(65535);
}
TEST_CASE("[StereoBuffer] Channel alignments (doubles)")
{
channelAlignmentTest<double>(4);
channelAlignmentTest<double>(5);
channelAlignmentTest<double>(8);
channelAlignmentTest<double>(256);
channelAlignmentTest<double>(257);
channelAlignmentTest<double>(1023);
channelAlignmentTest<double>(1024);
channelAlignmentTest<double>(65537);
channelAlignmentTest<double>(65536);
channelAlignmentTest<double>(65535);
channelAlignmentTest<double, 8>(4);
channelAlignmentTest<double, 8>(5);
channelAlignmentTest<double, 8>(8);
channelAlignmentTest<double, 8>(256);
channelAlignmentTest<double, 8>(257);
channelAlignmentTest<double, 8>(1023);
channelAlignmentTest<double, 8>(1024);
channelAlignmentTest<double, 8>(65537);
channelAlignmentTest<double, 8>(65536);
channelAlignmentTest<double, 8>(65535);
}
TEST_CASE("[AudioBuffer] fills")
{
StereoBuffer<float> buffer(10);
buffer.fill(1.3f);
std::array<float, 10> expected;
std::fill(expected.begin(), expected.end(), 1.3f);
std::array<float, 10> real { 0.0f };
for (auto frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx)
real[frameIdx] = buffer(Channel::left, frameIdx);
REQUIRE(real == expected);
for (auto frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx)
real[frameIdx] = buffer(Channel::right, frameIdx);
REQUIRE(real == expected);
}
TEST_CASE("[AudioBuffer] Fill a big Audiobuffer")
{
constexpr int size { 2039247 };
StereoBuffer<float> buffer(size);
std::vector<float> input(2 * size);
std::iota(input.begin(), input.end(), 1.0f);
buffer.readInterleaved(input);
}
TEST_CASE("[StereoBuffer] Interleaved write -- Scalar")
{
StereoBuffer<float> buffer(10);
std::array<float, 20> input = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f };
std::array<float, 20> output { 0.0f };
buffer.readInterleaved(input);
buffer.writeInterleaved(absl::MakeSpan(output));
REQUIRE(output == input);
}
TEST_CASE("[StereoBuffer] Interleaved write -- SIMD")
{
StereoBuffer<float> buffer(10);
std::array<float, 20> input = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f, 8.0f, 18.0f, 9.0f, 19.0f };
std::array<float, 20> output { 0.0f };
buffer.readInterleaved(input);
buffer.writeInterleaved(absl::MakeSpan(output));
REQUIRE(output == input);
}
TEST_CASE("[StereoBuffer] Small interleaved write -- SIMD")
{
StereoBuffer<float> buffer(3);
std::array<float, 6> input = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f };
std::array<float, 6> output { 0.0f };
buffer.readInterleaved(input);
buffer.writeInterleaved(absl::MakeSpan(output));
REQUIRE(output == input);
}