This reminds me of experimenting with polynomials as an amplitude enveloping 
function for a soft synthesiser. There was something rather alluring about the 
idea of a one-line-of-code amplitude envelope - unfortunately it made creating 
the envelopes pretty tiresome, and when I thought about the performance I 
realised it was probably slower to do that maths than the few conditionals you 
would use for a standard piecewise envelope. So basically a rubbish idea unless 
you have some strange need to have your amplitude envelope be a single line of 
code :I


-----Original Message-----
From: music-dsp-boun...@music.columbia.edu 
[mailto:music-dsp-boun...@music.columbia.edu] On Behalf Of robert 
bristow-johnson
Sent: 29 October 2013 01:56
To: music-dsp@music.columbia.edu
Subject: [music-dsp] family of soft clipping functions.


at the last AES in NYC, i was talking with some other folks (that likely hang 
out here, too) about this family of soft clipping curves made outa polynomials 
(so you have some idea of how high in frequency any generated images will 
appear).

these are odd-order, odd-symmetry polynomials that are monotonic from -1 < x < 
+1 and have as many continuous derivatives as possible at +/- 1 where these 
curves might be spliced to constant-valued rails.

the whole idea is to integrate the even polynomial  (1 - x^2)^N

                     x
      g(x)  =  integral{ (1 - v^2)^N dv}
                     0

you figger this out using binomial expansion and integrating each power term.

normalize g(x) with whatever g(1) is so that the curve is g(x)/g(1) and splice 
that to two constant functions for the rails

               { -1                    x <= -1
               {
      f(x)  =  { g(x)/g(1)       -1 <= x <= +1
               {
               { +1              +1 <= x


you can "hard limit" (at +/- 1) before passing through this soft clipper and it 
still works fine.  but it has some gain in the "linear" region which is g(0).


if you want to add some "even harmonic distortion" to this, add a little bit of

     (1 - x^2)^M

to f(x)  for |x| < 1 and it's still smooth everywhere, but there is a little DC 
added (which has to be the case for even-symmetry distortion). 
  M does not have to be the same as N and i wouldn't expect it to be.



you can think of f(x) as a smooth approximation the "sign" or "signum" 
function

       sgn(x)  =   lim           f(a*x)
                  a -> +inf

or

       sgn(x)  =   lim           f(x)
                  N -> +inf

which motivates using this as a smooth approximation of the sgn(x) 
function as an alternative to
   (2/pi)*arctan(a*x) or tanh(a*x).  from the sgn(x) function, you can 
create smooth versions of the unit step function and use that for 
splicing.  as many derivatives are continuous in the splice as possible. 
  and it satisfies conditions of symmetry and complementarity that are 
useful in our line of work.

      u(x)  =  1/2 * (1 + sgn(x))  =approx   1/2*(1 + f(x))

you can run a raised cosine (Hann) through this and get a more flattened 
Hann.  in some old stuff i wrote, i dubbed this window:


      w(x)  =  1/2  +  (9/16)*cos(pi*x) - (1/16)*cos(3*pi*x)


as the "Flattened Hann Window" but long ago Carla Scaletti called it the 
"Bristow-Johnson window" in some Kyma manual.  i don't think it deserves 
that label (i've seen that function in some wavelet/filterbank lit since 
for half-band filters).  you get that window by running a simple Hann 
through the biased waveshaper:

        1/2 * ( 1 + f(2x-1) )

with N=1.  you will get an even more pronounced effect (of smoothly 
flattening the Hann) with higher N.

below is a matlab file that demonstrates this as a soft clipping function.

BTW, Olli N, this can be integrated with that "splicing theory" thing we 
were talking about approximately a year ago.  it would define the 
"odd-symmetry" component.  we should do an AES paper about this.  i 
think now there is nearly enough "meat" to make a decent paper.  before 
i didn't think so.


________________________________________________________________________

  FILE:  softclip.m

line_color = ['g' 'c' 'b' 'm' 'r'];

figure;
hold on;

x = linspace(-2, 2, 2^18 + 1);

x = max(x, -1);         % hard clip for |x|>  1
x = min(x, +1);

for N = 0:10

        n = linspace(0, N, N+1);

        a = (-1).^n ./ (factorial(N-n) .* factorial(n) .* (2*n + 1));

        a = a/sum(a);

        y = x .* polyval(fliplr(a), x.^2);      % stupid MATLAB puts the coefs 
in the wrong order

        plot(x, y, line_color(mod(N,length(line_color))+1) );

end

hold off;

________________________________________________________________________



have fun with it, if you're so inclined.

L8r,

-- 

r b-j                  r...@audioimagination.com

"Imagination is more important than knowledge."



--
dupswapdrop -- the music-dsp mailing list and website:
subscription info, FAQ, source code archive, list archive, book reviews, dsp 
links
http://music.columbia.edu/cmc/music-dsp
http://music.columbia.edu/mailman/listinfo/music-dsp
--
dupswapdrop -- the music-dsp mailing list and website:
subscription info, FAQ, source code archive, list archive, book reviews, dsp 
links
http://music.columbia.edu/cmc/music-dsp
http://music.columbia.edu/mailman/listinfo/music-dsp

Reply via email to