diff options
author | Chris Robinson <[email protected]> | 2022-08-29 07:03:09 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-08-29 07:03:09 -0700 |
commit | 42aab714a1fafba2af6b60a47ce97ae2e2e4309a (patch) | |
tree | 30f66ee3f35fe0dacaad64e5eadb8f25275878bf /alc | |
parent | 56d7e09cc7b24f1d3087962f8e11959d210baefe (diff) |
Always fade the main early and late delay taps
These were actually missing from the current check for fading. But the EFX
documentation suggests these (along with the early/late gain and panning) can
be adjusted often without invoking a full change, as dynamically modeling an
environment would continually change these properties as the listener moves
around (changing the direction and distance to the reflective surfaces). So
ensuring they're kept up-to-date would be the way to go.
Diffstat (limited to 'alc')
-rw-r--r-- | alc/effects/reverb.cpp | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 687d76cb..01b70339 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -1369,18 +1369,31 @@ void ReverbState::earlyUnfaded(size_t offset, const size_t samplesToDo) /* First, load decorrelated samples from the main delay line as the * primary reflections. */ + const float fadeStep{1.0f / static_cast<float>(todo)}; for(size_t j{0u};j < NUM_LINES;j++) { - size_t early_delay_tap{offset - mEarlyDelayTap[j][0]}; + size_t early_delay_tap0{offset - mEarlyDelayTap[j][0]}; + size_t early_delay_tap1{offset - mEarlyDelayTap[j][1]}; const float coeff{mEarlyDelayCoeff[j][0]}; + const float coeffStep{early_delay_tap0 != early_delay_tap1 ? coeff*fadeStep : 0.0f}; + float fadeCount{0.0f}; + for(size_t i{0u};i < todo;) { - early_delay_tap &= in_delay.Mask; - size_t td{minz(in_delay.Mask+1 - early_delay_tap, todo - i)}; + early_delay_tap0 &= in_delay.Mask; + early_delay_tap1 &= in_delay.Mask; + const size_t max_tap{maxz(early_delay_tap0, early_delay_tap1)}; + size_t td{minz(in_delay.Mask+1 - max_tap, todo-i)}; do { - mTempSamples[j][i++] = in_delay.Line[early_delay_tap++][j] * coeff; + const float fade0{coeff - coeffStep*fadeCount}; + const float fade1{coeffStep*fadeCount}; + fadeCount += 1.0f; + mTempSamples[j][i++] = in_delay.Line[early_delay_tap0++][j]*fade0 + + in_delay.Line[early_delay_tap1++][j]*fade1; } while(--td); } + + mEarlyDelayTap[j][0] = mEarlyDelayTap[j][1]; } /* Apply a vector all-pass, to help color the initial reflections based @@ -1567,17 +1580,23 @@ void ReverbState::lateUnfaded(size_t offset, const size_t samplesToDo) /* Next, load decorrelated samples from the main and feedback delay * lines. Filter the signal to apply its frequency-dependent decay. */ + const float fadeStep{1.0f / static_cast<float>(todo)}; for(size_t j{0u};j < NUM_LINES;j++) { - size_t late_delay_tap{offset - mLateDelayTap[j][0]}; + size_t late_delay_tap0{offset - mLateDelayTap[j][0]}; + size_t late_delay_tap1{offset - mLateDelayTap[j][1]}; size_t late_feedb_tap{offset - mLate.Offset[j][0]}; const float midGain{mLate.T60[j].MidGain[0]}; const float densityGain{mLate.DensityGain[0] * midGain}; + const float densityStep{late_delay_tap0 != late_delay_tap1 ? + densityGain*fadeStep : 0.0f}; + float fadeCount{0.0f}; for(size_t i{0u};i < todo;) { - late_delay_tap &= in_delay.Mask; - size_t td{minz(todo - i, in_delay.Mask+1 - late_delay_tap)}; + late_delay_tap0 &= in_delay.Mask; + late_delay_tap1 &= in_delay.Mask; + size_t td{minz(todo-i, in_delay.Mask+1 - maxz(late_delay_tap0, late_delay_tap1))}; do { /* Calculate the read offset and fraction between it and * the next sample. @@ -1595,11 +1614,17 @@ void ReverbState::lateUnfaded(size_t offset, const size_t samplesToDo) * samples that were acquired above, and combined with the * main delay tap. */ + const float fade0{densityGain - densityStep*fadeCount}; + const float fade1{densityStep*fadeCount}; + fadeCount += 1.0f; mTempSamples[j][i] = lerpf(out0, out1, frac)*midGain + - in_delay.Line[late_delay_tap++][j]*densityGain; + in_delay.Line[late_delay_tap0++][j]*fade0 + + in_delay.Line[late_delay_tap1++][j]*fade1; ++i; } while(--td); } + mLateDelayTap[j][0] = mLateDelayTap[j][1]; + mLate.T60[j].process({mTempSamples[j].data(), todo}); } |