aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/effects/reverb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/effects/reverb.cpp')
-rw-r--r--Alc/effects/reverb.cpp71
1 files changed, 35 insertions, 36 deletions
diff --git a/Alc/effects/reverb.cpp b/Alc/effects/reverb.cpp
index 927c545a..ff4e744b 100644
--- a/Alc/effects/reverb.cpp
+++ b/Alc/effects/reverb.cpp
@@ -24,7 +24,8 @@
#include <cstdlib>
#include <cmath>
-#include <cmath>
+#include <array>
+#include <numeric>
#include <algorithm>
#include <functional>
@@ -51,21 +52,21 @@ using namespace std::placeholders;
/* This is the maximum number of samples processed for each inner loop
* iteration.
*/
-#define MAX_UPDATE_SAMPLES 256
+constexpr int MAX_UPDATE_SAMPLES{256};
/* The number of samples used for cross-faded delay lines. This can be used
* to balance the compensation for abrupt line changes and attenuation due to
* minimally lengthed recursive lines. Try to keep this below the device
* update size.
*/
-#define FADE_SAMPLES 128
+constexpr int FADE_SAMPLES{128};
/* The number of spatialized lines or channels to process. Four channels allows
* for a 3D A-Format response. NOTE: This can't be changed without taking care
* of the conversion matrices, and a few places where the length arrays are
* assumed to have 4 elements.
*/
-#define NUM_LINES 4
+constexpr int NUM_LINES{4};
/* The B-Format to A-Format conversion matrix. The arrangement of rows is
@@ -154,9 +155,9 @@ constexpr ALfloat DENSITY_SCALE{125000.0f};
*
* Assuming an average of 1m, we get the following taps:
*/
-constexpr ALfloat EARLY_TAP_LENGTHS[NUM_LINES]{
+constexpr std::array<ALfloat,NUM_LINES> EARLY_TAP_LENGTHS{{
0.0000000e+0f, 2.0213520e-4f, 4.2531060e-4f, 6.7171600e-4f
-};
+}};
/* The early all-pass filter lengths are based on the early tap lengths:
*
@@ -164,9 +165,9 @@ constexpr ALfloat EARLY_TAP_LENGTHS[NUM_LINES]{
*
* Where a is the approximate maximum all-pass cycle limit (20).
*/
-const ALfloat EARLY_ALLPASS_LENGTHS[NUM_LINES]{
+constexpr std::array<ALfloat,NUM_LINES> EARLY_ALLPASS_LENGTHS{{
9.7096800e-5f, 1.0720356e-4f, 1.1836234e-4f, 1.3068260e-4f
-};
+}};
/* The early delay lines are used to transform the primary reflections into
* the secondary reflections. The A-format is arranged in such a way that
@@ -190,17 +191,17 @@ const ALfloat EARLY_ALLPASS_LENGTHS[NUM_LINES]{
*
* Using an average dimension of 1m, we get:
*/
-constexpr ALfloat EARLY_LINE_LENGTHS[NUM_LINES]{
+constexpr std::array<ALfloat,NUM_LINES> EARLY_LINE_LENGTHS{{
5.9850400e-4f, 1.0913150e-3f, 1.5376658e-3f, 1.9419362e-3f
-};
+}};
/* The late all-pass filter lengths are based on the late line lengths:
*
* A_i = (5 / 3) L_i / r_1
*/
-constexpr ALfloat LATE_ALLPASS_LENGTHS[NUM_LINES]{
+constexpr std::array<ALfloat,NUM_LINES> LATE_ALLPASS_LENGTHS{{
1.6182800e-4f, 2.0389060e-4f, 2.8159360e-4f, 3.2365600e-4f
-};
+}};
/* The late lines are used to approximate the decaying cycle of recursive
* late reflections.
@@ -217,9 +218,9 @@ constexpr ALfloat LATE_ALLPASS_LENGTHS[NUM_LINES]{
*
* For our 1m average room, we get:
*/
-constexpr ALfloat LATE_LINE_LENGTHS[NUM_LINES]{
+constexpr std::array<ALfloat,NUM_LINES> LATE_LINE_LENGTHS{{
1.9419362e-3f, 2.4466860e-3f, 3.3791220e-3f, 3.8838720e-3f
-};
+}};
struct DelayLineI {
@@ -514,27 +515,27 @@ bool ReverbState::allocLines(const ALfloat frequency)
* largest late tap width. Finally, it must also be extended by the
* update size (MAX_UPDATE_SAMPLES) for block processing.
*/
- ALfloat length{AL_EAXREVERB_MAX_REFLECTIONS_DELAY + EARLY_TAP_LENGTHS[NUM_LINES-1]*multiplier +
- AL_EAXREVERB_MAX_LATE_REVERB_DELAY +
- (LATE_LINE_LENGTHS[NUM_LINES-1] - LATE_LINE_LENGTHS[0])*0.25f*multiplier};
+ ALfloat length{AL_EAXREVERB_MAX_REFLECTIONS_DELAY + EARLY_TAP_LENGTHS.back()*multiplier +
+ AL_EAXREVERB_MAX_LATE_REVERB_DELAY +
+ (LATE_LINE_LENGTHS.back() - LATE_LINE_LENGTHS.front())*0.25f*multiplier};
totalSamples += CalcLineLength(length, totalSamples, frequency, MAX_UPDATE_SAMPLES, &mDelay);
/* The early vector all-pass line. */
- length = EARLY_ALLPASS_LENGTHS[NUM_LINES-1] * multiplier;
+ length = EARLY_ALLPASS_LENGTHS.back() * multiplier;
totalSamples += CalcLineLength(length, totalSamples, frequency, 0, &mEarly.VecAp.Delay);
/* The early reflection line. */
- length = EARLY_LINE_LENGTHS[NUM_LINES-1] * multiplier;
+ length = EARLY_LINE_LENGTHS.back() * multiplier;
totalSamples += CalcLineLength(length, totalSamples, frequency, 0, &mEarly.Delay);
/* The late vector all-pass line. */
- length = LATE_ALLPASS_LENGTHS[NUM_LINES-1] * multiplier;
+ length = LATE_ALLPASS_LENGTHS.back() * multiplier;
totalSamples += CalcLineLength(length, totalSamples, frequency, 0, &mLate.VecAp.Delay);
/* The late delay lines are calculated from the largest maximum density
* line length.
*/
- length = LATE_LINE_LENGTHS[NUM_LINES-1] * multiplier;
+ length = LATE_LINE_LENGTHS.back() * multiplier;
totalSamples += CalcLineLength(length, totalSamples, frequency, 0, &mLate.Delay);
totalSamples *= NUM_LINES;
@@ -568,9 +569,8 @@ ALboolean ReverbState::deviceUpdate(const ALCdevice *device)
const ALfloat multiplier{CalcDelayLengthMult(AL_EAXREVERB_MAX_DENSITY)};
/* The late feed taps are set a fixed position past the latest delay tap. */
- mLateFeedTap = float2int((AL_EAXREVERB_MAX_REFLECTIONS_DELAY +
- EARLY_TAP_LENGTHS[NUM_LINES-1]*multiplier) *
- frequency);
+ mLateFeedTap = float2int(
+ (AL_EAXREVERB_MAX_REFLECTIONS_DELAY + EARLY_TAP_LENGTHS.back()*multiplier) * frequency);
/* Clear filters and gain coefficients since the delay lines were all just
* cleared (if not reallocated).
@@ -753,6 +753,10 @@ void LateReverb::updateLines(const ALfloat density, const ALfloat diffusion,
*/
const ALfloat norm_weight_factor{frequency / AL_EAXREVERB_MAX_HFREFERENCE};
+ const ALfloat late_allpass_avg{
+ std::accumulate(LATE_ALLPASS_LENGTHS.begin(), LATE_ALLPASS_LENGTHS.end(), 0.0f) /
+ static_cast<float>(LATE_ALLPASS_LENGTHS.size())};
+
/* To compensate for changes in modal density and decay time of the late
* reverb signal, the input is attenuated based on the maximal energy of
* the outgoing signal. This approximation is used to keep the apparent
@@ -762,11 +766,9 @@ void LateReverb::updateLines(const ALfloat density, const ALfloat diffusion,
* attenuation coefficient.
*/
const ALfloat multiplier{CalcDelayLengthMult(density)};
- ALfloat length{
- (LATE_LINE_LENGTHS[0] + LATE_LINE_LENGTHS[1] + LATE_LINE_LENGTHS[2] +
- LATE_LINE_LENGTHS[3]) / 4.0f * multiplier};
- length += (LATE_ALLPASS_LENGTHS[0] + LATE_ALLPASS_LENGTHS[1] +
- LATE_ALLPASS_LENGTHS[2] + LATE_ALLPASS_LENGTHS[3]) / 4.0f * multiplier;
+ ALfloat length{std::accumulate(LATE_LINE_LENGTHS.begin(), LATE_LINE_LENGTHS.end(), 0.0f) /
+ static_cast<float>(LATE_LINE_LENGTHS.size()) * multiplier};
+ length += late_allpass_avg * multiplier;
/* The density gain calculation uses an average decay time weighted by
* approximate bandwidth. This attempts to compensate for losses of energy
* that reduce decay time due to scattering into highly attenuated bands.
@@ -802,10 +804,7 @@ void LateReverb::updateLines(const ALfloat density, const ALfloat diffusion,
* given the current diffusion so we don't have to process a full T60
* filter for each of its four lines.
*/
- length += lerp(LATE_ALLPASS_LENGTHS[i],
- (LATE_ALLPASS_LENGTHS[0] + LATE_ALLPASS_LENGTHS[1] +
- LATE_ALLPASS_LENGTHS[2] + LATE_ALLPASS_LENGTHS[3]) / 4.0f,
- diffusion) * multiplier;
+ length += lerp(LATE_ALLPASS_LENGTHS[i], late_allpass_avg, diffusion) * multiplier;
/* Calculate the T60 damping coefficients for each line. */
T60[i].calcCoeffs(length, lfDecayTime, mfDecayTime, hfDecayTime, lf0norm, hf0norm);
@@ -837,7 +836,7 @@ void ReverbState::updateDelayLine(const ALfloat earlyDelay, const ALfloat lateDe
length = EARLY_TAP_LENGTHS[i]*multiplier;
mEarlyDelayCoeff[i][1] = CalcDecayCoeff(length, decayTime);
- length = lateDelay + (LATE_LINE_LENGTHS[i] - LATE_LINE_LENGTHS[0])*0.25f*multiplier;
+ length = lateDelay + (LATE_LINE_LENGTHS[i] - LATE_LINE_LENGTHS.front())*0.25f*multiplier;
mLateDelayTap[i][1] = mLateFeedTap + float2int(length * frequency);
}
}
@@ -895,13 +894,13 @@ void ReverbState::update3DPanning(const ALfloat *ReflectionsPan, const ALfloat *
const alu::Matrix latemat{GetTransformFromVector(LateReverbPan)};
mOutBuffer = target.Main->Buffer;
mOutChannels = target.Main->NumChannels;
- for(size_t i{0u};i < NUM_LINES;i++)
+ for(ALsizei i{0};i < NUM_LINES;i++)
{
const ALfloat coeffs[MAX_AMBI_CHANNELS]{earlymat[0][i], earlymat[1][i], earlymat[2][i],
earlymat[3][i]};
ComputePanGains(target.Main, coeffs, earlyGain, mEarly.PanGain[i]);
}
- for(size_t i{0u};i < NUM_LINES;i++)
+ for(ALsizei i{0};i < NUM_LINES;i++)
{
const ALfloat coeffs[MAX_AMBI_CHANNELS]{latemat[0][i], latemat[1][i], latemat[2][i],
latemat[3][i]};