13
0

Fix loop-fade and de-click buffersize calculation

Exponential approach to zero:
     1 / exp(t) == exp (-t)
we "stretch" it by a time-constant "c":
        gain(t) = exp (-t * c)

To find the time t, at which the exponential approach reaches gain "g":
                                  exp (-c * t) = g
take the log of both sides:  log (exp (-c * t) =  log (g)
since  log (exp (x)) == x :               -c t =  log (g)
divide by -c              :                  t = -log (g) / c
set g = 1e-5 and c = _a/sr and we get:       t = -log (1e-5) / (_a/sr)

The iterative approach using g += c * (target_gain - g);
converges faster than the exact exp() calculation.

Except with 32-bit float, if target-gain is 1.0f and "c" is small.

With 32bit float (1.0 - 1e-5) = .9999900 is represented as
   sign: +1 | mantissa: 0x7fff58 | exponent: 126
there are only 126 "steps" to 1.0. Rounding of the lowest
mantissa bit does matter. We have to assume worst-case,
and increase the required loop_fade_length buffersize.

vs. approaching 0, where there are over 2^110 steps between
zero and 1e-5.
This commit is contained in:
Robin Gareus 2020-02-12 17:19:57 +01:00
parent f477dd088c
commit 6f755c3c02
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -1528,6 +1528,8 @@ DiskReader::Declicker::alloc (samplecnt_t sr, bool fadein)
}
}
assert (n < loop_fade_length);
fade_length = n;
/* zero out the rest just to be safe */
@ -1733,7 +1735,7 @@ DiskReader::rt_midibuffer ()
void
DiskReader::alloc_loop_declick (samplecnt_t sr)
{
loop_fade_length = lrintf (ceil (-log (GAIN_COEFF_DELTA) / (1024. / sr)));
loop_fade_length = lrintf (ceil (-log (GAIN_COEFF_DELTA / 2.) / (1024. / sr)));
loop_declick_in.alloc (sr, true);
loop_declick_out.alloc (sr, false);
}