Moved everyone into the sfz namespace to avoid clashing when importing the lib

This commit is contained in:
paulfd 2019-09-25 23:48:52 +02:00
parent 92ba5f6036
commit d3280b5a29
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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));
output = std::vector<float>(state.range(0));
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]]) {
@ -54,28 +54,28 @@ public:
BENCHMARK_DEFINE_F(DiffArray, Diff_Scalar)(benchmark::State& 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) {
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) {
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) {
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>
static void Dummy(benchmark::State& state) {
Buffer<float> buffer (state.range(0));
sfz::Buffer<float> buffer (state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
@ -40,42 +40,42 @@ static void Dummy(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::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
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) {
Buffer<float> buffer (state.range(0));
sfz::Buffer<float> buffer (state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
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) {
Buffer<float> buffer (state.range(0));
sfz::Buffer<float> buffer (state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
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) {
Buffer<float> buffer (state.range(0));
sfz::Buffer<float> buffer (state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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)
{
for (auto _ : state) {
exp<float, false>(source, absl::MakeSpan(result));
sfz::exp<float, false>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result);
}
}
@ -73,7 +73,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDExp)
(benchmark::State& state)
{
for (auto _ : state) {
exp<float, true>(source, absl::MakeSpan(result));
sfz::exp<float, true>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result);
}
}
@ -82,7 +82,7 @@ BENCHMARK_DEFINE_F(MyFixture, ScalarExp_Unaligned)
(benchmark::State& 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);
}
}
@ -91,7 +91,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDExp_Unaligned)
(benchmark::State& 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);
}
}
@ -100,7 +100,7 @@ BENCHMARK_DEFINE_F(MyFixture, ScalarLog)
(benchmark::State& state)
{
for (auto _ : state) {
log<float, false>(source, absl::MakeSpan(result));
sfz::log<float, false>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result);
}
}
@ -109,7 +109,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDLog)
(benchmark::State& state)
{
for (auto _ : state) {
log<float, true>(source, absl::MakeSpan(result));
sfz::log<float, true>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result);
}
}
@ -118,7 +118,7 @@ BENCHMARK_DEFINE_F(MyFixture, ScalarSin)
(benchmark::State& state)
{
for (auto _ : state) {
sin<float, false>(source, absl::MakeSpan(result));
sfz::sin<float, false>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result);
}
}
@ -127,7 +127,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDSin)
(benchmark::State& state)
{
for (auto _ : state) {
sin<float, true>(source, absl::MakeSpan(result));
sfz::sin<float, true>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result);
}
}
@ -136,7 +136,7 @@ BENCHMARK_DEFINE_F(MyFixture, ScalarCos)
(benchmark::State& state)
{
for (auto _ : state) {
cos<float, false>(source, absl::MakeSpan(result));
sfz::cos<float, false>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result);
}
}
@ -145,7 +145,7 @@ BENCHMARK_DEFINE_F(MyFixture, SIMDCos)
(benchmark::State& state)
{
for (auto _ : state) {
cos<float, true>(source, absl::MakeSpan(result));
sfz::cos<float, true>(source, absl::MakeSpan(result));
benchmark::DoNotOptimize(result);
}
}

View file

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

View file

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

View file

@ -63,28 +63,28 @@ BENCHMARK_DEFINE_F(MultiplyAdd, Straight)(benchmark::State& state) {
BENCHMARK_DEFINE_F(MultiplyAdd, Scalar)(benchmark::State& 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) {
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) {
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) {
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) {
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) {
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) {
for (auto _ : state)
{
::fill<float>(span2, 1.0f);
::add<float>(span1, span2);
::applyGain<float>(piFour<float>, span2);
::cos<float>(span2, span1);
::sin<float>(span2, span2);
::applyGain<float>(span1, absl::MakeSpan(left));
::applyGain<float>(span2, absl::MakeSpan(right));
sfz::fill<float>(span2, 1.0f);
sfz::add<float>(span1, span2);
sfz::applyGain<float>(piFour<float>, span2);
sfz::cos<float>(span2, span1);
sfz::sin<float>(span2, span2);
sfz::applyGain<float>(span1, absl::MakeSpan(left));
sfz::applyGain<float>(span2, absl::MakeSpan(right));
}
}

View file

@ -42,7 +42,7 @@ public:
jumps.resize(state.range(0));
offsets.resize(state.range(0));
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]]) {
@ -58,7 +58,7 @@ public:
BENCHMARK_DEFINE_F(IterOffset, Pointers)(benchmark::State& state) {
for (auto _ : state)
{
diff<int>(offsets, absl::MakeSpan(jumps));
sfz::diff<int>(offsets, absl::MakeSpan(jumps));
auto jump = jumps.begin();
auto in = source.begin();
auto out = result.begin();

View file

@ -28,7 +28,7 @@
static void Dummy(benchmark::State& state) {
Buffer<float> output(state.range(0));
sfz::Buffer<float> output(state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
@ -40,96 +40,96 @@ static void Dummy(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::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state)
{
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) {
Buffer<float> output(state.range(0));
sfz::Buffer<float> output(state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state)
{
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) {
Buffer<float> output(state.range(0));
sfz::Buffer<float> output(state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state)
{
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) {
Buffer<float> output(state.range(0));
sfz::Buffer<float> output(state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state)
{
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) {
Buffer<float> output(state.range(0));
sfz::Buffer<float> output(state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state)
{
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) {
Buffer<float> output(state.range(0));
sfz::Buffer<float> output(state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state)
{
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) {
Buffer<float> output(state.range(0));
sfz::Buffer<float> output(state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state)
{
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) {
Buffer<float> output(state.range(0));
sfz::Buffer<float> output(state.range(0));
std::random_device rd { };
std::mt19937 gen { rd() };
std::uniform_real_distribution<float> dist { 1, 2 };
for (auto _ : state)
{
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>
static void Scalar(benchmark::State& state) {
Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0));
sfz::Buffer<float> input (state.range(0) * 2);
sfz::Buffer<float> outputLeft (state.range(0));
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
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) {
Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0));
sfz::Buffer<float> input (state.range(0) * 2);
sfz::Buffer<float> outputLeft (state.range(0));
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
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) {
Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0));
sfz::Buffer<float> input (state.range(0) * 2);
sfz::Buffer<float> outputLeft (state.range(0));
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
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) {
Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0));
sfz::Buffer<float> input (state.range(0) * 2);
sfz::Buffer<float> outputLeft (state.range(0));
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
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) {
Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0));
sfz::Buffer<float> input (state.range(0) * 2);
sfz::Buffer<float> outputLeft (state.range(0));
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
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) {
Buffer<float> input (state.range(0) * 2);
Buffer<float> outputLeft (state.range(0));
Buffer<float> outputRight (state.range(0));
sfz::Buffer<float> input (state.range(0) * 2);
sfz::Buffer<float> outputLeft (state.range(0));
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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>
static void Interleaved_Write(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2);
sfz::Buffer<float> inputLeft (state.range(0));
sfz::Buffer<float> inputRight (state.range(0));
sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
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) {
Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2);
sfz::Buffer<float> inputLeft (state.range(0));
sfz::Buffer<float> inputRight (state.range(0));
sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) {
writeInterleaved<float, true>(inputLeft, inputRight, absl::MakeSpan(output));
sfz::writeInterleaved<float, true>(inputLeft, inputRight, absl::MakeSpan(output));
benchmark::DoNotOptimize(output);
}
}
static void Unaligned_Interleaved_Write(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2);
sfz::Buffer<float> inputLeft (state.range(0));
sfz::Buffer<float> inputRight (state.range(0));
sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
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);
}
}
static void Unaligned_Interleaved_Write_SSE(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2);
sfz::Buffer<float> inputLeft (state.range(0));
sfz::Buffer<float> inputRight (state.range(0));
sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
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);
}
}
static void Unaligned_Interleaved_Write_2(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2);
sfz::Buffer<float> inputLeft (state.range(0));
sfz::Buffer<float> inputRight (state.range(0));
sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
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);
}
}
static void Unaligned_Interleaved_Write_SSE_2(benchmark::State& state) {
Buffer<float> inputLeft (state.range(0));
Buffer<float> inputRight (state.range(0));
Buffer<float> output (state.range(0) * 2);
sfz::Buffer<float> inputLeft (state.range(0));
sfz::Buffer<float> inputRight (state.range(0));
sfz::Buffer<float> output (state.range(0) * 2);
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
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);
}
}

View file

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

View file

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

View file

@ -32,6 +32,8 @@
#include <initializer_list>
#include <type_traits>
namespace sfz
{
template <class Type, unsigned int MaxChannels = sfz::config::numChannels>
class AudioSpan {
public:
@ -137,26 +139,26 @@ public:
return 0.0;
Type result = 0.0;
for (int i = 0; i < numChannels; ++i)
result += ::meanSquared<Type>(getConstSpan(i));
result += sfz::meanSquared<Type>(getConstSpan(i));
return result / numChannels;
}
void fill(Type value) noexcept
{
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
{
for (int i = 0; i < numChannels; ++i)
::applyGain<Type>(gain, getSpan(i));
sfz::applyGain<Type>(gain, getSpan(i));
}
void applyGain(Type gain) noexcept
{
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>>
@ -165,7 +167,7 @@ public:
ASSERT(other.getNumChannels() == numChannels);
if (other.getNumChannels() == numChannels) {
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);
if (other.getNumChannels() == numChannels) {
for (int i = 0; i < numChannels; ++i)
::copy<Type>(other.getConstSpan(i), getSpan(i));
sfz::copy<Type>(other.getConstSpan(i), getSpan(i));
}
}
@ -217,4 +219,5 @@ private:
std::array<Type*, MaxChannels> spans;
size_type numFrames { 0 };
int numChannels { 0 };
};
};
}

View file

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

View file

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

View file

@ -35,15 +35,15 @@
using namespace std::chrono_literals;
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) {
sndFile.readf(returnedBuffer->channelWriter(0), numFrames);
} 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);
::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;
}
@ -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.
// 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 ?
// 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());
}
returnedValue.preloadedData = alreadyPreloaded;

View file

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

View file

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

View file

@ -24,153 +24,153 @@
#include "SIMDHelpers.h"
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}

View file

@ -29,6 +29,8 @@
#include <absl/types/span.h>
#include <cmath>
namespace sfz
{
template <class T>
inline void snippetRead(const T*& input, T*& outputLeft, T*& outputRight)
{
@ -569,4 +571,6 @@ void diff(absl::Span<const T> input, absl::Span<T> output) noexcept
}
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 <>
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...
ASSERT(outputLeft.size() >= input.size() / 2);
@ -116,7 +116,7 @@ void readInterleaved<float, true>(absl::Span<const float> input, absl::Span<floa
}
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...
ASSERT(inputLeft.size() <= output.size() / 2);
@ -153,7 +153,7 @@ void writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span
}
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);
auto* out = output.begin();
@ -173,7 +173,7 @@ void fill<float, true>(absl::Span<float> output, float value) noexcept
}
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());
auto* in = input.begin();
@ -195,7 +195,7 @@ void exp<float, true>(absl::Span<const float> input, absl::Span<float> output) n
}
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());
auto* in = input.begin();
@ -217,7 +217,7 @@ void cos<float, true>(absl::Span<const float> input, absl::Span<float> output) n
}
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());
auto* in = input.begin();
@ -239,7 +239,7 @@ void log<float, true>(absl::Span<const float> input, absl::Span<float> output) n
}
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());
auto* in = input.begin();
@ -261,7 +261,7 @@ void sin<float, true>(absl::Span<const float> input, absl::Span<float> output) n
}
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* out = output.begin();
@ -283,7 +283,7 @@ void applyGain<float, true>(float gain, absl::Span<const float> input, absl::Spa
}
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* out = output.begin();
@ -306,7 +306,7 @@ void applyGain<float, true>(absl::Span<const float> gain, absl::Span<const float
}
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* out = output.begin();
@ -331,7 +331,7 @@ void multiplyAdd<float, true>(absl::Span<const float> gain, absl::Span<const flo
}
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> rightCoeffs,
absl::Span<int> indices,
@ -393,7 +393,7 @@ float loopingSFZIndex<float, true>(absl::Span<const float> jumps,
}
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> rightCoeffs,
absl::Span<int> indices,
@ -451,7 +451,7 @@ float saturatingSFZIndex<float, true>(absl::Span<const float> jumps,
}
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();
const auto* lastAligned = prevAligned(output.end());
@ -476,7 +476,7 @@ float linearRamp<float, true>(absl::Span<float> output, float value, float step)
}
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();
const auto* lastAligned = prevAligned(output.end());
@ -501,7 +501,7 @@ float multiplicativeRamp<float, true>(absl::Span<float> output, float value, flo
}
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());
auto* in = input.begin();
@ -523,7 +523,7 @@ void add<float, true>(absl::Span<const float> input, absl::Span<float> output) n
}
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* sentinel = output.end();
@ -543,7 +543,7 @@ void add<float, true>(float value, absl::Span<float> output) noexcept
}
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());
auto* in = input.begin();
@ -565,7 +565,7 @@ void subtract<float, true>(absl::Span<const float> input, absl::Span<float> outp
}
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* sentinel = output.end();
@ -585,7 +585,7 @@ void subtract<float, true>(const float value, absl::Span<float> output) noexcept
}
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());
auto* in = input.begin();
@ -607,7 +607,7 @@ void copy<float, true>(absl::Span<const float> input, absl::Span<float> output)
}
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(rightBuffer.size() >= panEnvelope.size());
@ -643,7 +643,7 @@ void pan<float, true>(absl::Span<const float> panEnvelope, absl::Span<float> lef
}
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 };
if (vector.size() == 0)
@ -675,7 +675,7 @@ float mean<float, true>(absl::Span<const float> vector) noexcept
}
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 };
if (vector.size() == 0)
@ -712,7 +712,7 @@ float meanSquared<float, true>(absl::Span<const float> vector) noexcept
}
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());
if (input.size() == 0)
@ -744,7 +744,7 @@ void cumsum<float, true>(absl::Span<const float> input, absl::Span<float> output
}
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() == leftCoeffs.size());
@ -780,7 +780,7 @@ void sfzInterpolationCast<float, true>(absl::Span<const float> floatJumps, absl:
}
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());
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
amplitudeEnvelope.getBlock(span1);
::applyGain<float>(span1, leftBuffer);
applyGain<float>(span1, leftBuffer);
// AmpEG envelope
egEnvelope.getBlock(span1);
::applyGain<float>(span1, leftBuffer);
applyGain<float>(span1, leftBuffer);
// Volume envelope
volumeEnvelope.getBlock(span1);
::applyGain<float>(span1, leftBuffer);
applyGain<float>(span1, leftBuffer);
// Prepare for stereo output
::copy<float>(leftBuffer, rightBuffer);
copy<float>(leftBuffer, rightBuffer);
panEnvelope.getBlock(span1);
// 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
::fill<float>(span2, 1.0f);
::add<float>(span1, span2);
::applyGain<float>(piFour<float>, span2);
::cos<float>(span2, span1);
::sin<float>(span2, span2);
::applyGain<float>(span1, leftBuffer);
::applyGain<float>(span2, rightBuffer);
fill<float>(span2, 1.0f);
add<float>(span1, span2);
applyGain<float>(piFour<float>, span2);
cos<float>(span2, span1);
sin<float>(span2, span2);
applyGain<float>(span1, leftBuffer);
applyGain<float>(span2, rightBuffer);
}
void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept
@ -310,36 +310,36 @@ void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept
buffer.applyGain(span1);
// Create mid/side from left/right in the output buffer
::copy<float>(rightBuffer, span1);
::add<float>(leftBuffer, rightBuffer);
::subtract<float>(span1, leftBuffer);
::applyGain<float>(sqrtTwoInv<float>, leftBuffer);
::applyGain<float>(sqrtTwoInv<float>, rightBuffer);
copy<float>(rightBuffer, span1);
add<float>(leftBuffer, rightBuffer);
subtract<float>(span1, leftBuffer);
applyGain<float>(sqrtTwoInv<float>, leftBuffer);
applyGain<float>(sqrtTwoInv<float>, rightBuffer);
// Apply the width process
widthEnvelope.getBlock(span1);
::fill<float>(span2, 1.0f);
::add<float>(span1, span2);
::applyGain<float>(piFour<float>, span2);
::cos<float>(span2, span1);
::sin<float>(span2, span2);
::applyGain<float>(span1, leftBuffer);
::applyGain<float>(span2, rightBuffer);
fill<float>(span2, 1.0f);
add<float>(span1, span2);
applyGain<float>(piFour<float>, span2);
cos<float>(span2, span1);
sin<float>(span2, span2);
applyGain<float>(span1, leftBuffer);
applyGain<float>(span2, rightBuffer);
// Apply a position to the "left" channel which is supposed to be our mid channel
// TODO: add panning here too?
positionEnvelope.getBlock(span1);
::fill<float>(span2, 1.0f);
::add<float>(span1, span2);
::applyGain<float>(piFour<float>, span2);
::cos<float>(span2, span1);
::sin<float>(span2, span2);
::copy<float>(leftBuffer, span3);
::copy<float>(rightBuffer, leftBuffer);
::multiplyAdd<float>(span1, span3, leftBuffer);
::multiplyAdd<float>(span2, span3, rightBuffer);
::applyGain<float>(sqrtTwoInv<float>, leftBuffer);
::applyGain<float>(sqrtTwoInv<float>, rightBuffer);
fill<float>(span2, 1.0f);
add<float>(span1, span2);
applyGain<float>(piFour<float>, span2);
cos<float>(span2, span1);
sin<float>(span2, span2);
copy<float>(leftBuffer, span3);
copy<float>(rightBuffer, leftBuffer);
multiplyAdd<float>(span1, span3, leftBuffer);
multiplyAdd<float>(span2, span3, rightBuffer);
applyGain<float>(sqrtTwoInv<float>, leftBuffer);
applyGain<float>(sqrtTwoInv<float>, rightBuffer);
}
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 rightCoeffs = tempSpan2.first(buffer.getNumFrames());
::fill<float>(jumps, pitchRatio * speedRatio);
fill<float>(jumps, pitchRatio * speedRatio);
jumps[0] += floatPositionOffset;
::cumsum<float>(jumps, jumps);
::sfzInterpolationCast<float>(jumps, indices, leftCoeffs, rightCoeffs);
::add<int>(sourcePosition, indices);
cumsum<float>(jumps, jumps);
sfzInterpolationCast<float>(jumps, indices, leftCoeffs, rightCoeffs);
add<int>(sourcePosition, indices);
//FIXME : all this casting is driving me crazy
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) {
if (*index > sampleEnd) {
const auto remainingElements = static_cast<size_t>(std::distance(index, indices.end()));
::subtract<int>(offset, { index, remainingElements });
subtract<int>(offset, { index, remainingElements });
}
}
} else {
for (auto* index = indices.begin(); index < indices.end(); ++index) {
if (*index > sampleEnd) {
const auto remainingElements = static_cast<size_t>(std::distance(index, indices.end()));
::fill<int>(indices.last(remainingElements), sampleEnd);
::fill<float>(leftCoeffs.last(remainingElements), 0.0f);
::fill<float>(rightCoeffs.last(remainingElements), 1.0f);
fill<int>(indices.last(remainingElements), sampleEnd);
fill<float>(leftCoeffs.last(remainingElements), 0.0f);
fill<float>(rightCoeffs.last(remainingElements), 1.0f);
break;
}
}
@ -430,10 +430,10 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
return;
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));
::copy<float>(buffer.getSpan(0), buffer.getSpan(1));
sin<float>(tempSpan1.first(buffer.getNumFrames()), buffer.getSpan(0));
copy<float>(buffer.getSpan(0), buffer.getSpan(1));
// Wrap the phase so we don't loose too much precision on longer notes
const auto numTwoPiWraps = static_cast<int>(phase / twoPi<float>);

View file

@ -29,28 +29,28 @@ using namespace Catch::literals;
TEST_CASE("[AudioBuffer] Empty buffers")
{
AudioBuffer<float> floatBuffer;
sfz::AudioBuffer<float> floatBuffer;
REQUIRE(floatBuffer.empty());
REQUIRE(floatBuffer.getNumFrames() == 0);
AudioBuffer<double> doubleBuffer;
sfz::AudioBuffer<double> doubleBuffer;
REQUIRE(doubleBuffer.empty());
REQUIRE(doubleBuffer.getNumFrames() == 0);
AudioBuffer<int> intBuffer;
sfz::AudioBuffer<int> intBuffer;
REQUIRE(intBuffer.empty());
REQUIRE(intBuffer.getNumFrames() == 0);
}
TEST_CASE("[AudioBuffer] Non-empty")
{
AudioBuffer<float> floatBuffer(1, 10);
sfz::AudioBuffer<float> floatBuffer(1, 10);
REQUIRE(!floatBuffer.empty());
REQUIRE(floatBuffer.getNumFrames() == 10);
REQUIRE(floatBuffer.getNumChannels() == 1);
AudioBuffer<double> doubleBuffer(2, 10);
sfz::AudioBuffer<double> doubleBuffer(2, 10);
REQUIRE(!doubleBuffer.empty());
REQUIRE(doubleBuffer.getNumFrames() == 10);
REQUIRE(doubleBuffer.getNumChannels() == 2);
AudioBuffer<int> intBuffer(1, 10);
sfz::AudioBuffer<int> intBuffer(1, 10);
REQUIRE(!intBuffer.empty());
REQUIRE(intBuffer.getNumFrames() == 10);
REQUIRE(intBuffer.getNumChannels() == 1);
@ -59,7 +59,7 @@ TEST_CASE("[AudioBuffer] Non-empty")
TEST_CASE("[AudioBuffer] Access")
{
const int size { 5 };
AudioBuffer<float> buffer(2, size);
sfz::AudioBuffer<float> buffer(2, size);
for (size_t frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx) {
buffer.getSample(0, 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 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(1), buffer.channelWriterEnd(1), fillValue);
@ -89,14 +89,14 @@ TEST_CASE("[AudioSpan] Constructions")
{
const int size { 256 };
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(1), buffer.channelWriterEnd(1), fillValue);
AudioSpan<float> span { buffer };
AudioSpan<const float> constSpan { buffer };
AudioSpan<float> manualSpan { { buffer.channelWriter(0), buffer.channelWriter(1) }, buffer.getNumFrames() };
AudioSpan<const float> manualConstSpan { { buffer.channelReader(0), buffer.channelReader(1) }, buffer.getNumFrames() };
AudioSpan<float> manualSpan2 { {buffer.getSpan(0), buffer.getSpan(1) } };
AudioSpan<const float> manualConstSpan2 { {buffer.getConstSpan(0), buffer.getConstSpan(1) } };
sfz::AudioSpan<float> span { buffer };
sfz::AudioSpan<const float> constSpan { buffer };
sfz::AudioSpan<float> manualSpan { { buffer.channelWriter(0), buffer.channelWriter(1) }, buffer.getNumFrames() };
sfz::AudioSpan<const float> manualConstSpan { { buffer.channelReader(0), buffer.channelReader(1) }, buffer.getNumFrames() };
sfz::AudioSpan<float> manualSpan2 { {buffer.getSpan(0), buffer.getSpan(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)")
{
Buffer<float> emptyBuffer;
sfz::Buffer<float> emptyBuffer;
REQUIRE(emptyBuffer.empty());
REQUIRE(emptyBuffer.size() == 0);
}
TEST_CASE("[Buffer] Empty (int)")
{
Buffer<int> emptyBuffer;
sfz::Buffer<int> emptyBuffer;
REQUIRE(emptyBuffer.empty());
REQUIRE(emptyBuffer.size() == 0);
}
TEST_CASE("[Buffer] Empty (double)")
{
Buffer<double> emptyBuffer;
sfz::Buffer<double> emptyBuffer;
REQUIRE(emptyBuffer.empty());
REQUIRE(emptyBuffer.size() == 0);
}
TEST_CASE("[Buffer] Empty (uint8_t)")
{
Buffer<uint8_t> emptyBuffer;
sfz::Buffer<uint8_t> emptyBuffer;
REQUIRE(emptyBuffer.empty());
REQUIRE(emptyBuffer.size() == 0);
}
template <class Type>
void checkBoundaries(Buffer<Type>& buffer, int expectedSize)
void checkBoundaries(sfz::Buffer<Type>& buffer, int expectedSize)
{
REQUIRE((int)buffer.size() == expectedSize);
REQUIRE(((size_t)buffer.data() & (SIMDConfig::defaultAlignment - 1)) == 0);
REQUIRE(((size_t)buffer.alignedEnd() & (SIMDConfig::defaultAlignment - 1)) == 0);
REQUIRE(((size_t)buffer.data() & (sfz::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.alignedEnd()) >= expectedSize);
}
@ -67,7 +67,7 @@ void checkBoundaries(Buffer<Type>& buffer, int expectedSize)
TEST_CASE("[Buffer] 10 floats ")
{
const int baseSize { 10 };
Buffer<float> buffer(baseSize);
sfz::Buffer<float> buffer(baseSize);
checkBoundaries(buffer, baseSize);
for (auto& element : buffer)
@ -81,7 +81,7 @@ TEST_CASE("[Buffer] Resize 10 floats ")
const int baseSize { 10 };
const int smallSize { baseSize / 2 };
const int bigSize { baseSize * 2 };
Buffer<float> buffer(baseSize);
sfz::Buffer<float> buffer(baseSize);
REQUIRE(!buffer.empty());
checkBoundaries(buffer, baseSize);
@ -103,7 +103,7 @@ TEST_CASE("[Buffer] Resize 4096 floats ")
const int baseSize { 4096 };
const int smallSize { baseSize / 2 };
const int bigSize { baseSize * 2 };
Buffer<float> buffer(baseSize);
sfz::Buffer<float> buffer(baseSize);
REQUIRE(!buffer.empty());
checkBoundaries(buffer, baseSize);
@ -125,7 +125,7 @@ TEST_CASE("[Buffer] Resize 65536 floats ")
const int baseSize { 10 };
const int smallSize { baseSize / 2 };
const int bigSize { baseSize * 2 };
Buffer<float> buffer(baseSize);
sfz::Buffer<float> buffer(baseSize);
REQUIRE(!buffer.empty());
checkBoundaries(buffer, baseSize);
@ -145,19 +145,19 @@ TEST_CASE("[Buffer] Resize 65536 floats ")
TEST_CASE("[Buffer] Copy and move")
{
const int baseSize { 128 };
Buffer<float> buffer(baseSize);
Buffer<float> copied { baseSize - 4 };
sfz::Buffer<float> buffer(baseSize);
sfz::Buffer<float> copied { baseSize - 4 };
std::fill(buffer.begin(), buffer.end(), 1.0f);
std::fill(copied.begin(), copied.end(), 2.0f);
copied = buffer;
checkBoundaries(copied, baseSize);
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);
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());
checkBoundaries(moveConstructed, baseSize);
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
OpcodeT.cpp
BufferT.cpp
StereoBufferT.cpp
SIMDHelpersT.cpp
FilesT.cpp
OnePoleFilterT.cpp

View file

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

View file

@ -69,7 +69,7 @@ TEST_CASE("[Helpers] fill() - Manual buffer")
{
std::vector<float> buffer(5);
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);
}
@ -79,7 +79,7 @@ TEST_CASE("[Helpers] fill() - Small buffer")
std::vector<float> expected(smallBufferSize);
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);
}
@ -89,7 +89,7 @@ TEST_CASE("[Helpers] fill() - Big buffer")
std::vector<float> expected(bigBufferSize);
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);
}
@ -99,7 +99,7 @@ TEST_CASE("[Helpers] fill() - Small buffer -- SIMD")
std::vector<float> expected(smallBufferSize);
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);
}
@ -109,7 +109,7 @@ TEST_CASE("[Helpers] fill() - Big buffer -- SIMD")
std::vector<float> expected(bigBufferSize);
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);
}
@ -119,7 +119,7 @@ TEST_CASE("[Helpers] fill() - Small buffer -- doubles")
std::vector<double> expected(smallBufferSize);
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);
}
@ -129,7 +129,7 @@ TEST_CASE("[Helpers] fill() - Big buffer -- doubles")
std::vector<double> expected(bigBufferSize);
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);
}
@ -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, 8> leftOutput;
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;
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, 10> leftOutput;
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;
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, 3> leftOutput;
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;
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, 8> leftOutput;
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;
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, 10> leftOutput;
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;
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, 3> leftOutput;
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;
auto realIdx = 0;
@ -243,8 +243,8 @@ TEST_CASE("[Helpers] Interleaved read SIMD vs Scalar")
std::array<float, medBufferSize> leftOutputSIMD;
std::array<float, medBufferSize> rightOutputSIMD;
std::iota(input.begin(), input.end(), 0.0f);
readInterleaved<float, false>(input, absl::MakeSpan(leftOutputScalar), absl::MakeSpan(rightOutputScalar));
readInterleaved<float, true>(input, absl::MakeSpan(leftOutputSIMD), absl::MakeSpan(rightOutputSIMD));
sfz::readInterleaved<float, false>(input, absl::MakeSpan(leftOutputScalar), absl::MakeSpan(rightOutputScalar));
sfz::readInterleaved<float, true>(input, absl::MakeSpan(leftOutputSIMD), absl::MakeSpan(rightOutputSIMD));
REQUIRE(leftOutputScalar == leftOutputSIMD);
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, 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 };
writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output));
sfz::writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output));
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, 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 };
writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output));
sfz::writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(output));
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, 6> output;
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);
}
@ -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, 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 };
writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output));
sfz::writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output));
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, 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 };
writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output));
sfz::writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(output));
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, 6> output;
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);
}
@ -335,8 +335,8 @@ TEST_CASE("[Helpers] Interleaved write SIMD vs Scalar")
std::array<float, medBufferSize * 2> outputSIMD;
std::iota(leftInput.begin(), leftInput.end(), 0.0f);
std::iota(rightInput.begin(), rightInput.end(), medBufferSize);
writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(outputScalar));
writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(outputSIMD));
sfz::writeInterleaved<float, false>(leftInput, rightInput, absl::MakeSpan(outputScalar));
sfz::writeInterleaved<float, true>(leftInput, rightInput, absl::MakeSpan(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> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
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);
}
@ -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> 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);
}
@ -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> 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 };
applyGain<float, false>(gain, input, absl::MakeSpan(output));
sfz::applyGain<float, false>(gain, input, absl::MakeSpan(output));
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> 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 };
applyGain<float, false>(gain, buffer, absl::MakeSpan(buffer));
sfz::applyGain<float, false>(gain, buffer, absl::MakeSpan(buffer));
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> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
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);
}
@ -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> 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);
}
@ -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> 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 };
applyGain<float, true>(gain, input, absl::MakeSpan(output));
sfz::applyGain<float, true>(gain, input, absl::MakeSpan(output));
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> 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 };
applyGain<float, true>(gain, buffer, absl::MakeSpan(buffer));
sfz::applyGain<float, true>(gain, buffer, absl::MakeSpan(buffer));
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<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 };
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(approxEqual<float>(leftCoeffs, expectedLeft));
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<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 };
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(approxEqual<float>(leftCoeffs, expectedLeft));
REQUIRE(approxEqual<float>(rightCoeffs, expectedRight));
@ -455,8 +455,8 @@ TEST_CASE("[Helpers] SFZ looping index (SIMD)")
// std::vector<int> indicesSIMD(bigBufferSize);
// std::vector<float> leftCoeffsSIMD(bigBufferSize);
// std::vector<float> rightCoeffsSIMD(bigBufferSize);
// 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, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 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)
// 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))) );
@ -471,7 +471,7 @@ TEST_CASE("[Helpers] SFZ saturating index")
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> 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(approxEqual<float>(leftCoeffs, expectedLeft));
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<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 };
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(approxEqualMargin<float>(leftCoeffs, expectedLeft));
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<float> leftCoeffsSIMD(medBufferSize);
std::vector<float> rightCoeffsSIMD(medBufferSize);
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, false>(jumps, absl::MakeSpan(leftCoeffs), absl::MakeSpan(rightCoeffs), absl::MakeSpan(indices), 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)
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 };
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 };
linearRamp<float, false>(absl::MakeSpan(output), start, v);
sfz::linearRamp<float, false>(absl::MakeSpan(output), start, v);
REQUIRE(output == expected);
}
@ -527,7 +527,7 @@ TEST_CASE("[Helpers] Linear Ramp (SIMD)")
const float v { fillValue };
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 };
linearRamp<float, true>(absl::MakeSpan(output), start, v);
sfz::linearRamp<float, true>(absl::MakeSpan(output), start, v);
REQUIRE(approxEqual<float>(output, expected));
}
@ -536,8 +536,8 @@ TEST_CASE("[Helpers] Linear Ramp (SIMD vs scalar)")
const float start { 0.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
linearRamp<float, false>(absl::MakeSpan(outputScalar), start, fillValue);
linearRamp<float, true>(absl::MakeSpan(outputSIMD), start, fillValue);
sfz::linearRamp<float, false>(absl::MakeSpan(outputScalar), start, fillValue);
sfz::linearRamp<float, true>(absl::MakeSpan(outputSIMD), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -546,8 +546,8 @@ TEST_CASE("[Helpers] Linear Ramp unaligned (SIMD vs scalar)")
const float start { 0.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
linearRamp<float, false>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue);
linearRamp<float, true>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue);
sfz::linearRamp<float, false>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue);
sfz::linearRamp<float, true>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -557,7 +557,7 @@ TEST_CASE("[Helpers] Multiplicative Ramp")
const float v { fillValue };
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 };
multiplicativeRamp<float, false>(absl::MakeSpan(output), start, v);
sfz::multiplicativeRamp<float, false>(absl::MakeSpan(output), start, v);
REQUIRE(output == expected);
}
@ -567,7 +567,7 @@ TEST_CASE("[Helpers] Multiplicative Ramp (SIMD)")
const float v { fillValue };
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 };
multiplicativeRamp<float, true>(absl::MakeSpan(output), start, v);
sfz::multiplicativeRamp<float, true>(absl::MakeSpan(output), start, v);
REQUIRE(output == expected);
}
@ -576,8 +576,8 @@ TEST_CASE("[Helpers] Multiplicative Ramp (SIMD vs scalar)")
const float start { 1.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
multiplicativeRamp<float, false>(absl::MakeSpan(outputScalar), start, fillValue);
multiplicativeRamp<float, true>(absl::MakeSpan(outputSIMD), start, fillValue);
sfz::multiplicativeRamp<float, false>(absl::MakeSpan(outputScalar), start, fillValue);
sfz::multiplicativeRamp<float, true>(absl::MakeSpan(outputSIMD), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -586,8 +586,8 @@ TEST_CASE("[Helpers] Multiplicative Ramp unaligned (SIMD vs scalar)")
const float start { 1.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
multiplicativeRamp<float, false>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue);
multiplicativeRamp<float, true>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue);
sfz::multiplicativeRamp<float, false>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue);
sfz::multiplicativeRamp<float, true>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue);
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> 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 };
add<float, false>(input, absl::MakeSpan(output));
sfz::add<float, false>(input, absl::MakeSpan(output));
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> 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 };
add<float, true>(input, absl::MakeSpan(output));
sfz::add<float, true>(input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -618,8 +618,8 @@ TEST_CASE("[Helpers] Add (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0);
absl::c_fill(outputSIMD, 0.0);
add<float, false>(input, absl::MakeSpan(outputScalar));
add<float, true>(input, absl::MakeSpan(outputSIMD));
sfz::add<float, false>(input, absl::MakeSpan(outputScalar));
sfz::add<float, true>(input, absl::MakeSpan(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> 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 };
subtract<float, false>(input, absl::MakeSpan(output));
sfz::subtract<float, false>(input, absl::MakeSpan(output));
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> 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);
}
@ -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> 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 };
subtract<float, true>(input, absl::MakeSpan(output));
sfz::subtract<float, true>(input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -659,8 +659,8 @@ TEST_CASE("[Helpers] Subtract (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0);
absl::c_fill(outputSIMD, 0.0);
subtract<float, false>(input, absl::MakeSpan(outputScalar));
subtract<float, true>(input, absl::MakeSpan(outputSIMD));
sfz::subtract<float, false>(input, absl::MakeSpan(outputScalar));
sfz::subtract<float, true>(input, absl::MakeSpan(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(outputSIMD, 0.0);
subtract<float, false>(1.2f, absl::MakeSpan(outputScalar));
subtract<float, true>(1.2f, absl::MakeSpan(outputSIMD));
sfz::subtract<float, false>(1.2f, absl::MakeSpan(outputScalar));
sfz::subtract<float, true>(1.2f, absl::MakeSpan(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> 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);
}
@ -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> 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);
}
@ -701,37 +701,37 @@ TEST_CASE("[Helpers] copy (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0);
absl::c_fill(outputSIMD, 0.0);
add<float, false>(input, absl::MakeSpan(outputScalar));
add<float, true>(input, absl::MakeSpan(outputSIMD));
sfz::add<float, false>(input, absl::MakeSpan(outputScalar));
sfz::add<float, true>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
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 };
REQUIRE(mean<float, false>(input) == 5.5f);
REQUIRE(mean<float, true>(input) == 5.5f);
REQUIRE(sfz::mean<float, false>(input) == 5.5f);
REQUIRE(sfz::mean<float, true>(input) == 5.5f);
}
TEST_CASE("[Helpers] Mean (SIMD vs scalar)")
{
std::vector<float> input(bigBufferSize);
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")
{
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(meanSquared<float, true>(input) == 38.5f);
REQUIRE(sfz::meanSquared<float, false>(input) == 38.5f);
REQUIRE(sfz::meanSquared<float, true>(input) == 38.5f);
}
TEST_CASE("[Helpers] Mean Squared (SIMD vs scalar)")
{
std::vector<float> input(medBufferSize);
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 ")
@ -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> output;
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));
}
@ -748,9 +748,9 @@ TEST_CASE("[Helpers] Cumulative sum (SIMD vs Scalar)")
std::vector<float> input(bigBufferSize);
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
linearRamp<float>(absl::MakeSpan(input), 0.0, 0.1);
cumsum<float, false>(input, absl::MakeSpan(outputScalar));
cumsum<float, true>(input, absl::MakeSpan(outputSIMD));
sfz::linearRamp<float>(absl::MakeSpan(input), 0.0, 0.1);
sfz::cumsum<float, false>(input, absl::MakeSpan(outputScalar));
sfz::cumsum<float, true>(input, absl::MakeSpan(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> output;
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));
}
@ -768,8 +768,8 @@ TEST_CASE("[Helpers] Diff (SIMD vs Scalar)")
std::vector<float> input(bigBufferSize);
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
linearRamp<float>(absl::MakeSpan(input), 0.0, 0.1);
diff<float, false>(input, absl::MakeSpan(outputScalar));
diff<float, true>(input, absl::MakeSpan(outputSIMD));
sfz::linearRamp<float>(absl::MakeSpan(input), 0.0, 0.1);
sfz::diff<float, false>(input, absl::MakeSpan(outputScalar));
sfz::diff<float, true>(input, absl::MakeSpan(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);
}