Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

346 lines
12KB

  1. ;;; multi-channel sound file expansion with srate and reverb.
  2. ;;; michael klingbeil (michael@klingbeil.com)
  3. ;;;
  4. ;;; $Name: $
  5. ;;; $Revision: 1.1 $
  6. ;;; $Date: 2005/10/16 22:15:44 $
  7. ;;;
  8. ;;; clm-4 and scheme May-08 bil
  9. ;;; split out cases to optimize May-09 bil
  10. (provide 'snd-expandn.scm)
  11. (if (provided? 'snd)
  12. (require snd-ws.scm)
  13. (require sndlib-ws.scm))
  14. (require snd-env.scm)
  15. (definstrument (expandn time duration filename amplitude
  16. (expand 1.0)
  17. matrix
  18. (ramp 0.4)
  19. (seglen 0.15)
  20. (srate 1.0)
  21. (hop .05)
  22. (amp-env '(0 0 50 1 100 0))
  23. (input-start 0.0)
  24. (grain-amp 0.8)
  25. reverb)
  26. (let ((fnam (file-name filename)))
  27. (if (not (file-exists? fnam))
  28. (error 'no-such-file (list 'expandn filename))
  29. (let* ((beg (seconds->samples time))
  30. (end (+ beg (seconds->samples duration)))
  31. (min-exp-amt (if (pair? expand) (min-envelope expand) expand))
  32. (max-out-hop (if (pair? hop) (max-envelope hop) hop)))
  33. (let ((in-chans (channels fnam))
  34. (out-chans (channels *output*))
  35. (rev-chans (if *reverb* (channels *reverb*) 0)))
  36. (let ((update-rate 100)
  37. (ochans (max in-chans out-chans))
  38. (max-seg-len (if (pair? seglen) (max-envelope seglen) seglen))
  39. (rampdata (if (pair? ramp) ramp (list 0 ramp 1 ramp)))
  40. (start (floor (* input-start (mus-sound-srate fnam))))
  41. (max-in-hop (/ max-out-hop min-exp-amt))
  42. (rev-mx (and *reverb* (real? reverb) (> reverb 0.0)
  43. (let* ((rchans (max out-chans rev-chans))
  44. (rmx (make-float-vector (list rchans rchans))))
  45. (do ((i 0 (+ i 1)))
  46. ((= i rchans))
  47. (set! (rmx i i) reverb))
  48. rmx))))
  49. (let ((mx (let ((v (make-float-vector (list ochans ochans))))
  50. (if (pair? matrix)
  51. (let ((mat-in (min ochans (length matrix)))
  52. (mat-out (min ochans (length (car matrix)))))
  53. (do ((inp 0 (+ inp 1)))
  54. ((= inp mat-in))
  55. (do ((outp 0 (+ outp 1)))
  56. ((= outp mat-out))
  57. (set! (v inp outp) (matrix inp outp)))))
  58. (do ((i 0 (+ i 1)))
  59. ((= i ochans))
  60. (set! (v i i) 1.0)))
  61. v))
  62. (revvals (and rev-mx (make-float-vector (max out-chans rev-chans))))
  63. (update-envs (or (pair? expand)
  64. (pair? seglen)
  65. (pair? ramp)
  66. (pair? hop)))
  67. (update-ctr 0)
  68. (expenv (make-env (if (pair? expand) expand (list 0 expand 1 expand))
  69. :duration (/ duration update-rate)))
  70. (lenenv (make-env (if (pair? seglen) seglen (list 0 seglen 1 seglen))
  71. :duration (/ duration update-rate)))
  72. (segment-scaler (if (> max-seg-len .15)
  73. (/ (* grain-amp .15) max-seg-len)
  74. grain-amp))
  75. (srenv (make-env (if (pair? srate) srate (list 0 srate)) :duration duration))
  76. (rampenv (make-env rampdata :duration (/ duration update-rate)))
  77. (minramp-bug (<= (min-envelope rampdata) 0.0))
  78. (maxramp-bug (>= (max-envelope rampdata) 0.5))
  79. (hopenv (make-env (if (pair? hop) hop (list 0 hop 1 hop))
  80. :duration (/ duration update-rate)))
  81. (ampenv (make-env amp-env :duration duration :scaler amplitude))
  82. (ex-array (make-vector in-chans #f))
  83. (ex-samp -1.0)
  84. (next-samp 0.0)
  85. (max-len (ceiling (* *clm-srate*
  86. (+ (max max-out-hop max-in-hop)
  87. max-seg-len))))
  88. (invals (make-float-vector ochans))
  89. (outvals (make-float-vector ochans)))
  90. (if (or minramp-bug maxramp-bug)
  91. (error 'out-of-range (list expand
  92. "ramp argument to expandn must always be "
  93. (if (and minramp-bug maxramp-bug) "between 0.0 and 0.5"
  94. (if minramp-bug "greater than 0.0"
  95. "less than 0.5")))))
  96. ;; setup granulate generators
  97. (do ((i 0 (+ i 1)))
  98. ((= i in-chans))
  99. (vector-set! ex-array i (make-granulate :input (make-readin fnam :start start :channel i)
  100. :expansion (if (pair? expand) (cadr expand) expand)
  101. :max-size max-len
  102. :ramp (if (pair? ramp) (cadr ramp) ramp)
  103. :hop (if (pair? hop) (cadr hop) hop)
  104. :length (if (pair? seglen) (cadr seglen) seglen)
  105. :scaler segment-scaler)))
  106. ;; split out 1 and 2 chan input
  107. (if (= in-chans 1)
  108. (let ((ingen (vector-ref ex-array 0))
  109. (sample-0 0.0)
  110. (sample-1 0.0))
  111. ;; these vars used for resampling
  112. (if (not (or (pair? srate)
  113. update-envs
  114. (not (= out-chans 1))
  115. matrix
  116. rev-mx))
  117. (let ((file-end (+ beg (seconds->samples (+ (* 2 seglen)
  118. (/ (* (mus-sound-duration fnam) (mus-sound-srate fnam) expand)
  119. *clm-srate* srate))))))
  120. (set! end (min end file-end))
  121. (do ((i beg (+ i 1)))
  122. ((= i end))
  123. (let ((vol (env ampenv)))
  124. (if (negative? ex-samp)
  125. (begin
  126. (set! sample-0 (* vol (granulate ingen)))
  127. (set! sample-1 (* vol (granulate ingen)))
  128. (set! ex-samp (+ ex-samp 1))
  129. (set! next-samp ex-samp)
  130. (outa i sample-0))
  131. (begin
  132. (set! next-samp (+ next-samp srate))
  133. (if (> next-samp (+ ex-samp 1))
  134. (let ((samps (floor (- next-samp ex-samp))))
  135. (if (= samps 2)
  136. (begin
  137. (set! sample-0 (* vol (granulate ingen)))
  138. (set! sample-1 (* vol (granulate ingen))))
  139. (do ((k 0 (+ k 1)))
  140. ((= k samps))
  141. (set! sample-0 sample-1)
  142. (set! sample-1 (* vol (granulate ingen)))))
  143. (set! ex-samp (+ ex-samp samps))))
  144. (if (= next-samp ex-samp)
  145. (outa i (if (= next-samp ex-samp)
  146. sample-0
  147. (+ sample-0 (* (- next-samp ex-samp) (- sample-1 sample-0)))))))))))
  148. (do ((i beg (+ i 1)))
  149. ((= i end))
  150. (let ((vol (env ampenv))
  151. (resa (env srenv)))
  152. (if update-envs
  153. (begin
  154. (set! update-ctr (+ update-ctr 1))
  155. (if (>= update-ctr update-rate)
  156. (let ((sl (floor (* (env lenenv) *clm-srate*))))
  157. (set! update-ctr 0)
  158. (set! (mus-length ingen) sl)
  159. (set! (mus-ramp ingen) (floor (* sl (env rampenv))))
  160. (set! (mus-frequency ingen) (env hopenv))
  161. (set! (mus-increment ingen) (env expenv))))))
  162. (if (negative? ex-samp)
  163. (begin
  164. (set! sample-0 (* vol (granulate ingen)))
  165. (set! sample-1 (* vol (granulate ingen)))
  166. (set! ex-samp (+ ex-samp 1))
  167. (set! next-samp ex-samp))
  168. (begin
  169. (set! next-samp (+ next-samp resa))
  170. (if (> next-samp (+ ex-samp 1))
  171. (let ((samps (floor (- next-samp ex-samp))))
  172. (if (= samps 2)
  173. (begin
  174. (set! sample-0 (* vol (granulate ingen)))
  175. (set! sample-1 (* vol (granulate ingen))))
  176. (do ((k 0 (+ k 1)))
  177. ((= k samps))
  178. (set! sample-0 sample-1)
  179. (set! sample-1 (* vol (granulate ingen)))))
  180. (set! ex-samp (+ ex-samp samps)))))))
  181. (set! (invals 0) (if (= next-samp ex-samp)
  182. sample-0 ; output actual samples
  183. (+ sample-0 (* (- next-samp ex-samp) (- sample-1 sample-0))))) ; output interpolated samples
  184. ;; output mixed result
  185. (frample->file *output* i (frample->frample mx invals ochans outvals ochans))
  186. ;; if reverb is turned on, output to the reverb streams
  187. (if rev-mx
  188. (frample->file *reverb* i (frample->frample rev-mx outvals ochans revvals rev-chans))))))
  189. (if (= in-chans 2)
  190. (let ((sample-0-0 0.0)
  191. (sample-1-0 0.0)
  192. (sample-0-1 0.0)
  193. (sample-1-1 0.0)
  194. (ingen0 (vector-ref ex-array 0))
  195. (ingen1 (vector-ref ex-array 1)))
  196. (do ((i beg (+ i 1)))
  197. ((= i end))
  198. (let ((vol (env ampenv))
  199. (resa (env srenv)))
  200. (if update-envs
  201. (begin
  202. (set! update-ctr (+ update-ctr 1))
  203. (if (>= update-ctr update-rate)
  204. (let ((expa (env expenv)) ;current expansion amount
  205. (segl (env lenenv)) ;current segment length
  206. (rmpl (env rampenv)) ;current ramp length (0 to .5)
  207. (hp (env hopenv))) ;current hop size
  208. (let* ((sl (floor (* segl *clm-srate*)))
  209. (rl (floor (* rmpl sl))))
  210. (set! update-ctr 0)
  211. (set! (mus-length ingen0) sl)
  212. (set! (mus-ramp ingen0) rl)
  213. (set! (mus-frequency ingen0) hp)
  214. (set! (mus-increment ingen0) expa)
  215. (set! (mus-length ingen1) sl)
  216. (set! (mus-ramp ingen1) rl)
  217. (set! (mus-frequency ingen1) hp)
  218. (set! (mus-increment ingen1) expa))))))
  219. (if (negative? ex-samp)
  220. (begin
  221. (set! sample-0-0 (* vol (granulate ingen0)))
  222. (set! sample-1-0 (* vol (granulate ingen0)))
  223. (set! sample-0-1 (* vol (granulate ingen1)))
  224. (set! sample-1-1 (* vol (granulate ingen1)))
  225. (set! ex-samp (+ ex-samp 1))
  226. (set! next-samp ex-samp))
  227. (begin
  228. (set! next-samp (+ next-samp resa))
  229. (if (> next-samp (+ ex-samp 1))
  230. (let ((samps (floor (- next-samp ex-samp))))
  231. (do ((k 0 (+ k 1)))
  232. ((= k samps))
  233. (set! sample-0-0 sample-1-0)
  234. (set! sample-1-0 (* vol (granulate ingen0)))
  235. (set! sample-0-1 sample-1-1)
  236. (set! sample-1-1 (* vol (granulate ingen1))))
  237. (set! ex-samp (+ ex-samp samps)))))))
  238. (if (= next-samp ex-samp)
  239. ;; output actual samples
  240. (begin
  241. (set! (invals 0) sample-0-0)
  242. (set! (invals 1) sample-0-1))
  243. (begin
  244. ;; output interpolated samples
  245. (set! (invals 0) (+ sample-0-0 (* (- next-samp ex-samp) (- sample-1-0 sample-0-0))))
  246. (set! (invals 1) (+ sample-0-1 (* (- next-samp ex-samp) (- sample-1-1 sample-0-1))))))
  247. ;; output mixed result
  248. (frample->file *output* i (frample->frample mx invals ochans outvals ochans))
  249. ;; if reverb is turned on, output to the reverb streams
  250. (if rev-mx
  251. (frample->file *reverb* i (frample->frample rev-mx outvals ochans revvals rev-chans)))))
  252. (let ((samples-0 (make-float-vector in-chans))
  253. (samples-1 (make-float-vector in-chans)))
  254. ;; more than 2 chans in input file
  255. (do ((i beg (+ i 1)))
  256. ((= i end))
  257. (let ((vol (env ampenv))
  258. (resa (env srenv)))
  259. (if update-envs
  260. (begin
  261. (set! update-ctr (+ update-ctr 1))
  262. (if (>= update-ctr update-rate)
  263. (let ((expa (env expenv)) ;current expansion amount
  264. (segl (env lenenv)) ;current segment length
  265. (rmpl (env rampenv)) ;current ramp length (0 to .5)
  266. (hp (env hopenv))) ;current hop size
  267. (let* ((sl (floor (* segl *clm-srate*)))
  268. (rl (floor (* rmpl sl))))
  269. (set! update-ctr 0)
  270. (do ((ix 0 (+ ix 1)))
  271. ((= ix in-chans))
  272. (let ((gen (vector-ref ex-array ix)))
  273. (set! (mus-length gen) sl)
  274. (set! (mus-ramp gen) rl)
  275. (set! (mus-frequency gen) hp)
  276. (set! (mus-increment gen) expa))))))))
  277. (if (negative? ex-samp)
  278. (begin
  279. (do ((ix 0 (+ ix 1)))
  280. ((= ix in-chans))
  281. (let ((gen (vector-ref ex-array ix)))
  282. (float-vector-set! samples-0 ix (* vol (granulate gen)))
  283. (float-vector-set! samples-1 ix (* vol (granulate gen)))))
  284. (set! ex-samp (+ ex-samp 1))
  285. (set! next-samp ex-samp))
  286. (begin
  287. (set! next-samp (+ next-samp resa))
  288. (if (> next-samp (+ ex-samp 1))
  289. (let ((samps (floor (- next-samp ex-samp))))
  290. (do ((k 0 (+ k 1)))
  291. ((= k samps))
  292. (do ((ix 0 (+ ix 1)))
  293. ((= ix in-chans))
  294. (let ((gen (vector-ref ex-array ix)))
  295. (float-vector-set! samples-0 ix (float-vector-ref samples-1 ix))
  296. (float-vector-set! samples-1 ix (* vol (granulate gen))))))
  297. (set! ex-samp (+ ex-samp samps)))))))
  298. (if (= next-samp ex-samp)
  299. ;; output actual samples
  300. (copy samples-0 invals 0 in-chans)
  301. ;; output interpolated samples
  302. (do ((ix 0 (+ ix 1)))
  303. ((= ix in-chans))
  304. (let ((v0 (float-vector-ref samples-0 ix))
  305. (v1 (float-vector-ref samples-1 ix)))
  306. (float-vector-set! invals ix (+ v0 (* (- next-samp ex-samp) (- v1 v0)))))))
  307. ;; output mixed result
  308. (frample->file *output* i (frample->frample mx invals ochans outvals ochans))
  309. ;; if reverb is turned on, output to the reverb streams
  310. (if rev-mx
  311. (frample->file *reverb* i (frample->frample rev-mx outvals ochans revvals rev-chans))))))))))))))
  312. ;;; (with-sound () (expandn 0 1 "oboe.snd" 1 :expand 4))