Skip to content

Instantly share code, notes, and snippets.

@catfact
Last active July 8, 2019 19:06
Show Gist options
  • Save catfact/5ab4589156432c09a2cf9154b5368b9a to your computer and use it in GitHub Desktop.
Save catfact/5ab4589156432c09a2cf9154b5368b9a to your computer and use it in GitHub Desktop.
tanc clipper
function y = tanc(x, a)
g = 1 - a;
y = 1 - g * (1 - tanhx((x - a) / g));
endfunction
% positive softclipper using "tanc" shaper
% t = limit threshold
% w = limit knee width
function y = tanc_softclip_pos(x, t, w)
a = 1/w;
lim = x/t;
if lim > a
y = lim;
else
y = tanc(a, min(max(lim, 0), 10));
endif
endfunction
n = 64;
x = linspace(-1, 1, n);
t = 0.5;
w = 0.2;
y = zeros(n);
for i=1:n
if x(i) < 0
y(i) = tanc_softclip_pos(x(i)*-1, t, w) * -1;
else
y(i) = tanc_softclip_pos(x(i), t, w);
endif
endfor
plot(x, y);
% tanh approximation
function y = tanhx(x)
y = (1-exp(-2*x))/(1+exp(-2*x));
end
@catfact
Copy link
Author

catfact commented Jul 8, 2019

adapted from this faust code:

tanhx(x) = (1-exp(-2*x))/(1+exp(-2*x));
tanc(sharpness, x) = 1 - g * (1 - tanhx((x - sharpness) / g)) with {
 g = 1 - sharpness;
};

soft_clip_positive(lim_thresh, lim_knee_width, sig) = clipped  with {
 sharpness = 1 / lim_knee_width;
 clip = sig / lim_thresh > sharpness;
 clipping = tanc(sharpness, min(max(sig / lim_thresh, 0.0), 10.0));
 clipped = lim_thresh * select2(clip, sig / lim_thresh, clipping);
};

but i've missed or misinterpreted something. soft_clip_positive outputs a ratio of input to limit threshold, which should probably be rescaled?

currently outputs the following transfer func with lim_thresh = 0.5, lim_knee_width=0.2
(i may also be totally mis-estimating the correct range of these parameters)

tanc_transfer_wrong

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment