That 354 comparison and clamping never sat well with me so I recently sought to eliminate it. Above about 60dB the output quickly degraded into aliasing just as bad as a straight tanh.

Stripping down F0, it's clear the loss of precision occurs in e^(-2x) for extreme -x values. For x -> +infinity there is no problem since e^(-2x) -> 0.

F0 is an even function so F0(x) can be changed to F0(abs(x)). This allows you to eliminate the comparison and maintains anti-aliasing up to infinite gain.

Here's the demonstration. Regular tanh is first, then the previous code, then the new one.

The only remaining problem is dealing with the 1/2 sample delay and inherent low-pass effect.

Code:

desc:Tanh AA
in_pin:left input
in_pin:right input
out_pin:left output
out_pin:right output
slider1:0<-6,24,1>Gain (dB)
slider2:0<-18,0,1>Ceiling (dB)
slider3:1<0,1,1>Antialias?
@slider
gain = 10^(slider1/20);
ceiling = 10^(-slider2/20);
inv_ceiling = 10^(slider2/20);
@sample
function F0(x)
(
abs(x) - log(2/(1 + exp(-2*abs(x))));
);
function tanh(x)
(
2/(1 + exp(-2*x)) - 1;
);
function antialiased_tanh_rect(x)
local(eps, F0_xn)
instance(xnm1, F0_xnm1, out)
(
F0_xn = F0(x);
eps = 0.0000000001;
out = eps < abs(x - xnm1) ? (F0_xn - F0_xnm1)/(x - xnm1) : tanh(0.5*(x+xnm1));
F0_xnm1 = F0_xn;
xnm1 = x;
out;
);
spl0 *= gain;
spl1 *= gain;
spl0 *= ceiling;
spl1 *= ceiling;
slider3 ? (
spl0 = ch0.antialiased_tanh_rect(spl0);
spl1 = ch1.antialiased_tanh_rect(spl1);
) : (
spl0 = tanh(spl0);
spl1 = tanh(spl1);
);
spl0 *= inv_ceiling;
spl1 *= inv_ceiling;