As an illustration of my newly-released software I dug through the
recent archive for something that would be easy and fun to implement
in Moselle, and came across this post from forum stalwart Robert
Bistow-Johnson.

The following is a Moselle program (or "patch") that implements the
first half-dozen functions in Robert's series of soft-clippers.  MIDI
general controller 1 selects which clipping function to use, while
general controller 2 selects the waveform to input.  (The oscillator
is spec'd as an LFO as the LFO doesn't scale its amplitude with pitch,
which saved me a bit of typing.)  Each of the functions is repeated in
the Oscilloscope module so they can all be seen simultaneously, even
though only one is heard at a time.

See a screenshot of the Oscilloscope with waveforms and harmonic
spectrum at: 
http://moselle.invisionzone.com/uploads/gallery/album_1/gallery_1_1_12533.gif

The self-contained Moselle IDE is available for no-cost download at:
http://moselle.invisionzone.com/index.php?/files/file/2-moselle-alpha-release

The following is literally the Moselle patch that produced the
screenshot (and woke up my wife while I was jamming with it).

[LFO]
Waveform = Select( General2, Sawtooth, Triangle, Sine)
Frequency = Voice:Frequency

[Voice]
Mono = IF( LFO < -1, -1,
           LFO >  1,  1,
           Select( General1,
   LFO,
   (LFO - 1 * LFO^3/3
       )*3/2,
   (LFO - 2 * LFO^3/3 +  1 * LFO^5/5
       )*15/8,
   (LFO - 3 * LFO^3/3 +  3 * LFO^5/5 -  1 * LFO^7/7
       )*35/16,
   (LFO - 4 * LFO^3/3 +  6 * LFO^5/5 -  4 * LFO^7/7 + 1 * LFO^9/9
       )*315/128,
   (LFO - 5 * LFO^3/3 + 10 * LFO^5/5 - 10 * LFO^7/7 + 5 * LFO^9/9 -
LFO^11/11 )*3465/1280
   )

[Scope]
Probe1 = LFO
Probe2 = (LFO - 1 * LFO^3/3
             )*3/2
Probe3 = (LFO - 2 * LFO^3/3 +  1 * LFO^5/5
             )*15/8
Probe4 = (LFO - 3 * LFO^3/3 +  3 * LFO^5/5 -  1 * LFO^7/7
             )*35/16
Probe5 = (LFO - 4 * LFO^3/3 +  6 * LFO^5/5 -  4 * LFO^7/7 + 1 *
LFO^9/9             )*315/128
Probe6 = (LFO - 5 * LFO^3/3 + 10 * LFO^5/5 - 10 * LFO^7/7 + 5 *
LFO^9/9 - LFO^11/11 )*3465/1280
Probe7 = Voice:Mono
Start       = LFO:SyncOut
Stop        = LFO:SyncOut
FreqHint    = LFO:Frequency


> 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.
--
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