(provide 'snd-v.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define default-index-env (float-vector 0 1 25 .4 75 .6 100 0)) (define default-amp-env (float-vector 0 0 25 1 75 1 100 0)) (define default-gliss-env (float-vector 0 0 100 0)) (definstrument (fm-violin startime dur frequency amplitude (fm-index 1.0) amp-env (periodic-vibrato-rate 5.0) (random-vibrato-rate 16.0) (periodic-vibrato-amplitude 0.0025) (random-vibrato-amplitude 0.005) (noise-amount 0.0) (noise-freq 1000.0) (ind-noise-freq 10.0) (ind-noise-amount 0.0) (amp-noise-freq 20.0) (amp-noise-amount 0.0) (gliss-env default-gliss-env) (glissando-amount 0.0) fm1-env fm2-env fm3-env (fm1-rat 1.0) (fm2-rat 3.0) (fm3-rat 4.0) fm1-index fm2-index fm3-index degree (distance 1.0) (reverb-amount 0.01) (base 1.0)) "(fm-violin startime dur frequency amplitude (fm-index 1.0) (amp-env '(0 0 25 1 75 1 100 0)) (periodic-vibrato-rate 5.0) (random-vibrato-rate 16.0) (periodic-vibrato-amplitude 0.0025) (random-vibrato-amplitude 0.005) (noise-amount 0.0) (noise-freq 1000.0) (ind-noise-freq 10.0) (ind-noise-amount 0.0) (amp-noise-freq 20.0) (amp-noise-amount 0.0) (gliss-env '(0 0 100 0)) (glissando-amount 0.0) (fm1-env '(0 1 25 .4 75 .6 100 0)) (fm2-env '(0 1 25 .4 75 .6 100 0)) (fm3-rat 4.0) (fm3-env '(0 1 25 .4 75 .6 100 0)) (fm1-rat 1.0) (fm2-rat 3.0) (fm1-index #f) (fm2-index #f) (fm3-index #f) (degree #f) (distance 1.0) (reverb-amount 0.01) (base 1.0)) (with-sound () (fm-violin 0 1 440 .1))" (let ((beg (seconds->samples startime)) (end (seconds->samples (+ startime dur))) (frq-scl (hz->radians frequency)) (logfreq (log frequency)) (sqrtfreq (sqrt frequency)) (maxdev (* (hz->radians frequency) fm-index))) (if (>= (* 2 fm1-rat frequency) *clm-srate*) (set! fm1-rat 1.0)) (if (>= (* 2 fm2-rat frequency) *clm-srate*) (set! fm2-rat 1.0)) (if (>= (* 2 fm3-rat frequency) *clm-srate*) (set! fm3-rat 1.0)) (let ((index1 (or fm1-index (min pi (* maxdev (/ 5.0 logfreq))))) (index2 (or fm2-index (min pi (/ (* maxdev 3.0 (- 8.5 logfreq)) (+ 3.0 (* frequency 0.001)))))) (index3 (or fm3-index (min pi (* maxdev (/ 4.0 sqrtfreq))))) (easy-case (and (zero? noise-amount) (equal? fm1-env fm2-env) (equal? fm1-env fm3-env) (= fm1-rat (floor fm1-rat)) (= fm2-rat (floor fm2-rat)) (= fm3-rat (floor fm3-rat)) (integer? (rationalize (/ fm2-rat fm1-rat))) ; might be 2=2 but 1=3 or whatever (integer? (rationalize (/ fm3-rat fm1-rat)))))) (let ((norm (if easy-case 1.0 index1))) (let ((fmosc1 (if easy-case (make-polywave (* fm1-rat frequency) (list (floor fm1-rat) index1 (floor (/ fm2-rat fm1-rat)) index2 (floor (/ fm3-rat fm1-rat)) index3) mus-chebyshev-second-kind) (make-oscil (* fm1-rat frequency)))) (indf1 (make-env (or fm1-env default-index-env) norm :duration dur)) (indf2 (or easy-case (make-env (or fm2-env default-index-env) index2 :duration dur))) (indf3 (or easy-case (make-env (or fm3-env default-index-env) index3 :duration dur))) (frqf (make-env gliss-env (* glissando-amount frq-scl) :duration dur)) (pervib (make-triangle-wave periodic-vibrato-rate (* periodic-vibrato-amplitude frq-scl))) (ranvib (make-rand-interp random-vibrato-rate (* random-vibrato-amplitude frq-scl))) (fm-noi (and (not (zero? noise-amount)) (make-rand noise-freq (* pi noise-amount)))) (ind-noi (and (not (zero? ind-noise-amount)) (not (zero? ind-noise-freq)) (make-rand-interp ind-noise-freq ind-noise-amount))) (amp-noi (and (not (zero? amp-noise-amount)) (not (zero? amp-noise-freq)) (make-rand-interp amp-noise-freq amp-noise-amount))) (carrier (make-oscil frequency)) (fmosc2 (if (not easy-case) (make-oscil (* fm2-rat frequency)))) (fmosc3 (if (not easy-case) (make-oscil (* fm3-rat frequency)))) (ampf (make-env (or amp-env default-amp-env) :scaler amplitude :base base :duration dur)) (locs (make-locsig (or degree (random 90.0)) distance reverb-amount))) (if (or (not easy-case) ind-noi amp-noi fm-noi) (let ((fuzz 0.0) (vib 0.0) (anoi 1.0) (inoi 1.0)) (if easy-case ; no fm-noi here (do ((i beg (+ i 1))) ((= i end)) (if amp-noi (set! anoi (* (env ampf) (+ 1.0 (rand-interp amp-noi)))) (set! anoi (env ampf))) (if ind-noi (set! inoi (+ 1.0 (rand-interp ind-noi)))) (set! vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib))) (locsig locs i (* anoi (oscil carrier (+ vib (* inoi (env indf1) (polywave fmosc1 vib))))))) (if (or ind-noi amp-noi fm-noi) (if (not (or ind-noi amp-noi)) (do ((i beg (+ i 1))) ((= i end)) (let ((fuzz (rand fm-noi)) (vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib)))) (locsig locs i (* (env ampf) (oscil carrier (+ vib (+ (* (env indf1) (oscil fmosc1 (+ (* fm1-rat vib) fuzz))) (* (env indf2) (oscil fmosc2 (+ (* fm2-rat vib) fuzz))) (* (env indf3) (oscil fmosc3 (+ (* fm3-rat vib) fuzz)))))))))) (do ((i beg (+ i 1))) ((= i end)) (if fm-noi (set! fuzz (rand fm-noi))) (if amp-noi (set! anoi (* (env ampf) (+ 1.0 (rand-interp amp-noi)))) (set! anoi (env ampf))) (if ind-noi (set! inoi (+ 1.0 (rand-interp ind-noi)))) (set! vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib))) (locsig locs i (* anoi (oscil carrier (+ vib (* inoi (+ (* (env indf1) (oscil fmosc1 (+ (* fm1-rat vib) fuzz))) (* (env indf2) (oscil fmosc2 (+ (* fm2-rat vib) fuzz))) (* (env indf3) (oscil fmosc3 (+ (* fm3-rat vib) fuzz))))))))))) (do ((i beg (+ i 1))) ((= i end)) (let ((vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib)))) (locsig locs i (* (env ampf) (oscil carrier (+ vib (+ (* (env indf1) (oscil fmosc1 (* fm1-rat vib))) (* (env indf2) (oscil fmosc2 (* fm2-rat vib))) (* (env indf3) (oscil fmosc3 (* fm3-rat vib))))))))))))) (if (= (mus-scaler frqf) 0.0) (do ((i beg (+ i 1))) ((= i end)) (let ((vib (+ (triangle-wave pervib) (rand-interp ranvib)))) (locsig locs i (* (env ampf) (oscil carrier (+ vib (* (env indf1) (polywave fmosc1 vib)))))))) (do ((i beg (+ i 1))) ((= i end)) (let ((vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib)))) (locsig locs i (* (env ampf) (oscil carrier (+ vib (* (env indf1) (polywave fmosc1 vib))))))))))))))) ;; (with-sound (:statistics #t) (fm-violin 0 10 440 .1 :fm-index 2.0)) ;; (with-sound (:statistics #t) (fm-violin 0 10 440 .1 :noise-amount .01)) ;; (with-sound (:statistics #t) (fm-violin 0 10 440 .1 :ind-noise-amount .01)) ;; (with-sound (:statistics #t) (fm-violin 0 10 440 .1 :fm1-rat 1.002))