;; pat-fm-note.sal -- pattern modulation encapsulated as a single note ;; (c) 2008 by Roger B. Dannenberg ;; pat-ctrl is copied from pat-ctrl.sal ;; It creates a control function from a pattern define function pat-ctrl(durpat, valpat) return seq(const(next(valpat), next(durpat)), pat-ctrl(durpat, valpat)) ;; pat-fm is copied from pat-fm.sal ;; It creates a tone with duration and frequency controlled by patterns define function pat-fm(durpat, valpat, pitch, dur) begin with hz = step-to-hz( pitch + pat-ctrl(durpat, valpat)) return pwl(0.01, 1, dur - 0.1, 1, dur) * hzosc(hz + 4.0 * hz * hzosc(hz)) end ;; pat-fm-note is a note that can be invoked from a score ;; This function is based on pat-fm-complex.sal ;; define function pat-fm-note(grain-dur: 1.0, spread: 20, pitch: c4, fixed-dur: nil, vel: 100) begin with durpat = make-product( make-copier( make-random( #?(fixed-dur, {0.01}, {0.005 0.01 0.02 0.0025}), for: 1), repeat: 10), grain-dur), valpat = make-sum( make-copier( ; long-term changes make-accumulate( make-random( {-4 0 1 2 3 {-24 :weight 0.06}}), for: 1, min: - spread, max: spread), repeat: make-product( make-random({1 2 3}), 20)), ; short-term changes for make-sum make-heap({0 3 5 6 7 9})), duration = get-duration(1.0) return stretch-abs(1.0, vel * 0.01 * pat-fm(durpat, valpat, pitch, duration)) end ;; here is a simple test, a sequence of two pat-fm-notes play seq(pat-fm-note(), s-rest(), pat-fm-note(pitch: c5))