;; code_6.sal -- examples for "Programming Techniques" lecture define function drum-stroke() return noise() * pwev(1, 0.05, 0.1) define function drum-roll() return seq(drum-stroke(), drum-roll()) define function limited-drum-roll() return const(1, 3) * drum-roll() ; duration = 3 ;play limited-drum-roll() * pwev(0.1, 2, 1, 3, 0.01) ;============================================ ; a simple vibrato function ; ;play fmosc(gs4, 10 * lfo(6)) ~ 3 ; a vibrato function that begins gradually ; define function smooth-vibrato() return pwl(0.5, 1, 0.9, 1, 1) * lfo(6) ;play fmosc(a4, 10 * smooth-vibrato()) ~ 3 ; it's still ugly because there is no amplitude control define function envelope-tone(p) return pwl(0.1, 1, 0.8, 0.4, 1) * fmosc(p, 10 * smooth-vibrato()) ;play envelope-tone(as4) ~ 3 ; let's give it a richer waveform define variable *mytable* = sim(0.5 * build-harmonic(1, 2048), 0.2 * build-harmonic(2, 2048), 0.1 * build-harmonic(3, 2048), 0.2 * build-harmonic(4, 2048), 0.4 * build-harmonic(5, 2048), 0.2 * build-harmonic(6, 2048), 0.1 * build-harmonic(7, 2048)) set *mytable* = list(*mytable*, hz-to-step(1.0), T) define function envelope-tone-2(p) return pwl(0.2, 1, 0.9, 0.4, 1) * fmosc(p, 10 * smooth-vibrato(), *mytable*) ;play envelope-tone-2(b4) ~ 3 ; now add a time varying filter to avoid the static spectrum define function filtered-tone(p) return lp(envelope-tone-2(p), pwev(100, 0.5, 10000, 1, 100)) ;play filtered-tone(c5) ~ 3 ; revise the previous tone by adding low frequency noise ; to the vibrato function ; ; we will simply redefine smooth-vibrato here and rerun ; the the last play command: ; ; you control the speed of random number updates using ; sound-srate-abs (currently 10 updates/second) and the ; amount of randomness (amplitude) using scale (currently ; 0.5) ; ; When the low sample rate noise is added (via sim) to the ; enveloped lfo signal, it will be upsampled by linear interpolation ; to the *control-srate* sample rate of 2205Hz ; define function smooth-vibrato-3() return sim(1 * sound-srate-abs(10, noise()), 0.5 * pwl(0.5, 1, 0.9, 1, 1) * lfo(6)) define function envelope-tone-3(p) return pwl(0.1, 1, 0.8, 0.4, 1) * fmosc(p, 10 * smooth-vibrato-3(), *mytable*) define function filtered-tone-3(p) return lp(envelope-tone-3(p), pwev(100, 0.3, 10000, 1, 1000)) ;play filtered-tone-3(c5) ~ 3 ; Control functions can span many notes/events or apply to ; just one here are two examples. The first uses a new ; frequency rise behavior (fmod) on each tone in a sequence: define function fmod() return pwl(0.5, 1, 1) ; linear rise and fall define function vib-tone(p) return pwl(0.1, 1, 0.8, 0.4, 1) * fmosc(p, 40 * fmod(), *mytable*) ;play seq(vib-tone(f4), vib-tone(g4), vib-tone(fs4)) ; Next, one (fmod) function spans all three tones ; note that you MUST stretch smooth-vibrato to the necessary ; length. Also, since FMOSC gets its duration from the ; modulation function, we have to "shorten" the vibrato ; signal seen by each tone to the nominal duration of 1.0s ; This is done by multiplying by an instance of (const 40), ; a signal with the value 10 for 1 second: define function vib-tone-2(p, vib) return pwl(0.1, 1, 0.8, 0.4, 1) * fmosc(p, const(40) * vib, *mytable*) define function vib-sequence() begin with vib = fmod() ~ 3 return seq(vib-tone-2(f4, vib), vib-tone-2(g4, vib), vib-tone-2(fs4, vib)) end ;play vib-sequence() ;; lets try that with vibrato intensity ;; define function envelope-tone-4(p, vib-intensity) return pwl(0.1, 1, 0.8, 0.4, 1) * fmosc(p, vib-intensity * smooth-vibrato(), *mytable*) define function filtered-tone-4(p, vib-intensity) return lp(envelope-tone-4(p, vib-intensity), pwev(100, 0.3, 10000, 1, 1000)) ;; vibrato intensity increases to near the end of the second note ;; then decreases to the end ;; ;; also, a global gain control makes the last note softer ;; define function global-vib-intensity-demo() begin with vib-intensity = pwlv(0, 5, 6, 9, 2), global-amplitude = pwev(1, 5, 1, 9, 0.3) return global-amplitude * seq(filtered-tone-4(f4, vib-intensity), filtered-tone-4(g4, vib-intensity), filtered-tone-4(fs4, vib-intensity)) ~ 3 end ;play global-vib-intensity-demo()