aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2024-01-03 20:54:50 -0800
committerChris Robinson <[email protected]>2024-01-03 20:58:40 -0800
commit6675317107257c2cc16c947b359d557821d85bf2 (patch)
treea79444cae7dbdba28d6391126ea34c372dfc8825
parent744bd1e289502f3ab413a4026f3dc9a6b6e07a72 (diff)
Avoid a union for storing a temporary value
-rw-r--r--alc/effects/reverb.cpp70
1 files changed, 37 insertions, 33 deletions
diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp
index 047dca6c..2d884500 100644
--- a/alc/effects/reverb.cpp
+++ b/alc/effects/reverb.cpp
@@ -22,6 +22,7 @@
#include <algorithm>
#include <array>
+#include <cassert>
#include <cstdint>
#include <cstdio>
#include <functional>
@@ -289,20 +290,16 @@ struct DelayLineI {
* of 2 to allow the use of bit-masking instead of a modulus for wrapping.
*/
size_t Mask{0u};
- union {
- uintptr_t LineOffset{0u};
- std::array<float,NUM_LINES> *Line;
- };
+ std::array<float,NUM_LINES> *Line;
/* Given the allocated sample buffer, this function updates each delay line
* offset.
*/
void realizeLineOffset(std::array<float,NUM_LINES> *sampleBuffer) noexcept
- { Line = sampleBuffer + LineOffset; }
+ { Line = sampleBuffer; }
/* Calculate the length of a delay line and store its mask and offset. */
- uint calcLineLength(const float length, const uintptr_t offset, const float frequency,
- const uint extra)
+ size_t calcLineLength(const float length, const float frequency, const uint extra)
{
/* All line lengths are powers of 2, calculated from their lengths in
* seconds, rounded up.
@@ -312,7 +309,6 @@ struct DelayLineI {
/* All lines share a single sample buffer. */
Mask = samples - 1;
- LineOffset = offset;
/* Return the sample count for accumulation. */
return samples;
@@ -676,11 +672,6 @@ inline float CalcDelayLengthMult(float density)
*/
void ReverbState::allocLines(const float frequency)
{
- /* All delay line lengths are calculated to accommodate the full range of
- * lengths given their respective parameters.
- */
- size_t totalSamples{0u};
-
/* Multiplier for the maximum density value, i.e. density=1, which is
* actually the least density...
*/
@@ -690,8 +681,12 @@ void ReverbState::allocLines(const float frequency)
* time and depth coefficient, and halfed for the low-to-high frequency
* swing.
*/
- constexpr float max_mod_delay{MaxModulationTime*MODULATION_DEPTH_COEFF / 2.0f};
+ static constexpr float max_mod_delay{MaxModulationTime*MODULATION_DEPTH_COEFF / 2.0f};
+
+ std::array<size_t,12> lineoffsets{};
+ size_t oidx{0};
+ size_t totalSamples{0u};
for(auto &pipeline : mPipelines)
{
/* The main delay length includes the maximum early reflection delay,
@@ -700,37 +695,45 @@ void ReverbState::allocLines(const float frequency)
* update size (BufferLineSize) for block processing.
*/
float length{ReverbMaxReflectionsDelay + EARLY_TAP_LENGTHS.back()*multiplier};
- totalSamples += pipeline.mEarlyDelayIn.calcLineLength(length, totalSamples, frequency,
- BufferLineSize);
+ size_t count{pipeline.mEarlyDelayIn.calcLineLength(length, frequency, BufferLineSize)};
+ lineoffsets[oidx++] = totalSamples;
+ totalSamples += count;
- constexpr float LateLineDiffAvg{(LATE_LINE_LENGTHS.back()-LATE_LINE_LENGTHS.front()) /
+ static constexpr float LateDiffAvg{(LATE_LINE_LENGTHS.back()-LATE_LINE_LENGTHS.front()) /
float{NUM_LINES}};
- length = ReverbMaxLateReverbDelay + LateLineDiffAvg*multiplier;
- totalSamples += pipeline.mLateDelayIn.calcLineLength(length, totalSamples, frequency,
- BufferLineSize);
+ length = ReverbMaxLateReverbDelay + LateDiffAvg*multiplier;
+ count = pipeline.mLateDelayIn.calcLineLength(length, frequency, BufferLineSize);
+ lineoffsets[oidx++] = totalSamples;
+ totalSamples += count;
/* The early vector all-pass line. */
length = EARLY_ALLPASS_LENGTHS.back() * multiplier;
- totalSamples += pipeline.mEarly.VecAp.Delay.calcLineLength(length, totalSamples, frequency,
- 0);
+ count = pipeline.mEarly.VecAp.Delay.calcLineLength(length, frequency, 0);
+ lineoffsets[oidx++] = totalSamples;
+ totalSamples += count;
/* The early reflection line. */
length = EARLY_LINE_LENGTHS.back() * multiplier;
- totalSamples += pipeline.mEarly.Delay.calcLineLength(length, totalSamples, frequency,
- MAX_UPDATE_SAMPLES);
+ count = pipeline.mEarly.Delay.calcLineLength(length, frequency, MAX_UPDATE_SAMPLES);
+ lineoffsets[oidx++] = totalSamples;
+ totalSamples += count;
/* The late vector all-pass line. */
length = LATE_ALLPASS_LENGTHS.back() * multiplier;
- totalSamples += pipeline.mLate.VecAp.Delay.calcLineLength(length, totalSamples, frequency,
- 0);
+ count = pipeline.mLate.VecAp.Delay.calcLineLength(length, frequency, 0);
+ lineoffsets[oidx++] = totalSamples;
+ totalSamples += count;
/* The late delay lines are calculated from the largest maximum density
* line length, and the maximum modulation delay. Four additional
* samples are needed for resampling the modulator delay.
*/
length = LATE_LINE_LENGTHS.back()*multiplier + max_mod_delay;
- totalSamples += pipeline.mLate.Delay.calcLineLength(length, totalSamples, frequency, 4);
+ count = pipeline.mLate.Delay.calcLineLength(length, frequency, 4);
+ lineoffsets[oidx++] = totalSamples;
+ totalSamples += count;
}
+ assert(oidx == lineoffsets.size());
if(totalSamples != mSampleBuffer.size())
decltype(mSampleBuffer)(totalSamples).swap(mSampleBuffer);
@@ -739,14 +742,15 @@ void ReverbState::allocLines(const float frequency)
std::fill(mSampleBuffer.begin(), mSampleBuffer.end(), decltype(mSampleBuffer)::value_type{});
/* Update all delays to reflect the new sample buffer. */
+ oidx = 0;
for(auto &pipeline : mPipelines)
{
- pipeline.mEarlyDelayIn.realizeLineOffset(mSampleBuffer.data());
- pipeline.mLateDelayIn.realizeLineOffset(mSampleBuffer.data());
- pipeline.mEarly.VecAp.Delay.realizeLineOffset(mSampleBuffer.data());
- pipeline.mEarly.Delay.realizeLineOffset(mSampleBuffer.data());
- pipeline.mLate.VecAp.Delay.realizeLineOffset(mSampleBuffer.data());
- pipeline.mLate.Delay.realizeLineOffset(mSampleBuffer.data());
+ pipeline.mEarlyDelayIn.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]);
+ pipeline.mLateDelayIn.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]);
+ pipeline.mEarly.VecAp.Delay.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]);
+ pipeline.mEarly.Delay.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]);
+ pipeline.mLate.VecAp.Delay.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]);
+ pipeline.mLate.Delay.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]);
}
}