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.
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)))))
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.
See Other Sounds Using Ring in Vinal Scratch Tutorial for another example.