aboutsummaryrefslogtreecommitdiffstats
path: root/alc/effects/reverb.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-09-11 02:56:14 -0700
committerChris Robinson <[email protected]>2023-09-11 03:27:17 -0700
commit43fac7e95568a2b7205db365a49e3938b05e913b (patch)
treef2457aa5456a483775cb6a349019417f424919fd /alc/effects/reverb.cpp
parenta89345540520cb4fca40fc394eeac4b5f071680d (diff)
Approximate sin for the reverb modulator LFO
Reverb needs to prioritize efficiency since it's expected that an app may use multiple reverb effects simultaneously, and each individual effect may process twice during a pipeline transition. Approximating sin helps by replacing a per- sample libc call that we don't need to be perfectly accurate.
Diffstat (limited to 'alc/effects/reverb.cpp')
-rw-r--r--alc/effects/reverb.cpp9
1 files changed, 7 insertions, 2 deletions
diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp
index 429d0225..b00f638b 100644
--- a/alc/effects/reverb.cpp
+++ b/alc/effects/reverb.cpp
@@ -1505,14 +1505,19 @@ void ReverbPipeline::processEarly(size_t offset, const size_t samplesToDo,
void Modulation::calcDelays(size_t todo)
{
- constexpr float mod_scale{al::numbers::pi_v<float> * 2.0f / MOD_FRACONE};
uint idx{Index};
const uint step{Step};
const float depth{Depth};
for(size_t i{0};i < todo;++i)
{
idx += step;
- const float lfo{std::sin(static_cast<float>(idx&MOD_FRACMASK) * mod_scale)};
+ const float x{static_cast<float>(idx&MOD_FRACMASK) * (1.0f/MOD_FRACONE)};
+ /* Approximate sin(x*2pi). As long as it roughly fits a sinusoid shape
+ * and stays within [-1...+1], it needn't be perfect.
+ */
+ const float lfo{!(idx&(MOD_FRACONE>>1))
+ ? ((-16.0f * x * x) + (8.0f * x))
+ : ((16.0f * x * x) + (-8.0f * x) + (-16.0f * x) + 8.0f)};
ModDelays[i] = (lfo+1.0f) * depth;
}
Index = idx;