|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- ;;; this is a translation to Snd (from CLM's prc-toolkit95.lisp)
- ;;; of Perry Cook's Physical Modelling Toolkit.
-
- (provide 'snd-prc95.scm)
- (if (provided? 'snd)
- (require snd-ws.scm)
- (require sndlib-ws.scm))
-
-
- (define* (make-reed (offset 0.6) (slope -0.8))
- (float-vector offset slope))
-
- (define (reedtable r samp)
- (min 1.0 (+ (r 0) (* (r 1) samp))))
-
- (define* (make-bowtable (offset 0.0) (slope 1.0))
- (float-vector offset slope))
-
- (define (bowtable b samp)
- (max 0.0 (- 1.0 (abs (* (b 1) (+ samp (b 0)))))))
-
- (define (jettable samp)
- (max -1.0 (min 1.0 (* samp (- (* samp samp) 1.0)))))
-
- (define* (make-onezero (gain 0.5) (zerocoeff 1.0))
- (make-one-zero gain (* gain zerocoeff)))
-
- (define* (make-onep (polecoeff 0.9))
- (make-one-pole (- 1.0 polecoeff) (- polecoeff)))
-
- (define (set-pole p val)
- (set! (mus-ycoeff p 1) (- val))
- (set! (mus-xcoeff p 0) (- 1.0 val)))
-
- (define (set-gain p val)
- (set! (mus-xcoeff p 0) (* (mus-xcoeff p 0) val)))
-
-
- (define (lip-set-freq b freq)
- (set! (mus-frequency b) freq))
-
- (define (lip b mouthsample boresample)
- (let ((temp (formant b (- mouthsample boresample))))
- (set! temp (min 1.0 (* temp temp)))
- (+ (* temp mouthsample) (* (- 1.0 temp) boresample))))
-
-
- (define (make-dc-block)
- (float-vector 0.0 0.0))
-
- (define (dc-block b samp)
- (set! (b 1) (- (+ samp (* 0.99 (b 1))) (b 0)))
- (set! (b 0) samp)
- (b 1))
- ;; we could also use a filter generator here: (make-filter 2 (float-vector 1 -1) (float-vector 0 -0.99))
-
-
- ;;; this ia a 0-based versions of the clm delays
- (defgenerator dlya (outp 0) (input #f))
-
- (define (make-delayl len lag)
- ;; Perry's original had linear interp bug, I think -- this form is more in tune
- (make-dlya :input (make-delay len :max-size (ceiling (+ len lag 1)))
- :outp (- lag len)))
-
- (define (delayl d samp)
- (delay-tick (d 'input) samp)
- (tap (d 'input) (d 'outp)))
-
-
-
- ;;; now some example instruments
-
- (definstrument (plucky beg dur freq amplitude maxa)
- ;; (with-sound () (plucky 0 .3 440 .2 1.0))
-
- (let ((len (+ 1 (floor (/ *clm-srate* 100.0))))) ; 100 = lowest freq
- (let ((delayline (make-delayl len (- (/ *clm-srate* freq) 0.5)))
- (filt (make-onezero))
- (start (seconds->samples beg))
- (end (seconds->samples (+ beg dur)))
- (dout 0.0))
- (do ((i 0 (+ i 1)))
- ((= i len))
- (set! dout (delayl delayline (+ (* 0.99 dout) (mus-random maxa)))))
- (do ((i start (+ i 1)))
- ((= i end))
- (set! dout (delayl delayline (one-zero filt dout)))
- (outa i (* amplitude dout))))))
-
-
- ;;; freq is off in this one (in prc's original also)
- (definstrument (bowstr beg dur frq amplitude maxa)
- ;; (with-sound () (bowstr 0 .3 220 .2 1.0))
-
- (let ((len (+ 1 (floor (/ *clm-srate* 100.0))))) ; 100 = lowest freq
- (let ((ratio 0.8317)
- (rate .001)
- (bowing #t)
- (temp (- (/ *clm-srate* frq) 4.0)))
- (let ((neckdelay (make-delayl len (* temp ratio)))
- (bridgedelay (make-delayl (floor (/ len 2)) (* temp (- 1.0 ratio))))
- (bowtab (make-bowtable :slope 3.0))
- (filt (make-onep))
- (bowvelocity rate)
- (maxvelocity maxa)
- (attackrate rate)
- (st (seconds->samples beg))
- (end (seconds->samples (+ beg dur)))
- (release (seconds->samples (* .8 dur)))
- (ctr 0)
- (bridgeout 0.0)
- (neckout 0.0))
-
- (set-pole filt 0.6)
- (set-gain filt 0.3)
-
- (do ((i st (+ i 1))
- (bridgerefl 0.0 0.0)
- (nutrefl 0.0 0.0)
- (veldiff 0.0 0.0)
- (stringvel 0.0 0.0)
- (bowtemp 0.0 0.0))
- ((= i end))
- (if bowing
- (if (not (= maxvelocity bowvelocity))
- (set! bowvelocity ((if (< bowvelocity maxvelocity) + -) bowvelocity attackrate)))
- (if (> bowvelocity 0.0)
- (set! bowvelocity (- bowvelocity attackrate))))
- (set! bowtemp (* 0.3 bowvelocity))
- (let ((filt-output (one-pole filt bridgeout)))
- (set! bridgerefl (- filt-output))
- (set! nutrefl (- neckout))
- (set! stringvel (+ bridgerefl nutrefl))
- (set! veldiff (- bowtemp stringvel))
- (set! veldiff (* veldiff (bowtable bowtab veldiff)))
- (set! neckout (delayl neckdelay (+ bridgerefl veldiff)))
- (set! bridgeout (delayl bridgedelay (+ nutrefl veldiff)))
- (outa i (* amplitude 10.0 filt-output))
- (if (= ctr release)
- (begin
- (set! bowing #f)
- (set! attackrate .0005)))
- (set! ctr (+ ctr 1))))))))
-
-
- (definstrument (brass beg dur freq amplitude maxa)
- ;; does this work at all?
- (let ((len (+ 1 (floor (/ *clm-srate* 100.0)))))
- (let ((blowing #t)
- (rate .001)
- (breathpressure 0.0)) ; 0.1 ?
- (let ((delayline (make-delayl len (+ 1.0 (/ *clm-srate* freq))))
- (lipfilter (make-formant freq))
- (dcblocker (make-dc-block))
- (maxpressure maxa)
- (attackrate rate)
- (st (seconds->samples beg))
- (end (seconds->samples (+ beg dur)))
- (release (seconds->samples (* .8 dur)))
- (ctr 0)
- (dout 0.0))
- (do ((i st (+ i 1)))
- ((= i end))
- (if blowing
- (if (not (= maxpressure breathpressure))
- (set! breathpressure ((if (< breathpressure maxpressure) + -) breathpressure attackrate)))
- (if (> breathpressure 0.0)
- (set! breathpressure (- breathpressure attackrate))))
- (set! dout (delayl delayline (dc-block dcblocker
- (lip lipfilter
- (* 0.3 breathpressure)
- (* 0.9 dout)))))
- (outa i (* amplitude dout))
- (if (= ctr release)
- (begin
- (set! blowing #f)
- (set! attackrate .0005)))
- (set! ctr (+ ctr 1)))))))
-
-
- (definstrument (clarinet beg dur freq amplitude maxa)
- ;; (with-sound () (clarinet 0 .3 440 .2 1.0))
-
- (let ((len (+ 1 (floor (/ *clm-srate* 100.0)))))
- (let ((blowing #t)
- (breathpressure 0.0) ; 0.1 ?
- (rate .001))
- (let ((delayline (make-delayl len (- (* 0.5 (/ *clm-srate* freq)) 1.0)))
- (rtable (make-reed :offset 0.7 :slope -0.3))
- (filt (make-onezero))
- (maxpressure maxa)
- (attackrate rate)
- (st (seconds->samples beg))
- (end (seconds->samples (+ beg dur)))
- (ctr 0)
- (release (seconds->samples (* .8 dur)))
- (dlyout 0.0))
- (do ((i st (+ i 1)))
- ((= i end))
- (if blowing
- (if (not (= maxpressure breathpressure))
- (set! breathpressure ((if (< breathpressure maxpressure) + -) breathpressure attackrate)))
- (if (> breathpressure 0.0)
- (set! breathpressure (- breathpressure attackrate))))
- (let ((pressurediff (- (one-zero filt (* -0.95 dlyout)) breathpressure)))
- (set! dlyout (delayl delayline
- (+ breathpressure
- (* pressurediff
- (reedtable rtable pressurediff))))))
- (outa i (* amplitude dlyout))
- (if (= ctr release)
- (begin
- (set! blowing #f)
- (set! attackrate .0005)))
- (set! ctr (+ ctr 1)))))))
-
-
- (definstrument (flute beg dur freq amplitude maxa)
- ;; (with-sound () (flute 0 .3 440 .2 1.0))
-
- (let ((len (+ 1 (floor (/ *clm-srate* 100.0)))))
- (let ((jetrefl 0.6)
- (endrefl 0.6)
- (sinphase 0.0)
- (blowing #t)
- (rate .0005)
- (breathpressure 0.0) ; 0.1 ?
- (ratio 0.8)
- (temp (- (/ *clm-srate* freq) 5.0)))
- (let ((jetdelay (make-delayl (floor (/ len 2)) (* temp (- 1.0 ratio))))
- (boredelay (make-delayl len (* ratio temp)))
- (filt (make-onep))
- (dcblocker (make-dc-block))
- (maxpressure maxa)
- (attackrate rate)
- (st (seconds->samples beg))
- (end (seconds->samples (+ beg dur)))
- (ctr 0)
- (release (seconds->samples (* .8 dur)))
- (boreout 0.0))
- (set-pole filt 0.8)
- (set-gain filt -1.0)
- (do ((i st (+ i 1)))
- ((= i end))
- (let ((randpressure (random (* 0.1 breathpressure))))
- (set! sinphase (+ sinphase 0.0007)) ;5 hz vibrato?
- (if (> sinphase 6.28) (set! sinphase (- sinphase 6.28)))
- (set! randpressure (+ randpressure (* 0.05 breathpressure (sin sinphase))))
- (if blowing
- (if (not (= maxpressure breathpressure))
- (set! breathpressure ((if (< breathpressure maxpressure) + -) breathpressure attackrate)))
- (if (> breathpressure 0.0)
- (set! breathpressure (- breathpressure attackrate))))
- (let ((pressurediff (let ((temp (dc-block dcblocker (one-pole filt boreout))))
- (+ (jettable (delayl jetdelay (- (+ breathpressure randpressure) (* jetrefl temp))))
- (* endrefl temp)))))
- (set! boreout (delayl boredelay pressurediff)))
- (outa i (* 0.3 amplitude boreout))
- (if (= ctr release)
- (begin
- (set! blowing #f)
- (set! attackrate .0005)))
- (set! ctr (+ ctr 1))))))))
-
- #|
- (with-sound ()
- (plucky 0 .3 440 .2 1.0)
- (bowstr .5 .3 220 .2 1.0)
- (brass 1 .3 440 .2 1.0)
- (clarinet 1.5 .3 440 .2 1.0)
- (flute 2 .3 440 .2 1.0))
- |#
-
|