-
-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into simpler-file-loading
- Loading branch information
Showing
72 changed files
with
3,314 additions
and
1,675 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// SPDX-License-Identifier: BSD-2-Clause | ||
|
||
// This code is part of the sfizz library and is licensed under a BSD 2-clause | ||
// license. You should have receive a LICENSE.md file along with the code. | ||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz | ||
|
||
#include "Panning.h" | ||
#include "simd/Common.h" | ||
#include <benchmark/benchmark.h> | ||
#include <random> | ||
#include <absl/algorithm/container.h> | ||
#include "absl/types/span.h" | ||
#include <arm_neon.h> | ||
|
||
#include <jsl/allocator> | ||
template <class T, std::size_t A = 16> | ||
using aligned_vector = std::vector<T, jsl::aligned_allocator<T, A>>; | ||
|
||
// Number of elements in the table, odd for equal volume at center | ||
constexpr int panSize = 4095; | ||
|
||
// Table of pan values for the left channel, extra element for safety | ||
static const auto panData = []() | ||
{ | ||
std::array<float, panSize + 1> pan; | ||
int i = 0; | ||
|
||
for (; i < panSize; ++i) | ||
pan[i] = std::cos(i * (piTwo<double>() / (panSize - 1))); | ||
|
||
for (; i < static_cast<int>(pan.size()); ++i) | ||
pan[i] = pan[panSize - 1]; | ||
|
||
return pan; | ||
}(); | ||
|
||
float _panLookup(float pan) | ||
{ | ||
// reduce range, round to nearest | ||
int index = lroundPositive(pan * (panSize - 1)); | ||
return panData[index]; | ||
} | ||
|
||
void panScalar(const float* panEnvelope, float* leftBuffer, float* rightBuffer, unsigned size) noexcept | ||
{ | ||
const auto sentinel = panEnvelope + size; | ||
while (panEnvelope < sentinel) { | ||
auto p =(*panEnvelope + 1.0f) * 0.5f; | ||
p = clamp(p, 0.0f, 1.0f); | ||
*leftBuffer *= _panLookup(p); | ||
*rightBuffer *= _panLookup(1 - p); | ||
incrementAll(panEnvelope, leftBuffer, rightBuffer); | ||
} | ||
} | ||
|
||
void panSIMD(const float* panEnvelope, float* leftBuffer, float* rightBuffer, unsigned size) noexcept | ||
{ | ||
const auto sentinel = panEnvelope + size; | ||
int32_t indices[4]; | ||
while (panEnvelope < sentinel) { | ||
float32x4_t mmPan = vld1q_f32(panEnvelope); | ||
mmPan = vaddq_f32(mmPan, vdupq_n_f32(1.0f)); | ||
mmPan = vmulq_n_f32(mmPan, 0.5f * panSize); | ||
mmPan = vaddq_f32(mmPan, vdupq_n_f32(0.5f)); | ||
mmPan = vminq_f32(mmPan, vdupq_n_f32(panSize)); | ||
mmPan = vmaxq_f32(mmPan, vdupq_n_f32(0.0f)); | ||
int32x4_t mmIdx = vcvtq_s32_f32(mmPan); | ||
vst1q_s32(indices, mmIdx); | ||
|
||
leftBuffer[0] *= panData[indices[0]]; | ||
rightBuffer[0] *= panData[panSize - indices[0] - 1]; | ||
leftBuffer[1] *= panData[indices[1]]; | ||
rightBuffer[1] *= panData[panSize - indices[1]- 1]; | ||
leftBuffer[2] *= panData[indices[2]]; | ||
rightBuffer[2] *= panData[panSize - indices[2]- 1]; | ||
leftBuffer[3] *= panData[indices[3]]; | ||
rightBuffer[3] *= panData[panSize - indices[3]- 1]; | ||
|
||
incrementAll<4>(panEnvelope, leftBuffer, rightBuffer); | ||
} | ||
} | ||
|
||
class PanFixture : public benchmark::Fixture { | ||
public: | ||
void SetUp(const ::benchmark::State& state) { | ||
std::random_device rd { }; | ||
std::mt19937 gen { rd() }; | ||
std::uniform_real_distribution<float> dist { -1.0f, 1.0f }; | ||
pan.resize(state.range(0)); | ||
right.resize(state.range(0)); | ||
left.resize(state.range(0)); | ||
|
||
if (!willAlign<16>(pan.data(), left.data(), right.data())) | ||
std::cout << "Will not align!" << '\n'; | ||
absl::c_generate(pan, [&]() { return dist(gen); }); | ||
absl::c_generate(left, [&]() { return dist(gen); }); | ||
absl::c_generate(right, [&]() { return dist(gen); }); | ||
} | ||
|
||
void TearDown(const ::benchmark::State& /* state */) { | ||
|
||
} | ||
|
||
aligned_vector<float> pan; | ||
aligned_vector<float> right; | ||
aligned_vector<float> left; | ||
}; | ||
|
||
BENCHMARK_DEFINE_F(PanFixture, PanScalar)(benchmark::State& state) { | ||
for (auto _ : state) | ||
{ | ||
panScalar(pan.data(), left.data(), right.data(), state.range(0)); | ||
} | ||
} | ||
|
||
BENCHMARK_DEFINE_F(PanFixture, PanSIMD)(benchmark::State& state) { | ||
for (auto _ : state) | ||
{ | ||
panSIMD(pan.data(), left.data(), right.data(), state.range(0)); | ||
} | ||
} | ||
|
||
BENCHMARK_DEFINE_F(PanFixture, PanSfizz)(benchmark::State& state) { | ||
for (auto _ : state) | ||
{ | ||
sfz::pan(pan.data(), left.data(), right.data(), state.range(0)); | ||
} | ||
} | ||
|
||
// Register the function as a benchmark | ||
BENCHMARK_REGISTER_F(PanFixture, PanScalar)->RangeMultiplier(4)->Range((1 << 4), (1 << 12)); | ||
BENCHMARK_REGISTER_F(PanFixture, PanSIMD)->RangeMultiplier(4)->Range((1 << 4), (1 << 12)); | ||
BENCHMARK_REGISTER_F(PanFixture, PanSfizz)->RangeMultiplier(4)->Range((1 << 4), (1 << 12)); | ||
BENCHMARK_MAIN(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.