# Warble Tutorial

The warble function by Alex illustrates the use of AM and FM oscillators to create an "analog" electronic synthesizer sound.

Note: all examples use SAL syntax followed by Lisp syntax in a smaller font. Since SAL does not support optional parameters, keyword parameters are used instead, so these implementations are not exactly equivalent.

    function warble(dur: 1, pch: 60)
      return (env(0.017, 0.1, 0.004, 1, 0.7, 0.8, 1) *
              amosc(pch, fmosc(hz-to-step(8),
                               pwl(0, 4, 0.2, -4, 0.56, 9, 0.7,
                                   0, 1, -8, 1))) +
              env(0.2, 0.09, 0.07, 0.92, 0.8, 0.6, 1) ~ 0.96 *
              amosc(pch, fmosc(pch * 1.414,
                               pwl(0.2, 80, 0.5, 4, 0.9,
                                   1120, 1, 200, 1)))) ~ dur

    (defun warble (&optional (dur 1) (pch 60))
      (stretch dur
        (sum (mult
               (env 0.017 0.1 0.004 1 0.7 0.8 1)
               (amosc pch (fmosc (hz-to-step 8)
                                 (pwl 0 4 0.2 -4 0.56 9 0.7 0 1 -8 1))))
             (mult (stretch 0.96 (env 0.2 0.09 0.07 0.92 0.8 0.6 1))
                   (amosc pch (fmosc (* pch 1.414)
                                     (pwl 0.2 80 0.5 4 0.9 1120 1 200 1)))))))

This sound is the sum of two components. Each of these components is the product of an envelope (`env`) and an AM oscillator (`amosc`). The first one modulates the AM oscillator with a low frequency (about 8 Hz) sinusoid produced by an FM oscillator. The modulator varies in frequency according to a piece-wise linear envelope.

The second component is similar, but uses a much higher modulating frequency in the audio range, producing a ring-modulation effect. Another piece-wise linear envelope sweeps the modulator frequency by as much as 1120 Hz.

## Thicker Texture

A thicker texture can be obtained by playing copies of warble together with slight parameter changes. Here is an example:

    function thicker()
      return sim(0.5 * warble(dur: 8, pch: 48) @ 0.0,
                 0.3 * warble(dur: 8.05, pch: 47.9) @ 0.05)

    (defun thicker ()
      (sim (scale 0.5 (at 0.00 (warble 8 48)))
           (scale 0.3 (at 0.05 (warble 8.05 47.9)))))

## Another FM Sound

The following produces another analog-sounding FM texture:

    function mod(dur)
      return (pwl(0, 1000, 0.2, 200, 0.5, 8000, 1, 100, 1) *
    	  fmosc(c4, pwl(0, 1, 0.5, 3.25, 1, 0.74, 1)) ~ dur

    function blurp(dur)
      return fmosc(c3, osc(7, dur) * mod(dur))

    (defun mod (dur)
      (stretch dur
        (mult (pwl 0 1000 .2 200 .5 8000 1 100 1)
    	  (fmosc c4 (pwl 0 1 .5 3.25 1 .74 1)))))

    (defun blurp (dur)
      (fmosc c3 (mult (osc 07 dur) (mod dur))))

This example relies on a combination of AM and FM: the output is from an FM oscillator, but its modulator is formed by multiplying (AM) two oscillators. The first is low frequency (about 12 Hz), giving a warbling sound, and the second, generated by `(mod dur)`, is another FM oscillator. It appears that the modulation generated by the piece-wise linear function is almost insignificant. You might try scaling the expression (pwl 0 1 .5 3.25 1 .74 1) in `mod` by varying amounts to see what happens.

The original duration of `blurp` was 3.1 (seconds), but longer versions are interesting and reveal more detail.

## Yet Another Sound

See Other Sounds Using Ring in Vinal Scratch Tutorial for another example.