您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

282 行
9.4KB

  1. ;;; cross fade instruments
  2. ;;;
  3. ;;; cross-fade sweeps up, down, or from mid-spectrum outwards,
  4. ;;; dissolve-fade chooses randomly -- like a graphical dissolve
  5. ;;; neither is exactly spectacular, but they work -- use similar sounds if possible (speech is problematic)
  6. ;;;
  7. ;;; translated from fade.ins
  8. (provide 'snd-fade.scm)
  9. (if (provided? 'snd)
  10. (require snd-ws.scm)
  11. (require sndlib-ws.scm))
  12. (definstrument (cross-fade beg dur amp file1 file2 ramp-beg ramp-dur ramp-type bank-dur fs fwidth)
  13. ;; ramp-type 0=sweep up, 1=sweep down, 2=split from middle
  14. (if (> (+ (max bank-dur ramp-beg) ramp-dur bank-dur) dur)
  15. (begin
  16. (set! ramp-beg (* 0.25 dur))
  17. (set! ramp-dur (* dur 0.49))
  18. (set! bank-dur (* dur 0.24))))
  19. (let ((fil1 (make-sampler 0 file1))
  20. (fil2 (make-sampler 0 file2))
  21. (start (seconds->samples beg))
  22. (ramp-samps (seconds->samples ramp-dur))
  23. (bank-samps (seconds->samples bank-dur))
  24. (fs1 (make-vector fs)))
  25. (let ((bin (/ *clm-srate* (* 2 fs)))
  26. (radius (- 1.0 (/ fwidth (* 2 fs)))))
  27. (do ((k 0 (+ k 1)))
  28. ((= k fs))
  29. (set! (fs1 k) (make-formant (* k bin) radius))))
  30. (set! fs1 (make-formant-bank fs1))
  31. (let ((end (+ start (seconds->samples dur)))
  32. (bank-incr (/ 1.0 bank-samps))
  33. (ramp-incr (/ 1.0 ramp-samps))
  34. (ramp-start (+ start (seconds->samples ramp-beg))))
  35. (let ((bank1-start (- ramp-start bank-samps))
  36. (ramp-end (+ ramp-start ramp-samps))
  37. (bank2-start (+ ramp-start ramp-samps)))
  38. (do ((i start (+ i 1)))
  39. ((= i bank1-start))
  40. ;; in first section -- just mix in file1
  41. (outa i (* amp (read-sample fil1))))
  42. (let ((bank2-end (+ bank2-start bank-samps))
  43. (ramp 0.0)
  44. (outval 0.0)
  45. (inputs (make-float-vector fs))
  46. (ifs (/ 1.0 fs))
  47. (mid 0))
  48. (do ((i bank1-start (+ i 1))
  49. (bank1 0.0 (+ bank1 bank-incr)))
  50. ((= i ramp-start))
  51. ;; in bank1 section -- fire up the resonators
  52. (let ((inval (read-sample fil1)))
  53. (set! outval (formant-bank fs1 inval))
  54. (outa i (* amp (+ (* bank1 outval) (* (- 1.0 bank1) inval))))))
  55. ;; in the ramp
  56. (case ramp-type
  57. ((0)
  58. (do ((i ramp-start (+ i 1)))
  59. ((= i ramp-end))
  60. (let ((inval1 (read-sample fil1))
  61. (inval2 (read-sample fil2)))
  62. ;; now the choice of spectral fade -- we should end with all bank1 0.0 and all bank2 1.0
  63. (set! ramp (+ ramp ramp-incr))
  64. ;; low freqs go first
  65. (if (>= ramp 0.5)
  66. (begin
  67. (set! mid (floor (* (- (* 2.0 ramp) 1.0) fs)))
  68. (fill! inputs inval2 0 mid)
  69. (float-vector-interpolate inputs mid fs 1.0 (- ifs) inval2 inval1)
  70. ;; (do ((k mid (+ k 1)) (ks 1.0 (- ks ifs))) ((>= k fs)) (float-vector-set! inputs k (+ (* ks inval2) (* (- 1.0 ks) inval1))))
  71. )
  72. (begin
  73. (set! mid (min fs (floor (* 2.0 ramp fs))))
  74. (fill! inputs inval1 mid)
  75. (float-vector-interpolate inputs 0 mid (* 2.0 ramp) (- ifs) inval2 inval1)
  76. ;; (do ((k 0 (+ k 1)) (ks (* 2.0 ramp) (- ks ifs))) ((= k mid)) (float-vector-set! inputs k (+ (* ks inval2) (* (- 1.0 ks) inval1))))
  77. ))
  78. (outa i (* amp (formant-bank fs1 inputs))))))
  79. ((1)
  80. (do ((i ramp-start (+ i 1)))
  81. ((= i ramp-end))
  82. (let ((inval1 (read-sample fil1))
  83. (inval2 (read-sample fil2)))
  84. (set! ramp (+ ramp ramp-incr))
  85. ;; high freqs go first
  86. (if (>= ramp 0.5)
  87. (let ((r2 (- (* 2.0 ramp) 1.0)))
  88. (set! mid (min fs (ceiling (* (- 1.0 r2) fs))))
  89. (fill! inputs inval2 mid)
  90. (float-vector-interpolate inputs 0 mid r2 ifs inval2 inval1)
  91. ;; (do ((k 0 (+ k 1)) (ks r2 (+ ks ifs))) ((= k mid)) (float-vector-set! inputs k (+ (* ks inval2) (* (- 1.0 ks) inval1))))
  92. )
  93. (begin
  94. (set! mid (ceiling (* (- 1.0 (* 2.0 ramp)) fs)))
  95. (fill! inputs inval1 0 mid)
  96. (float-vector-interpolate inputs mid fs 0.0 ifs inval2 inval1)
  97. ;; (do ((k mid (+ k 1)) (ks 0.0 (+ ks ifs))) ((>= k fs)) (float-vector-set! inputs k (+ (* ks inval2) (* (- 1.0 ks) inval1))))
  98. ))
  99. (outa i (* amp (formant-bank fs1 inputs))))))
  100. (else
  101. (let ((half-fs (/ fs 2)))
  102. (do ((i ramp-start (+ i 1)))
  103. ((= i ramp-end))
  104. (let ((inval1 (read-sample fil1))
  105. (inval2 (read-sample fil2)))
  106. ;; now the choice of spectral fade -- we should end with all bank1 0.0 and all bank2 1.0
  107. (set! ramp (+ ramp ramp-incr))
  108. ;; sweep from midpoint out
  109. (fill! inputs inval1)
  110. (set! mid (min half-fs (floor (* fs ramp))))
  111. (do ((k (- half-fs mid) (+ k 1))
  112. (hk (+ half-fs mid -1) (- hk 1))
  113. (ks (max 0.0 (- (* 2.0 ramp) 1.0)) (+ ks ifs)))
  114. ((= k half-fs))
  115. (let ((rfs (min 1.0 ks)))
  116. (set! (inputs k) (+ (* rfs inval2) (* (- 1.0 rfs) inval1)))
  117. (set! (inputs hk) (inputs k))))
  118. (outa i (* amp (formant-bank fs1 inputs))))))))
  119. (do ((i ramp-end (+ i 1))
  120. (bank2 1.0 (- bank2 bank-incr)))
  121. ((= i bank2-end))
  122. ;; in bank2 section -- ramp out resonators
  123. (let ((inval (read-sample fil2)))
  124. (set! outval (formant-bank fs1 inval))
  125. (outa i (* amp (+ (* bank2 outval) (* (- 1.0 bank2) inval))))))
  126. (do ((i bank2-end (+ i 1)))
  127. ((= i end))
  128. ;; in last section -- just mix file2
  129. (outa i (* amp (read-sample fil2))))
  130. )))))
  131. ;;; (float-vector->channel (with-sound ((make-float-vector 22050)) (cross-fade 0 .1 1 0 1 .01 .01 0 .1 256 2)))
  132. ;;; (float-vector->channel (with-sound ((make-float-vector 44100)) (cross-fade 0 2 1.0 "oboe.snd" "trumpet.snd" 0.5 1.0 0 .1 256 2)))
  133. ;;; (with-sound (:statistics #t) (cross-fade 0 2 1.0 "oboe.snd" "trumpet.snd" 0.5 1.0 0 .1 256 2))
  134. ;;; (with-sound () (cross-fade 0 2 1.0 "oboe.snd" "trumpet.snd" 0.5 1.0 0 .1 256 2))
  135. ;;; these fades seem more successful to me when done relatively quickly (the opposite of the dissolve below
  136. ;;; which is best if done as slowly as possible). I like the sweep up best -- a sort of "evaporation" effect.
  137. (definstrument (dissolve-fade beg dur amp file1 file2 fsize r lo hi)
  138. (let ((fil1 (make-sampler 0 file1))
  139. (fil2 (make-sampler 0 file2))
  140. (start (seconds->samples beg))
  141. (freq-inc (floor (/ fsize 2)))
  142. (ramp-inc (/ 1.0 1024.0)))
  143. (let ((end (+ start (seconds->samples dur)))
  144. (spectr (make-vector freq-inc #f))
  145. (trigger (floor (/ (* dur *clm-srate*) freq-inc)))
  146. (fs (make-vector freq-inc #f))
  147. (amps (make-float-vector freq-inc amp))
  148. (ctr 0)
  149. (inputs (make-float-vector freq-inc))
  150. (ramps (make-vector freq-inc -1))
  151. (in2s (make-int-vector freq-inc))
  152. (in2-ctr 0)
  153. (ramp-ctr 0))
  154. (if (not (number? hi)) (set! hi freq-inc))
  155. (let ((bin (floor (/ *clm-srate* fsize)))
  156. (radius (- 1.0 (/ r fsize))))
  157. (do ((k lo (+ k 1)))
  158. ((= k hi))
  159. (set! (fs k) (make-formant (* k bin) radius))))
  160. (set! fs (make-formant-bank fs amps)) ; wrap it up...
  161. (do ((i start (+ i 1)))
  162. ((= i end))
  163. ;; once a ramp is set in motion, it takes care of itself -- we need only choose which to trigger
  164. (set! ctr (+ ctr 1))
  165. (if (> ctr trigger)
  166. (let ((next (floor (random freq-inc))))
  167. ;; find next randomly chosen resonator to flip
  168. (if (not (spectr next))
  169. (set! (spectr next) (- 1.0 ramp-inc))
  170. (call-with-exit
  171. (lambda (bbreak)
  172. (do ((j next (+ j 1))
  173. (k next (- k 1)))
  174. ()
  175. (if (and (< j freq-inc)
  176. (not (spectr j)))
  177. (begin
  178. (set! (spectr j) (- 1.0 ramp-inc))
  179. (set! next j)
  180. (bbreak)))
  181. (if (and (>= k 0)
  182. (not (spectr k)))
  183. (begin
  184. (set! (spectr k) (- 1.0 ramp-inc))
  185. (set! next k)
  186. (bbreak)))))))
  187. (set! (ramps ramp-ctr) next)
  188. (set! ramp-ctr (+ ramp-ctr 1))
  189. (set! ctr 0)))
  190. (let ((inval1 (read-sample fil1))
  191. (inval2 (read-sample fil2)))
  192. (fill! inputs inval1)
  193. (float-vector-spatter inputs in2s in2-ctr inval2)
  194. ;; (do ((k 0 (+ k 1))) ((= k in2-ctr)) (float-vector-set! inputs (int-vector-ref in2s k) inval2))
  195. (when (> ramp-ctr 0)
  196. (let ((rk 0)
  197. (sp 0.0)
  198. (fixup-ramps #f))
  199. (do ((k 0 (+ k 1)))
  200. ((= k ramp-ctr))
  201. (set! rk (ramps k))
  202. (set! sp (vector-ref spectr rk))
  203. (float-vector-set! inputs k (+ (* sp inval1) (* (- 1.0 sp) inval2)))
  204. (set! sp (- sp ramp-inc))
  205. (if (> sp 0.0)
  206. (vector-set! spectr rk sp)
  207. (begin
  208. (set! (in2s in2-ctr) rk)
  209. (set! in2-ctr (+ in2-ctr 1))
  210. (set! fixup-ramps #t)
  211. (set! (ramps k) -1))))
  212. (if fixup-ramps
  213. (let ((j 0))
  214. (do ((k 0 (+ k 1)))
  215. ((= k ramp-ctr))
  216. (if (>= (ramps k) 0)
  217. (begin
  218. (set! (ramps j) (ramps k))
  219. (set! j (+ j 1)))))
  220. (set! ramp-ctr j)))))
  221. (outa i (formant-bank fs inputs)))))))
  222. ;;; (with-sound (:statistics #t) (dissolve-fade 0 1 1.0 "oboe.snd" "trumpet.snd" 256 2 0 128))
  223. ;;; (float-vector->channel (with-sound ((make-float-vector 44100)) (dissolve-fade 0 2 1 0 1 4096 2 2 #f)))
  224. ;;;
  225. ;;; another neat effect here is to simply let the random changes float along with no
  226. ;;; direction -- if the hit is 1.0 send it toward 0.0 and vice versa -- strange
  227. ;;; pitches emerge from noises etc
  228. #|
  229. ;;; make it easy to see and hear:
  230. (with-sound ("p1.snd")
  231. (let ((g (make-ncos 200 100)))
  232. (do ((i 0 (+ i 1)))
  233. ((= i 100000))
  234. (outa i (ncos g)))))
  235. (with-sound ("p2.snd")
  236. (let ((g (make-ncos 123 100)))
  237. (do ((i 0 (+ i 1)))
  238. ((= i 100000))
  239. (outa i (ncos g)))))
  240. (with-sound (:statistics #t)
  241. (cross-fade 0 2 1.0 "p1.snd" "p2.snd" 0.5 1.0 0 .1 256 2))
  242. (with-sound (:statistics #t)
  243. (dissolve-fade 0 2 1.0 "p1.snd" "p2.snd" 256 2 0 128))
  244. |#