The fill simd helper is just an alias for absl::c_fill

The pass-by-value alias is still necessary for cases where you pass an rvalue to the function (which happens often when e.g. you take a subspan)
This commit is contained in:
Paul Ferrand 2020-05-30 20:59:41 +02:00 committed by Jean Pierre Cimalando
parent 781cae65ef
commit b10b05078a
7 changed files with 18 additions and 41 deletions

View file

@ -67,7 +67,7 @@ BENCHMARK_DEFINE_F(PanArray, BlockOps)(benchmark::State& state) {
ScopedFTZ ftz; ScopedFTZ ftz;
for (auto _ : state) for (auto _ : state)
{ {
sfz::fill<float>(span2, 1.0f); sfz::fill(span2, 1.0f);
sfz::add<float>(span1, span2); sfz::add<float>(span1, span2);
sfz::applyGain<float>(piFour<float>(), span2); sfz::applyGain<float>(piFour<float>(), span2);
sfz::cos<float>(span2, span1); sfz::cos<float>(span2, span1);

View file

@ -279,7 +279,7 @@ public:
{ {
static_assert(!std::is_const<Type>::value, "Can't allow mutating operations on const AudioSpans"); static_assert(!std::is_const<Type>::value, "Can't allow mutating operations on const AudioSpans");
for (size_t i = 0; i < numChannels; ++i) for (size_t i = 0; i < numChannels; ++i)
sfz::fill<Type>(getSpan(i), value); sfz::fill(getSpan(i), value);
} }
/** /**

View file

@ -35,7 +35,7 @@ public:
void resize(size_t size) void resize(size_t size)
{ {
buffer.resize(size); buffer.resize(size);
fill<ValueType>(absl::MakeSpan(buffer), 0.0); fill(absl::MakeSpan(buffer), ValueType { 0 });
index = 0; index = 0;
validMean = false; validMean = false;
} }

View file

@ -74,7 +74,7 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
lastValue = linearRamp<float>(envelope.subspan(lastDelay, length), lastValue, step); lastValue = linearRamp<float>(envelope.subspan(lastDelay, length), lastValue, step);
lastDelay += length; lastDelay += length;
} }
fill<float>(envelope.subspan(lastDelay), lastValue); fill(envelope.subspan(lastDelay), lastValue);
} }
template <class F> template <class F>
@ -100,7 +100,7 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
const auto length = min(events[i].delay, maxDelay) - lastDelay; const auto length = min(events[i].delay, maxDelay) - lastDelay;
if (difference < step) { if (difference < step) {
fill<float>(envelope.subspan(lastDelay, length), lastValue); fill(envelope.subspan(lastDelay, length), lastValue);
lastValue = nextValue; lastValue = nextValue;
lastDelay += length; lastDelay += length;
continue; continue;
@ -109,12 +109,12 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
const auto numSteps = static_cast<int>(difference / step); const auto numSteps = static_cast<int>(difference / step);
const auto stepLength = static_cast<int>(length / numSteps); const auto stepLength = static_cast<int>(length / numSteps);
for (int i = 0; i < numSteps; ++i) { for (int i = 0; i < numSteps; ++i) {
fill<float>(envelope.subspan(lastDelay, stepLength), lastValue); fill(envelope.subspan(lastDelay, stepLength), lastValue);
lastValue += lastValue <= nextValue ? step : -step; lastValue += lastValue <= nextValue ? step : -step;
lastDelay += stepLength; lastDelay += stepLength;
} }
} }
fill<float>(envelope.subspan(lastDelay), lastValue); fill(envelope.subspan(lastDelay), lastValue);
} }
template <class F> template <class F>
@ -137,7 +137,7 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
lastValue = nextValue; lastValue = nextValue;
lastDelay += length; lastDelay += length;
} }
fill<float>(envelope.subspan(lastDelay), lastValue); fill(envelope.subspan(lastDelay), lastValue);
} }
template <class F, bool Round = false> template <class F, bool Round = false>
@ -170,7 +170,7 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
const auto difference = nextValue > lastValue ? nextValue / lastValue : lastValue / nextValue; const auto difference = nextValue > lastValue ? nextValue / lastValue : lastValue / nextValue;
if (difference < step) { if (difference < step) {
fill<float>(envelope.subspan(lastDelay, length), lastValue); fill(envelope.subspan(lastDelay, length), lastValue);
lastValue = nextValue; lastValue = nextValue;
lastDelay += length; lastDelay += length;
continue; continue;
@ -179,12 +179,12 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
const auto numSteps = std::round(std::log(difference) / logStep); const auto numSteps = std::round(std::log(difference) / logStep);
const auto stepLength = static_cast<int>(length / numSteps); const auto stepLength = static_cast<int>(length / numSteps);
for (int i = 0; i < static_cast<int>(numSteps); ++i) { for (int i = 0; i < static_cast<int>(numSteps); ++i) {
fill<float>(envelope.subspan(lastDelay, stepLength), lastValue); fill(envelope.subspan(lastDelay, stepLength), lastValue);
lastValue = nextValue > lastValue ? lastValue * step : lastValue / step; lastValue = nextValue > lastValue ? lastValue * step : lastValue / step;
lastDelay += stepLength; lastDelay += stepLength;
} }
} }
fill<float>(envelope.subspan(lastDelay), lastValue); fill(envelope.subspan(lastDelay), lastValue);
} }
template <class F> template <class F>

View file

@ -151,15 +151,12 @@ inline void writeInterleaved(absl::Span<const float> inputLeft, absl::Span<const
* @param output * @param output
* @param value * @param value
*/ */
template <class T, bool SIMD = SIMDConfig::fill> template <class T>
void fill(absl::Span<T> output, T value) noexcept void fill(absl::Span<T> output, T value) noexcept
{ {
absl::c_fill(output, value); absl::c_fill(output, value);
} }
template <>
void fill<float, true>(absl::Span<float> output, float value) noexcept;
/** /**
* @brief Exp math function * @brief Exp math function
* *

View file

@ -16,26 +16,6 @@
constexpr uintptr_t TypeAlignment = 4; constexpr uintptr_t TypeAlignment = 4;
template <>
void sfz::fill<float, true>(absl::Span<float> output, float value) noexcept
{
const auto mmValue = _mm_set_ps1(value);
auto* out = output.begin();
const auto* lastAligned = prevAligned(output.end());
while (unaligned(out) && out < lastAligned)
*out++ = value;
while (out < lastAligned) // we should only need to test a single channel
{
_mm_store_ps(out, mmValue);
out += TypeAlignment;
}
while (out < output.end())
*out++ = value;
}
template <> template <>
void sfz::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
{ {

View file

@ -358,7 +358,7 @@ void sfz::Voice::panStageMono(AudioSpan<float> buffer) noexcept
copy<float>(leftBuffer, rightBuffer); copy<float>(leftBuffer, rightBuffer);
// Apply panning // Apply panning
fill<float>(*modulationSpan, region->pan); fill(*modulationSpan, region->pan);
for (const auto& mod : region->panCC) { for (const auto& mod : region->panCC) {
linearModifier(resources, *tempSpan, mod, normalizePercents<float>); linearModifier(resources, *tempSpan, mod, normalizePercents<float>);
add<float>(*tempSpan, *modulationSpan); add<float>(*tempSpan, *modulationSpan);
@ -379,7 +379,7 @@ void sfz::Voice::panStageStereo(AudioSpan<float> buffer) noexcept
return; return;
// Apply panning // Apply panning
fill<float>(*modulationSpan, region->pan); fill(*modulationSpan, region->pan);
for (const auto& mod : region->panCC) { for (const auto& mod : region->panCC) {
linearModifier(resources, *tempSpan, mod, normalizePercents<float>); linearModifier(resources, *tempSpan, mod, normalizePercents<float>);
add<float>(*tempSpan, *modulationSpan); add<float>(*tempSpan, *modulationSpan);
@ -387,14 +387,14 @@ void sfz::Voice::panStageStereo(AudioSpan<float> buffer) noexcept
pan<float>(*modulationSpan, leftBuffer, rightBuffer); pan<float>(*modulationSpan, leftBuffer, rightBuffer);
// Apply the width/position process // Apply the width/position process
fill<float>(*modulationSpan, region->width); fill(*modulationSpan, region->width);
for (const auto& mod : region->widthCC) { for (const auto& mod : region->widthCC) {
linearModifier(resources, *tempSpan, mod, normalizePercents<float>); linearModifier(resources, *tempSpan, mod, normalizePercents<float>);
add<float>(*tempSpan, *modulationSpan); add<float>(*tempSpan, *modulationSpan);
} }
width<float>(*modulationSpan, leftBuffer, rightBuffer); width<float>(*modulationSpan, leftBuffer, rightBuffer);
fill<float>(*modulationSpan, region->position); fill(*modulationSpan, region->position);
for (const auto& mod : region->positionCC) { for (const auto& mod : region->positionCC) {
linearModifier(resources, *tempSpan, mod, normalizePercents<float>); linearModifier(resources, *tempSpan, mod, normalizePercents<float>);
add<float>(*tempSpan, *modulationSpan); add<float>(*tempSpan, *modulationSpan);
@ -457,7 +457,7 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
if (!jumps || !bends || !indices || !coeffs) if (!jumps || !bends || !indices || !coeffs)
return; return;
fill<float>(*jumps, pitchRatio * speedRatio); fill(*jumps, pitchRatio * speedRatio);
const auto events = resources.midiState.getPitchEvents(); const auto events = resources.midiState.getPitchEvents();
const auto bendLambda = [this](float bend) { const auto bendLambda = [this](float bend) {
@ -588,7 +588,7 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
return; return;
float keycenterFrequency = midiNoteFrequency(region->pitchKeycenter); float keycenterFrequency = midiNoteFrequency(region->pitchKeycenter);
fill<float>(*frequencies, pitchRatio * keycenterFrequency); fill(*frequencies, pitchRatio * keycenterFrequency);
const auto events = resources.midiState.getPitchEvents(); const auto events = resources.midiState.getPitchEvents();
const auto bendLambda = [this](float bend) { const auto bendLambda = [this](float bend) {