Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

275 lines
8.3KB

  1. ;;; this is a translation to Snd (from CLM's prc-toolkit95.lisp)
  2. ;;; of Perry Cook's Physical Modelling Toolkit.
  3. (provide 'snd-prc95.scm)
  4. (if (provided? 'snd)
  5. (require snd-ws.scm)
  6. (require sndlib-ws.scm))
  7. (define* (make-reed (offset 0.6) (slope -0.8))
  8. (float-vector offset slope))
  9. (define (reedtable r samp)
  10. (min 1.0 (+ (r 0) (* (r 1) samp))))
  11. (define* (make-bowtable (offset 0.0) (slope 1.0))
  12. (float-vector offset slope))
  13. (define (bowtable b samp)
  14. (max 0.0 (- 1.0 (abs (* (b 1) (+ samp (b 0)))))))
  15. (define (jettable samp)
  16. (max -1.0 (min 1.0 (* samp (- (* samp samp) 1.0)))))
  17. (define* (make-onezero (gain 0.5) (zerocoeff 1.0))
  18. (make-one-zero gain (* gain zerocoeff)))
  19. (define* (make-onep (polecoeff 0.9))
  20. (make-one-pole (- 1.0 polecoeff) (- polecoeff)))
  21. (define (set-pole p val)
  22. (set! (mus-ycoeff p 1) (- val))
  23. (set! (mus-xcoeff p 0) (- 1.0 val)))
  24. (define (set-gain p val)
  25. (set! (mus-xcoeff p 0) (* (mus-xcoeff p 0) val)))
  26. (define (lip-set-freq b freq)
  27. (set! (mus-frequency b) freq))
  28. (define (lip b mouthsample boresample)
  29. (let ((temp (formant b (- mouthsample boresample))))
  30. (set! temp (min 1.0 (* temp temp)))
  31. (+ (* temp mouthsample) (* (- 1.0 temp) boresample))))
  32. (define (make-dc-block)
  33. (float-vector 0.0 0.0))
  34. (define (dc-block b samp)
  35. (set! (b 1) (- (+ samp (* 0.99 (b 1))) (b 0)))
  36. (set! (b 0) samp)
  37. (b 1))
  38. ;; we could also use a filter generator here: (make-filter 2 (float-vector 1 -1) (float-vector 0 -0.99))
  39. ;;; this ia a 0-based versions of the clm delays
  40. (defgenerator dlya (outp 0) (input #f))
  41. (define (make-delayl len lag)
  42. ;; Perry's original had linear interp bug, I think -- this form is more in tune
  43. (make-dlya :input (make-delay len :max-size (ceiling (+ len lag 1)))
  44. :outp (- lag len)))
  45. (define (delayl d samp)
  46. (delay-tick (d 'input) samp)
  47. (tap (d 'input) (d 'outp)))
  48. ;;; now some example instruments
  49. (definstrument (plucky beg dur freq amplitude maxa)
  50. ;; (with-sound () (plucky 0 .3 440 .2 1.0))
  51. (let ((len (+ 1 (floor (/ *clm-srate* 100.0))))) ; 100 = lowest freq
  52. (let ((delayline (make-delayl len (- (/ *clm-srate* freq) 0.5)))
  53. (filt (make-onezero))
  54. (start (seconds->samples beg))
  55. (end (seconds->samples (+ beg dur)))
  56. (dout 0.0))
  57. (do ((i 0 (+ i 1)))
  58. ((= i len))
  59. (set! dout (delayl delayline (+ (* 0.99 dout) (mus-random maxa)))))
  60. (do ((i start (+ i 1)))
  61. ((= i end))
  62. (set! dout (delayl delayline (one-zero filt dout)))
  63. (outa i (* amplitude dout))))))
  64. ;;; freq is off in this one (in prc's original also)
  65. (definstrument (bowstr beg dur frq amplitude maxa)
  66. ;; (with-sound () (bowstr 0 .3 220 .2 1.0))
  67. (let ((len (+ 1 (floor (/ *clm-srate* 100.0))))) ; 100 = lowest freq
  68. (let ((ratio 0.8317)
  69. (rate .001)
  70. (bowing #t)
  71. (temp (- (/ *clm-srate* frq) 4.0)))
  72. (let ((neckdelay (make-delayl len (* temp ratio)))
  73. (bridgedelay (make-delayl (floor (/ len 2)) (* temp (- 1.0 ratio))))
  74. (bowtab (make-bowtable :slope 3.0))
  75. (filt (make-onep))
  76. (bowvelocity rate)
  77. (maxvelocity maxa)
  78. (attackrate rate)
  79. (st (seconds->samples beg))
  80. (end (seconds->samples (+ beg dur)))
  81. (release (seconds->samples (* .8 dur)))
  82. (ctr 0)
  83. (bridgeout 0.0)
  84. (neckout 0.0))
  85. (set-pole filt 0.6)
  86. (set-gain filt 0.3)
  87. (do ((i st (+ i 1))
  88. (bridgerefl 0.0 0.0)
  89. (nutrefl 0.0 0.0)
  90. (veldiff 0.0 0.0)
  91. (stringvel 0.0 0.0)
  92. (bowtemp 0.0 0.0))
  93. ((= i end))
  94. (if bowing
  95. (if (not (= maxvelocity bowvelocity))
  96. (set! bowvelocity ((if (< bowvelocity maxvelocity) + -) bowvelocity attackrate)))
  97. (if (> bowvelocity 0.0)
  98. (set! bowvelocity (- bowvelocity attackrate))))
  99. (set! bowtemp (* 0.3 bowvelocity))
  100. (let ((filt-output (one-pole filt bridgeout)))
  101. (set! bridgerefl (- filt-output))
  102. (set! nutrefl (- neckout))
  103. (set! stringvel (+ bridgerefl nutrefl))
  104. (set! veldiff (- bowtemp stringvel))
  105. (set! veldiff (* veldiff (bowtable bowtab veldiff)))
  106. (set! neckout (delayl neckdelay (+ bridgerefl veldiff)))
  107. (set! bridgeout (delayl bridgedelay (+ nutrefl veldiff)))
  108. (outa i (* amplitude 10.0 filt-output))
  109. (if (= ctr release)
  110. (begin
  111. (set! bowing #f)
  112. (set! attackrate .0005)))
  113. (set! ctr (+ ctr 1))))))))
  114. (definstrument (brass beg dur freq amplitude maxa)
  115. ;; does this work at all?
  116. (let ((len (+ 1 (floor (/ *clm-srate* 100.0)))))
  117. (let ((blowing #t)
  118. (rate .001)
  119. (breathpressure 0.0)) ; 0.1 ?
  120. (let ((delayline (make-delayl len (+ 1.0 (/ *clm-srate* freq))))
  121. (lipfilter (make-formant freq))
  122. (dcblocker (make-dc-block))
  123. (maxpressure maxa)
  124. (attackrate rate)
  125. (st (seconds->samples beg))
  126. (end (seconds->samples (+ beg dur)))
  127. (release (seconds->samples (* .8 dur)))
  128. (ctr 0)
  129. (dout 0.0))
  130. (do ((i st (+ i 1)))
  131. ((= i end))
  132. (if blowing
  133. (if (not (= maxpressure breathpressure))
  134. (set! breathpressure ((if (< breathpressure maxpressure) + -) breathpressure attackrate)))
  135. (if (> breathpressure 0.0)
  136. (set! breathpressure (- breathpressure attackrate))))
  137. (set! dout (delayl delayline (dc-block dcblocker
  138. (lip lipfilter
  139. (* 0.3 breathpressure)
  140. (* 0.9 dout)))))
  141. (outa i (* amplitude dout))
  142. (if (= ctr release)
  143. (begin
  144. (set! blowing #f)
  145. (set! attackrate .0005)))
  146. (set! ctr (+ ctr 1)))))))
  147. (definstrument (clarinet beg dur freq amplitude maxa)
  148. ;; (with-sound () (clarinet 0 .3 440 .2 1.0))
  149. (let ((len (+ 1 (floor (/ *clm-srate* 100.0)))))
  150. (let ((blowing #t)
  151. (breathpressure 0.0) ; 0.1 ?
  152. (rate .001))
  153. (let ((delayline (make-delayl len (- (* 0.5 (/ *clm-srate* freq)) 1.0)))
  154. (rtable (make-reed :offset 0.7 :slope -0.3))
  155. (filt (make-onezero))
  156. (maxpressure maxa)
  157. (attackrate rate)
  158. (st (seconds->samples beg))
  159. (end (seconds->samples (+ beg dur)))
  160. (ctr 0)
  161. (release (seconds->samples (* .8 dur)))
  162. (dlyout 0.0))
  163. (do ((i st (+ i 1)))
  164. ((= i end))
  165. (if blowing
  166. (if (not (= maxpressure breathpressure))
  167. (set! breathpressure ((if (< breathpressure maxpressure) + -) breathpressure attackrate)))
  168. (if (> breathpressure 0.0)
  169. (set! breathpressure (- breathpressure attackrate))))
  170. (let ((pressurediff (- (one-zero filt (* -0.95 dlyout)) breathpressure)))
  171. (set! dlyout (delayl delayline
  172. (+ breathpressure
  173. (* pressurediff
  174. (reedtable rtable pressurediff))))))
  175. (outa i (* amplitude dlyout))
  176. (if (= ctr release)
  177. (begin
  178. (set! blowing #f)
  179. (set! attackrate .0005)))
  180. (set! ctr (+ ctr 1)))))))
  181. (definstrument (flute beg dur freq amplitude maxa)
  182. ;; (with-sound () (flute 0 .3 440 .2 1.0))
  183. (let ((len (+ 1 (floor (/ *clm-srate* 100.0)))))
  184. (let ((jetrefl 0.6)
  185. (endrefl 0.6)
  186. (sinphase 0.0)
  187. (blowing #t)
  188. (rate .0005)
  189. (breathpressure 0.0) ; 0.1 ?
  190. (ratio 0.8)
  191. (temp (- (/ *clm-srate* freq) 5.0)))
  192. (let ((jetdelay (make-delayl (floor (/ len 2)) (* temp (- 1.0 ratio))))
  193. (boredelay (make-delayl len (* ratio temp)))
  194. (filt (make-onep))
  195. (dcblocker (make-dc-block))
  196. (maxpressure maxa)
  197. (attackrate rate)
  198. (st (seconds->samples beg))
  199. (end (seconds->samples (+ beg dur)))
  200. (ctr 0)
  201. (release (seconds->samples (* .8 dur)))
  202. (boreout 0.0))
  203. (set-pole filt 0.8)
  204. (set-gain filt -1.0)
  205. (do ((i st (+ i 1)))
  206. ((= i end))
  207. (let ((randpressure (random (* 0.1 breathpressure))))
  208. (set! sinphase (+ sinphase 0.0007)) ;5 hz vibrato?
  209. (if (> sinphase 6.28) (set! sinphase (- sinphase 6.28)))
  210. (set! randpressure (+ randpressure (* 0.05 breathpressure (sin sinphase))))
  211. (if blowing
  212. (if (not (= maxpressure breathpressure))
  213. (set! breathpressure ((if (< breathpressure maxpressure) + -) breathpressure attackrate)))
  214. (if (> breathpressure 0.0)
  215. (set! breathpressure (- breathpressure attackrate))))
  216. (let ((pressurediff (let ((temp (dc-block dcblocker (one-pole filt boreout))))
  217. (+ (jettable (delayl jetdelay (- (+ breathpressure randpressure) (* jetrefl temp))))
  218. (* endrefl temp)))))
  219. (set! boreout (delayl boredelay pressurediff)))
  220. (outa i (* 0.3 amplitude boreout))
  221. (if (= ctr release)
  222. (begin
  223. (set! blowing #f)
  224. (set! attackrate .0005)))
  225. (set! ctr (+ ctr 1))))))))
  226. #|
  227. (with-sound ()
  228. (plucky 0 .3 440 .2 1.0)
  229. (bowstr .5 .3 220 .2 1.0)
  230. (brass 1 .3 440 .2 1.0)
  231. (clarinet 1.5 .3 440 .2 1.0)
  232. (flute 2 .3 440 .2 1.0))
  233. |#