Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

202 linhas
7.2KB

  1. ;;; Moog style four pole lowpass filter clm unit generator
  2. ;;; low pass, 24db/Oct, variable resonance, warm, analog sound ;-)
  3. ;;; [all this digital wizardry and we're back where we started!]
  4. ;;;
  5. ;;; original C instrument by Tim Stilson
  6. ;;; translation into clm and tuning by
  7. ;;; Fernando Lopez-Lezcano, nando@ccrma.stanford.edu
  8. ;;; http://ccrma.stanford.edu/~nando/clm/moog
  9. ;;;
  10. ;;; translated to Snd scheme function by Bill,
  11. ;;; changed 21-Sep-10 to use defgenerator
  12. (provide 'snd-moog.scm)
  13. (if (provided? 'snd)
  14. (require snd-ws.scm)
  15. (require sndlib-ws.scm))
  16. (define moog-gaintable (float-vector 0.999969 0.990082 0.980347 0.970764 0.961304 0.951996 0.94281 0.933777 0.924866 0.916077
  17. 0.90741 0.898865 0.890442 0.882141 0.873962 0.865906 0.857941 0.850067 0.842346 0.834686
  18. 0.827148 0.819733 0.812378 0.805145 0.798004 0.790955 0.783997 0.77713 0.770355 0.763672
  19. 0.75708 0.75058 0.744141 0.737793 0.731537 0.725342 0.719238 0.713196 0.707245 0.701355
  20. 0.695557 0.689819 0.684174 0.678558 0.673035 0.667572 0.66217 0.65686 0.651581 0.646393
  21. 0.641235 0.636169 0.631134 0.62619 0.621277 0.616425 0.611633 0.606903 0.602234 0.597626
  22. 0.593048 0.588531 0.584045 0.579651 0.575287 0.570953 0.566681 0.562469 0.558289 0.554169
  23. 0.550079 0.546051 0.542053 0.538116 0.53421 0.530334 0.52652 0.522736 0.518982 0.515289
  24. 0.511627 0.507996 0.504425 0.500885 0.497375 0.493896 0.490448 0.487061 0.483704 0.480377
  25. 0.477081 0.473816 0.470581 0.467377 0.464203 0.46109 0.457977 0.454926 0.451874 0.448883
  26. 0.445892 0.442932 0.440033 0.437134 0.434265 0.431427 0.428619 0.425842 0.423096 0.42038
  27. 0.417664 0.415009 0.412354 0.409729 0.407135 0.404572 0.402008 0.399506 0.397003 0.394501
  28. 0.392059 0.389618 0.387207 0.384827 0.382477 0.380127 0.377808 0.375488 0.37323 0.370972
  29. 0.368713 0.366516 0.364319 0.362122 0.359985 0.357849 0.355713 0.353607 0.351532 0.349457
  30. 0.347412 0.345398 0.343384 0.34137 0.339417 0.337463 0.33551 0.333588 0.331665 0.329773
  31. 0.327911 0.32605 0.324188 0.322357 0.320557 0.318756 0.316986 0.315216 0.313446 0.311707
  32. 0.309998 0.308289 0.30658 0.304901 0.303223 0.301575 0.299927 0.298309 0.296692 0.295074
  33. 0.293488 0.291931 0.290375 0.288818 0.287262 0.285736 0.284241 0.282715 0.28125 0.279755
  34. 0.27829 0.276825 0.275391 0.273956 0.272552 0.271118 0.269745 0.268341 0.266968 0.265594
  35. 0.264252 0.262909 0.261566 0.260223 0.258911 0.257599 0.256317 0.255035 0.25375))
  36. (define moog-freqtable
  37. '(0 -1
  38. 0.03311111 -0.9
  39. 0.06457143 -0.8
  40. 0.0960272 -0.7
  41. 0.127483 -0.6
  42. 0.1605941 -0.5
  43. 0.1920544 -0.4
  44. 0.22682086 -0.3
  45. 0.2615873 -0.2
  46. 0.29801363 -0.1
  47. 0.33278003 -0.0
  48. 0.37086168 0.1
  49. 0.40893877 0.2
  50. 0.4536417 0.3
  51. 0.5 0.4
  52. 0.5463583 0.5
  53. 0.5943719 0.6
  54. 0.6556281 0.7
  55. 0.72185487 0.8
  56. 0.8096009 0.9
  57. 0.87913835 0.95
  58. 0.9933787 1
  59. 1 1))
  60. ;;; moog struct is a list (freq res arr a)
  61. ;;; freq: cutoff frequency in Hertz
  62. ;;; Q: resonance, 0->no resonance, 1->oscilates at freq
  63. ;;;
  64. ;;; Note: the relation between freq and the actual cutoff is not exactly linear but
  65. ;;; I prefered to translate Hz into the internal parameter rather than controlling
  66. ;;; the cutoff frequency in terms of a number that goes between -1 and 1.
  67. #|
  68. (defgenerator moog freq Q s y fc gain sig)
  69. (define make-moog-filter
  70. (let ((documentation "(make-moog-filter frequency Q) makes a new moog-filter generator. 'frequency' is the cutoff in Hz,
  71. 'Q' sets the resonance: 0 = no resonance, 1: oscillates at 'frequency'"))
  72. (lambda (frequency Q)
  73. (let ((frq (envelope-interp (/ frequency (* *clm-srate* 0.5)) moog-freqtable)))
  74. (make-moog :freq frequency
  75. :Q Q
  76. :s (make-float-vector 4)
  77. :y 0.0
  78. :fc frq
  79. :gain (* Q (array-interp moog-gaintable (+ 99.0 (* frq 99.0)))))))))
  80. (define moog-frequency
  81. (dilambda
  82. (let ((documentation "(moog-frequency gen) accesses the cutoff frequency of the Moog filter 'gen'"))
  83. (lambda (gen)
  84. (gen 'freq)))
  85. (lambda (gen frq)
  86. (let ((fr (envelope-interp (/ frq (* *clm-srate* 0.5)) moog-freqtable)))
  87. (set! (gen 'freq) frq)
  88. (set! (gen 'fc) fr)
  89. (set! (gen 'gain) (* (gen 'Q) (array-interp moog-gaintable (+ 99.0 (* fr 99.0)))))))))
  90. (define moog-filter
  91. (let ((documentation "(moog-filter m sig) is the generator associated with make-moog-filter"))
  92. (lambda (m sig)
  93. (let-set! m 'sig sig)
  94. (with-let m
  95. (let ((A (* 0.25 (- sig y)))
  96. (st 0.0))
  97. (do ((cell 0 (+ 1 cell)))
  98. ((= cell 4))
  99. (set! st (float-vector-ref s cell))
  100. (set! A (min 0.95 (max -0.95 (+ A (* fc (- A st))))))
  101. (float-vector-set! s cell A)
  102. (set! A (min 0.95 (max -0.95 (+ A st)))))
  103. (set! y (* A gain))
  104. A)))))
  105. ;;; (let ((gen (make-moog-filter 500.0 .1))) (map-channel (lambda (y) (moog-filter gen y))))
  106. |#
  107. ;;; faster version?
  108. (defgenerator moog freq Q s0 s1 s2 s3 y fc gain sig)
  109. (define make-moog-filter
  110. (let ((documentation "(make-moog-filter frequency Q) makes a new moog-filter generator. 'frequency' is the cutoff in Hz,
  111. 'Q' sets the resonance: 0 = no resonance, 1: oscillates at 'frequency'"))
  112. (lambda (frequency Q)
  113. (let ((frq (envelope-interp (/ frequency (* *clm-srate* 0.5)) moog-freqtable)))
  114. (make-moog :freq frequency
  115. :Q Q
  116. :y 0.0 :s0 0.0 :s1 0.0 :s2 0.0 :s3 0.0
  117. :fc frq
  118. :gain (* Q (array-interp moog-gaintable (+ 99.0 (* frq 99.0)))))))))
  119. (define moog-frequency
  120. (dilambda
  121. (let ((documentation "(moog-frequency gen) accesses the cutoff frequency of the Moog filter 'gen'"))
  122. (lambda (gen)
  123. (gen 'freq)))
  124. (lambda (gen frq)
  125. (let ((fr (envelope-interp (/ frq (* *clm-srate* 0.5)) moog-freqtable)))
  126. (set! (gen 'freq) frq)
  127. (set! (gen 'fc) fr)
  128. (set! (gen 'gain) (* (gen 'Q) (array-interp moog-gaintable (+ 99.0 (* fr 99.0)))))))))
  129. (define moog-filter
  130. (let ((documentation "(moog-filter m sig) is the generator associated with make-moog-filter"))
  131. (lambda (m sig)
  132. ; see below for the "saturate" option
  133. (let-set! m 'sig sig)
  134. (with-let m
  135. (let ((A (* 0.25 (- sig y)))
  136. (st s0))
  137. (set! s0 (+ A (* fc (- A st))))
  138. (set! A (+ s0 st))
  139. (set! st s1)
  140. (set! s1 (+ A (* fc (- A st))))
  141. (set! A (+ s1 st))
  142. (set! st s2)
  143. (set! s2 (+ A (* fc (- A st))))
  144. (set! A (+ s2 st))
  145. (set! st s3)
  146. (set! s3 (+ A (* fc (- A st))))
  147. (set! A (+ s3 st))
  148. (set! y (* A gain))
  149. A)))))
  150. (define moog-filter-saturated
  151. (let ((documentation "(moog-filter-saturated m sig) is the generator associated with make-moog-filter with internal saturation"))
  152. (lambda (m sig)
  153. (let-set! m 'sig sig)
  154. (with-let m
  155. (let ((A (* 0.25 (- sig y)))
  156. (st s0))
  157. (set! s0 (min 0.95 (max -0.95 (+ A (* fc (- A st))))))
  158. (set! A (min 0.95 (max -0.95 (+ s0 st))))
  159. (set! st s1)
  160. (set! s1 (min 0.95 (max -0.95 (+ A (* fc (- A st))))))
  161. (set! A (min 0.95 (max -0.95 (+ s1 st))))
  162. (set! st s2)
  163. (set! s2 (min 0.95 (max -0.95 (+ A (* fc (- A st))))))
  164. (set! A (min 0.95 (max -0.95 (+ s2 st))))
  165. (set! st s3)
  166. (set! s3 (min 0.95 (max -0.95 (+ A (* fc (- A st))))))
  167. (set! A (min 0.95 (max -0.95 (+ s3 st))))
  168. (set! y (* A gain))
  169. A)))))