Added a new quantized envelope
This commit is contained in:
parent
75cf7dee96
commit
055f233d88
4 changed files with 121 additions and 9 deletions
|
|
@ -79,9 +79,9 @@ static void FillSIMD_unaligned(benchmark::State& state) {
|
|||
}
|
||||
}
|
||||
|
||||
BENCHMARK(Dummy)->Range((2<<6), (2<<16));
|
||||
BENCHMARK(FillScalar)->Range((2<<6), (2<<16));
|
||||
BENCHMARK(FillSIMD)->Range((2<<6), (2<<16));
|
||||
BENCHMARK(FillScalar_unaligned)->Range((2<<6), (2<<16));
|
||||
BENCHMARK(FillSIMD_unaligned)->Range((2<<6), (2<<16));
|
||||
BENCHMARK(Dummy)->RangeMultiplier(4)->Range((1<<2), (1<<12));
|
||||
BENCHMARK(FillScalar)->RangeMultiplier(4)->Range((1<<2), (1<<12));
|
||||
BENCHMARK(FillSIMD)->RangeMultiplier(4)->Range((1<<2), (1<<12));
|
||||
BENCHMARK(FillScalar_unaligned)->RangeMultiplier(4)->Range((1<<2), (1<<12));
|
||||
BENCHMARK(FillSIMD_unaligned)->RangeMultiplier(4)->Range((1<<2), (1<<12));
|
||||
BENCHMARK_MAIN();
|
||||
|
|
@ -133,6 +133,63 @@ static void MulSIMDUnaligned(benchmark::State& state) {
|
|||
}
|
||||
}
|
||||
|
||||
static void LogDomainScalar(benchmark::State& state) {
|
||||
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);
|
||||
sfz::linearRamp<float, false>(absl::MakeSpan(output), 1.0f, value);
|
||||
sfz::applyGain<float, false>(std::log(2.0f), absl::MakeSpan(output));
|
||||
sfz::exp<float, false>(output, absl::MakeSpan(output));
|
||||
}
|
||||
}
|
||||
|
||||
static void LogDomainSIMD(benchmark::State& state) {
|
||||
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);
|
||||
sfz::linearRamp<float, true>(absl::MakeSpan(output), 1.0f, value);
|
||||
sfz::applyGain<float, true>(std::log(2.0f), absl::MakeSpan(output));
|
||||
sfz::exp<float, true>(output, absl::MakeSpan(output));
|
||||
}
|
||||
}
|
||||
static void LogDomainScalarUnaligned(benchmark::State& state) {
|
||||
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);
|
||||
auto outputSpan = absl::MakeSpan(output).subspan(1);
|
||||
sfz::linearRamp<float, false>(outputSpan, 1.0f, value);
|
||||
sfz::applyGain<float, false>(std::log(2.0f), outputSpan);
|
||||
sfz::exp<float, false>(outputSpan, outputSpan);
|
||||
}
|
||||
}
|
||||
|
||||
static void LogDomainSIMDUnaligned(benchmark::State& state) {
|
||||
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);
|
||||
auto outputSpan = absl::MakeSpan(output).subspan(1);
|
||||
sfz::linearRamp<float, true>(outputSpan, 1.0f, value);
|
||||
sfz::applyGain<float, true>(std::log(2.0f), outputSpan);
|
||||
sfz::exp<float, true>(outputSpan, outputSpan);
|
||||
}
|
||||
}
|
||||
|
||||
// Register the function as a benchmark
|
||||
BENCHMARK(Dummy)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
||||
BENCHMARK(LinearScalar)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
||||
|
|
@ -143,4 +200,8 @@ BENCHMARK(MulScalar)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
|||
BENCHMARK(MulSIMD)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
||||
BENCHMARK(MulScalarUnaligned)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
||||
BENCHMARK(MulSIMDUnaligned)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
||||
BENCHMARK(LogDomainScalar)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
||||
BENCHMARK(LogDomainSIMD)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
||||
BENCHMARK(LogDomainScalarUnaligned)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
||||
BENCHMARK(LogDomainSIMDUnaligned)->RangeMultiplier(4)->Range((1 << 2), (1 << 12));
|
||||
BENCHMARK_MAIN();
|
||||
|
|
@ -103,13 +103,16 @@ void LinearEnvelope<Type>::getBlock(absl::Span<Type> output)
|
|||
template <class Type>
|
||||
void LinearEnvelope<Type>::getQuantizedBlock(absl::Span<Type> output, Type quantizationStep)
|
||||
{
|
||||
ASSERT(quantizationStep != 0.0);
|
||||
|
||||
absl::c_sort(events, [](const auto& lhs, const auto& rhs) {
|
||||
return lhs.first < rhs.first;
|
||||
});
|
||||
int index { 0 };
|
||||
|
||||
auto quantize = [quantizationStep](Type value) -> Type {
|
||||
return static_cast<int>(value / quantizationStep) * quantizationStep;
|
||||
const auto halfStep = quantizationStep / 2;
|
||||
auto quantize = [quantizationStep, halfStep](Type value) -> Type {
|
||||
return static_cast<int>((value + halfStep) / quantizationStep) * quantizationStep;
|
||||
};
|
||||
|
||||
currentValue = quantize(currentValue);
|
||||
|
|
@ -125,9 +128,9 @@ void LinearEnvelope<Type>::getQuantizedBlock(absl::Span<Type> output, Type quant
|
|||
|
||||
const int numSteps = abs(newValue - currentValue) / quantizationStep;
|
||||
const auto stepLength = static_cast<int>(length / numSteps);
|
||||
while (outputSize - index > stepLength) {
|
||||
currentValue += currentValue <= newValue ? quantizationStep : -quantizationStep;
|
||||
for (int i = 0; i < numSteps; ++i) {
|
||||
fill<Type>(output.subspan(index, stepLength), currentValue);
|
||||
currentValue += currentValue <= newValue ? quantizationStep : -quantizationStep;
|
||||
index += stepLength;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,4 +156,52 @@ TEST_CASE("[LinearEnvelope] 2 events, function")
|
|||
std::array<float, 8> expected { 1, 2, 2.5, 3, 3.5, 4.0, 4.0, 4.0 };
|
||||
envelope.getBlock(absl::MakeSpan(output));
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0);
|
||||
envelope.registerEvent(6, 2.0);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0 };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0);
|
||||
envelope.registerEvent(6, 3.0);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0 };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized with unclean events")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.2);
|
||||
envelope.registerEvent(6, 2.5);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0 };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[LinearEnvelope] Get quantized 3 events, one out of block")
|
||||
{
|
||||
sfz::LinearEnvelope<float> envelope;
|
||||
envelope.registerEvent(2, 1.0);
|
||||
envelope.registerEvent(6, 2.0);
|
||||
envelope.registerEvent(10, 3.0);
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0 };
|
||||
std::array<float, 8> expected2 { 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0 };
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected);
|
||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 1.0f);
|
||||
REQUIRE(output == expected2);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue