You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6825 satır
207KB

  1. (provide 'snd-generators.scm)
  2. (if (provided? 'snd)
  3. (require snd-ws.scm)
  4. (require sndlib-ws.scm))
  5. ;;; it is dangerous to use a method within a generator's definition of that method --
  6. ;;; if the gen is used as the environment in with-let, the embedded call
  7. ;;; becomes a recursive call on that method. You either need to check the type
  8. ;;; of the method argument, or use #_method to override the name lookup, or use
  9. ;;; the explicit call style: (((gen 'embedded-gen) 'shared-method) ...)
  10. ;;; if gen has embedded gen, mus-copy needs a special copy method (see adjustable-oscil)
  11. ;;; a problem with a special copy method: if you change the generator, remember to change its copy method!
  12. ;;; also, I think (inlet e) is a way to copy e without accidentally invoking any 'copy method in e
  13. (define nearly-zero 1.0e-10) ; 1.0e-14 in clm.c, but that is trouble here (noddcos)
  14. (define two-pi (* 2.0 pi))
  15. ;;; --------------------------------------------------------------------------------
  16. ;;; nssb (see nxycos) -- wouldn't a more consistent name be nxycos? but it already exists -- perhaps delete nssb?
  17. (defgenerator (nssb
  18. :make-wrapper (lambda (g)
  19. (set! (g 'frequency) (hz->radians (g 'frequency)))
  20. g))
  21. (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm)
  22. (define nssb
  23. (let ((documentation "(make-nssb frequency (ratio 1.0) (n 1)) creates an nssb generator,
  24. similar to nxysin. (nssb gen (fm 0.0)) returns n sinusoids from frequency spaced by frequency * ratio."))
  25. (lambda* (gen (fm 0.0))
  26. (let-set! gen 'fm fm)
  27. (with-let gen
  28. (let* ((cx angle)
  29. (mx (* cx ratio))
  30. (den (sin (* 0.5 mx))))
  31. (set! angle (+ angle fm frequency))
  32. (if (< (abs den) nearly-zero)
  33. -1.0
  34. (/ (- (* (sin cx)
  35. (sin (* mx (/ (+ n 1) 2)))
  36. (sin (/ (* n mx) 2)))
  37. (* (cos cx)
  38. 0.5 (+ den (sin (* mx (+ n 0.5))))))
  39. (* (+ n 1) den))))))))
  40. #|
  41. (with-sound (:clipped #f :statistics #t :play #t)
  42. (let ((gen (make-nssb 1000.0 0.1 3)))
  43. (do ((i 0 (+ i 1)))
  44. ((= i 10000))
  45. (outa i (nssb gen)))))
  46. (with-sound (:clipped #f :statistics #t :play #t)
  47. (let ((gen (make-nssb 1000.0 0.1 3))
  48. (vib (make-oscil 5.0))
  49. (ampf (make-env '(0 0 1 1 2 1 3 0) :length 20000 :scaler 1.0)))
  50. (do ((i 0 (+ i 1)))
  51. ((= i 20000))
  52. (outa i (* (env ampf)
  53. (nssb gen (* (hz->radians 100.0)
  54. (oscil vib))))))))
  55. |#
  56. ;;; --------------------------------------------------------------------------------
  57. ;;; G&R first col rows 1&2
  58. (define (find-nxysin-max n ratio)
  59. (define (find-mid-max n lo hi)
  60. (define (ns x n)
  61. (let* ((a2 (/ x 2))
  62. (den (sin a2)))
  63. (if (= den 0.0)
  64. 0.0
  65. (/ (* (sin (* n a2)) (sin (* (+ 1 n) a2))) den))))
  66. (let ((mid (/ (+ lo hi) 2))
  67. (ylo (ns lo n))
  68. (yhi (ns hi n)))
  69. (if (< (abs (- ylo yhi)) nearly-zero) ; was e-100 but that hangs if not using doubles
  70. (ns mid n)
  71. (find-mid-max n (if (> ylo yhi)
  72. (values lo mid)
  73. (values mid hi))))))
  74. (define (find-nodds-mid-max n lo hi)
  75. (define (nodds x n)
  76. (let ((den (sin x))
  77. (num (sin (* n x))))
  78. (if (= den 0.0)
  79. 0.0
  80. (/ (* num num) den))))
  81. (let ((mid (/ (+ lo hi) 2))
  82. (ylo (nodds lo n))
  83. (yhi (nodds hi n)))
  84. (if (< (abs (- ylo yhi)) nearly-zero)
  85. (nodds mid n)
  86. (find-nodds-mid-max n (if (> ylo yhi)
  87. (values lo mid)
  88. (values mid hi))))))
  89. (if (= ratio 1)
  90. (find-mid-max n 0.0 (/ pi (+ n .5)))
  91. (if (= ratio 2)
  92. (find-nodds-mid-max n 0.0 (/ pi (+ (* 2 n) 0.5)))
  93. n)))
  94. (defgenerator (nxysin
  95. :make-wrapper (lambda (g)
  96. (set! (g 'frequency) (hz->radians (g 'frequency)))
  97. (set! (g 'norm) (/ 1.0 (find-nxysin-max (g 'n) (g 'ratio))))
  98. g))
  99. (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm
  100. (norm 1.0))
  101. (define nxysin
  102. (let ((documentation "(make-nxysin frequency (ratio 1.0) (n 1)) creates an nxysin
  103. generator. (nxysin gen (fm 0.0)) returns n sines from frequency spaced by frequency * ratio."))
  104. (lambda* (gen (fm 0.0))
  105. (let-set! gen 'fm fm)
  106. (with-let gen
  107. (let* ((x angle)
  108. (y (* x ratio))
  109. (den (sin (* y 0.5))))
  110. (set! angle (+ angle fm frequency))
  111. (if (< (abs den) nearly-zero)
  112. 0.0
  113. (/ (* (sin (+ x (* 0.5 (- n 1) y)))
  114. (sin (* 0.5 n y))
  115. norm)
  116. den)))))))
  117. ;;; if x (angle) is constant (an initial-phase offset for a sum of sines,
  118. ;;; the peak amp is nsin-max(n) + abs(sin(initial-phase))*(1 - nsin-max(n))
  119. ;;; that is, it varys sinusoidally from a sum-of-sines .7245 to a sum-of-cosines 1
  120. ;;; since we're treating "x" as the carrier (it's not a constant phase offset in this case)
  121. ;;; the output varies as x does, so we have a maxamp of n? There are special cases
  122. ;;; for low n and low integer ratio:
  123. ;;; ratio (4): (40): (400):
  124. ;;; 1: 3.23 29.34 290.1
  125. ;;; 2: 2.9404 28.97 289.7
  126. ;;; 3: 3.85 38.6 346.8
  127. ;;; 1.123: n
  128. ;;; .5: 3.55 30.0 290
  129. ;;; a ratio of 1 gives a sum of equal amplitude sines, so we could use nsin-max?
  130. ;;; 2 odd harmonics -- use noddsin?
  131. ;;; else use n (not so great for ratio: 3, but not way off)
  132. ;;; worst case right now is probably ratio .5
  133. #|
  134. (with-sound (:clipped #f :statistics #t :play #t)
  135. (let ((gen (make-nxysin 300 1/3 3)))
  136. (do ((i 0 (+ i 1)))
  137. ((= i 20000))
  138. (outa i (nxysin gen)))))
  139. ;;; here's the varying initial-phase case:
  140. (with-sound (:clipped #f)
  141. (let ((x 0.0)
  142. (ix (/ pi 1000))
  143. (n 100))
  144. (do ((i 0 (+ i 1)))
  145. ((= i 1000))
  146. (let ((pk 0.0)
  147. (phi x)
  148. (y 0.0)
  149. (iy (/ (* 2 pi) 10000)))
  150. (set! x (+ x ix))
  151. (do ((k 0 (+ k 1)))
  152. ((= k 10000))
  153. ;; x = phi
  154. (let ((den (sin (/ y 2))))
  155. (if (not (= den 0.0))
  156. (let ((sum (abs (/ (* (sin (+ phi (* y (/ (- n 1) 2)))) (sin (/ (* n y) 2))) den))))
  157. (if (> sum pk)
  158. (set! pk sum)))))
  159. (set! y (+ y iy)))
  160. (outa i pk)))))
  161. |#
  162. (defgenerator (nxycos
  163. :make-wrapper (lambda (g)
  164. (set! (g 'frequency) (hz->radians (g 'frequency)))
  165. g))
  166. (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm)
  167. (define nxycos
  168. (let ((documentation "(make-nxycos frequency (ratio 1.0) (n 1)) creates an nxycos generator. (nxycos gen (fm 0.0))
  169. returns n cosines from frequency spaced by frequency * ratio."))
  170. (lambda* (gen (fm 0.0))
  171. (let-set! gen 'fm fm)
  172. (with-let gen
  173. (let* ((x angle)
  174. (y (* x ratio))
  175. (den (sin (* y 0.5))))
  176. (set! angle (+ angle fm frequency))
  177. (if (< (abs den) nearly-zero)
  178. 1.0
  179. (/ (* (cos (+ x (* 0.5 (- n 1) y)))
  180. (sin (* 0.5 n y)))
  181. (* n den)))))))) ; n=normalization
  182. #|
  183. (with-sound (:clipped #f :statistics #t :play #t)
  184. (let ((gen (make-nxycos 300 1/3 3)))
  185. (do ((i 0 (+ i 1)))
  186. ((= i 20000))
  187. (outa i (* .5 (nxycos gen))))))
  188. |#
  189. ;;; --------------------------------------------------------------------------------
  190. ;;;
  191. ;;; G&R first col rows 3 4
  192. (defgenerator (nxy1cos
  193. :make-wrapper (lambda (g)
  194. (set! (g 'frequency) (hz->radians (g 'frequency)))
  195. g))
  196. (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm)
  197. (define nxy1cos
  198. (let ((documentation "(make-nxy1cos frequency (ratio 1.0) (n 1)) creates an nxy1cos
  199. generator. (nxy1cos gen (fm 0.0)) returns 2n cosines from frequency spaced by frequency * ratio with every other cosine multiplied by -1."))
  200. (lambda* (gen (fm 0.0))
  201. (let-set! gen 'fm fm)
  202. (with-let gen
  203. (let* ((x angle)
  204. (y (* x ratio))
  205. (den (cos (* y 0.5))))
  206. (set! angle (+ angle fm frequency))
  207. (if (< (abs den) nearly-zero)
  208. -1.0
  209. (max -1.0
  210. (min 1.0
  211. (/ (* (sin (* n y))
  212. (sin (+ x (* (- n 0.5) y))))
  213. (* 2 n den))))))))))
  214. #|
  215. (with-sound (:clipped #f :statistics #t :play #t)
  216. (let ((gen (make-nxy1cos 300 1/3 3)))
  217. (do ((i 0 (+ i 1)))
  218. ((= i 20000))
  219. (outa i (nxy1cos gen)))))
  220. (with-sound (:clipped #f :statistics #t :play #t)
  221. (let ((gen (make-nxy1cos 300 1/3 3))
  222. (gen1 (make-nxycos 300 1/3 6)))
  223. (do ((i 0 (+ i 1)))
  224. ((= i 20000))
  225. (outa i (* 0.4 (+ (nxycos gen1 0.0) (nxy1cos gen)))))))
  226. (with-sound (:clipped #f :statistics #t :play #t)
  227. (let ((gen (make-nxy1cos (radians->hz (* .01 pi)) 1.0 3)))
  228. (do ((i 0 (+ i 1)))
  229. ((= i 20000))
  230. (outa i (nxy1cos gen)))))
  231. |#
  232. (defgenerator (nxy1sin
  233. :make-wrapper (lambda (g)
  234. (set! (g 'frequency) (hz->radians (g 'frequency)))
  235. g))
  236. (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm)
  237. (define nxy1sin
  238. (let ((documentation "(make-nxy1sin frequency (ratio 1.0) (n 1)) creates an nxy1sin generator. (nxy1sin gen (fm 0.0))
  239. returns n sines from frequency spaced by frequency * ratio with every other sine multiplied by -1."))
  240. (lambda* (gen (fm 0.0))
  241. (let-set! gen 'fm fm)
  242. (with-let gen
  243. (let* ((x angle)
  244. (y (* x ratio))
  245. (den (cos (* y 0.5))))
  246. (set! angle (+ angle fm frequency))
  247. (/ (* (sin (+ x (* 0.5 (- n 1) (+ y pi))))
  248. (sin (* 0.5 n (+ y pi))))
  249. (* n den)))))))
  250. #|
  251. (with-sound (:clipped #f :statistics #t :play #t)
  252. (let ((gen (make-nxy1sin 300 1/3 3)))
  253. (do ((i 0 (+ i 1)))
  254. ((= i 20000))
  255. (outa i (nxy1sin gen)))))
  256. |#
  257. ;;; we can get the sinusoidally varying maxamp by using e.g. (make-nxy1sin 1 1000 3)
  258. ;;; the peak starts at ca .72 and goes to 1 etc
  259. ;;; the peak is just offset from pi (either way)
  260. ;;; --------------------------------------------------------------------------------
  261. ;;; n odd sinusoids: noddsin, noddcos, noddssb
  262. ;;; sndclm.html (G&R) first col 5th row (sum of odd sines)
  263. (define (find-noddsin-max n)
  264. (let find-mid-max ((n n)
  265. (lo 0.0000)
  266. (hi (/ pi (+ (* 2 n) 0.5))))
  267. (define (nodds x n)
  268. (let ((den (sin x))
  269. (num (sin (* n x))))
  270. (if (= den 0.0)
  271. 0.0000
  272. (/ (* num num) den))))
  273. (let ((mid (/ (+ lo hi) 2))
  274. (ylo (nodds lo n))
  275. (yhi (nodds hi n)))
  276. (if (< (abs (- ylo yhi)) 1e-09)
  277. (nodds mid n)
  278. (find-mid-max n (if (> ylo yhi)
  279. (values lo mid)
  280. (values mid hi)))))))
  281. (define noddsin-maxes (make-float-vector 100))
  282. (defgenerator (noddsin
  283. :make-wrapper (lambda (g)
  284. (set! (g 'n) (max (g 'n) 1))
  285. (set! (g 'frequency) (hz->radians (g 'frequency)))
  286. (if (not (and (< (g 'n) 100)
  287. (> (noddsin-maxes (g 'n)) 0.0)))
  288. (set! (noddsin-maxes (g 'n)) (find-noddsin-max (g 'n))))
  289. (set! (g 'norm) (/ 1.0 (noddsin-maxes (g 'n))))
  290. g))
  291. (frequency *clm-default-frequency*) (n 1) (angle 0.0) (norm 1.0) fm)
  292. (define noddsin
  293. (let ((documentation "(make-noddsin frequency (n 1)) creates an noddsin generator. (noddsin gen (fm 0.0))
  294. returns n odd-numbered sines spaced by frequency."))
  295. (lambda* (gen (fm 0.0))
  296. (let-set! gen 'fm fm)
  297. (with-let gen
  298. (let ((snx (sin (* n angle)))
  299. (den (sin angle)))
  300. (set! angle (+ angle fm frequency))
  301. (if (< (abs den) nearly-zero)
  302. 0.0
  303. (/ (* norm snx snx) den)))))))
  304. ;;; max is at about: 3*pi/(8*n) -- essentially half of the nsin peak
  305. ;;; and we end up with the same max amp as nsin!!
  306. ;;; :(/ (* 8 (sin (* pi 3/8)) (sin (* pi 3/8))) (* 3 pi))
  307. ;;; 7.245186202974229185687564326622851596478E-1
  308. #|
  309. ;;; clarinety
  310. (with-sound (:clipped #f :statistics #t :play #t)
  311. (let ((gen (make-noddsin 300 :n 3))
  312. (ampf (make-env '(0 0 1 1 2 1 3 0) :length 40000 :scaler .5)))
  313. (do ((i 0 (+ i 1)))
  314. ((= i 40000))
  315. (outa i (* (env ampf) (noddsin gen))))))
  316. |#
  317. (defgenerator (noddcos
  318. :make-wrapper (lambda (g)
  319. (set! (g 'frequency) (hz->radians (g 'frequency)))
  320. g))
  321. (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm)
  322. (define noddcos
  323. (let ((documentation "(make-noddcos frequency (n 1)) creates an noddcos generator. (noddcos gen (fm 0.0))
  324. returns n odd-numbered cosines spaced by frequency."))
  325. (lambda* (gen (fm 0.0))
  326. (let-set! gen 'fm fm)
  327. (with-let gen
  328. (let ((cx angle)
  329. (den (* 2 n (sin angle)))) ; "n" here is normalization
  330. (set! angle (+ angle fm frequency))
  331. (if (< (abs den) nearly-zero)
  332. (let ((fang (modulo cx (* 2 pi))))
  333. ;; hopefully this almost never happens...
  334. (if (or (< fang 0.001)
  335. (< (abs (- fang (* 2 pi))) 0.001))
  336. 1.0
  337. -1.0))
  338. (/ (sin (* 2 n cx)) den)))))))
  339. ;;; (Gradshteyn and Ryzhik 1.342)
  340. #|
  341. (with-sound (:clipped #f :statistics #t :play #t)
  342. (let ((gen (make-noddcos 100 :n 10)))
  343. (do ((i 0 (+ i 1)))
  344. ((= i 10000))
  345. (outa i (* .5 (noddcos gen))))))
  346. |#
  347. (defgenerator (noddssb
  348. :make-wrapper (lambda (g)
  349. (set! (g 'frequency) (hz->radians (g 'frequency)))
  350. g))
  351. (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm)
  352. (define noddssb
  353. (let ((documentation "(make-noddssb frequency (ratio 1.0) (n 1)) creates an noddssb generator. (noddssb gen (fm 0.0))
  354. returns n sinusoids from frequency spaced by 2 * ratio * frequency."))
  355. (lambda* (gen (fm 0.0))
  356. (let-set! gen 'fm fm)
  357. (with-let gen
  358. (let* ((cx angle)
  359. (mx (* cx ratio)))
  360. (let ((x (- cx mx))
  361. (sinnx (sin (* n mx)))
  362. (den (* n (sin mx)))) ; "n" is normalization
  363. (set! angle (+ angle fm frequency))
  364. (if (< (abs den) nearly-zero)
  365. (if (< (modulo mx (* 2 pi)) .1)
  366. -1.0
  367. 1.0)
  368. (- (* (sin x)
  369. (/ (* sinnx sinnx) den))
  370. (* (cos x)
  371. (/ (sin (* 2 n mx))
  372. (* 2 den)))))))))))
  373. #|
  374. (with-sound (:clipped #f :statistics #t :play #t)
  375. (let ((gen (make-noddssb 1000.0 0.1 5)))
  376. (do ((i 0 (+ i 1)))
  377. ((= i 10000))
  378. (outa i (* .5 (noddssb gen))))))
  379. (with-sound (:clipped #f :statistics #t :play #t)
  380. (let ((gen (make-noddssb 1000.0 0.1 5))
  381. (vib (make-oscil 5.0)))
  382. (do ((i 0 (+ i 1)))
  383. ((= i 10000))
  384. (outa i (* .5 (noddssb gen (* (hz->radians 100.0) (oscil vib))))))))
  385. |#
  386. ;;; --------------------------------------------------------------------------------
  387. ;;;
  388. ;;; various kernels: ncos2 = ncos squared (Fejer), ncos4 = ncos2 squared (Jackson), npcos = Poussin kernel
  389. (defgenerator (ncos2
  390. :make-wrapper (lambda (g)
  391. (set! (g 'frequency) (hz->radians (g 'frequency)))
  392. g))
  393. (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm)
  394. (define ncos2
  395. (let ((documentation "(make-ncos2 frequency (n 1)) creates an ncos2 (Fejer kernel) generator. (ncos2 gen (fm 0.0))
  396. returns n sinusoids spaced by frequency scaled by (n-k)/(n+1)"))
  397. ;; from "Trigonometric Series" Zygmund p88 with changes suggested by Katznelson "Introduction to Harmonic Analysis" p12, and
  398. ;; scaling by an extra factor of 1/n+1 to make sure we always peak at 1.0 (I assume callers in this context are interested
  399. ;; in the pulse-train aspect and want easily predictable peak amp). Harmonics go as (n-i)/n+1.
  400. (lambda* (gen (fm 0.0))
  401. (let-set! gen 'fm fm)
  402. (with-let gen
  403. (let* ((x angle)
  404. (den (sin (* 0.5 x))))
  405. (set! angle (+ angle fm frequency))
  406. (if (< (abs den) nearly-zero)
  407. 1.0
  408. (let ((val (/ (sin (* 0.5 (+ n 1) x))
  409. (* (+ n 1) den))))
  410. (* val val))))))))
  411. ;;; can't use two oscils here because the angles have to line up perfectly
  412. #|
  413. (with-sound (:clipped #f :statistics #t :play #t)
  414. (let ((gen (make-ncos2 100.0 :n 10)))
  415. (do ((i 0 (+ i 1)))
  416. ((= i 20000))
  417. (outa i (* .5 (ncos2 gen))))))
  418. |#
  419. (define make-ncos4 make-ncos2)
  420. ;; Katznelson p16
  421. (define ncos4
  422. (let ((documentation "(make-ncos4 frequency (n 1)) creates an ncos4 (Jackson kernel) generator. (ncos4 gen (fm 0.0))
  423. returns n sinusoids spaced by frequency scaled by ((n-k)/(n+1))^2"))
  424. (lambda* (gen (fm 0.0))
  425. (let ((val (ncos2 gen fm)))
  426. (* val val))))) ; we already normalized this to 1.0
  427. #|
  428. (with-sound (:clipped #f :statistics #t :play #t)
  429. (let ((gen (make-ncos4 100.0 :n 10)))
  430. (do ((i 0 (+ i 1)))
  431. ((= i 20000))
  432. (outa i (* .5 (ncos4 gen))))))
  433. |#
  434. (defgenerator (npcos
  435. :make-wrapper (lambda (g)
  436. (set! (g 'frequency) (hz->radians (g 'frequency)))
  437. g))
  438. (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm)
  439. (define npcos
  440. (let ((documentation "(make-npcos frequency (n 1)) creates an npcos (Poussin kernel) generator. (npcos gen (fm 0.0))
  441. returns n*2+1 sinusoids spaced by frequency with amplitudes in a sort of tent shape."))
  442. (lambda* (gen (fm 0.0))
  443. (let-set! gen 'fm fm)
  444. (with-let gen
  445. (let ((result (let ((den (sin (* 0.5 angle))))
  446. (if (< (abs den) nearly-zero)
  447. 1.0
  448. (let ((result1 (let ((val (let ((n1 (+ n 1)))
  449. (/ (sin (* 0.5 n1 angle))
  450. (* n1 den)))))
  451. (* val val)))
  452. (result2 (let ((val (let ((p2n2 (+ (* 2 n) 2)))
  453. (/ (sin (* 0.5 p2n2 angle))
  454. (* p2n2 den)))))
  455. (* val val))))
  456. (- (* 2 result2) result1))))))
  457. (set! angle (+ angle fm frequency))
  458. result)))))
  459. #|
  460. (with-sound (:clipped #f :statistics #t :play #t)
  461. (let ((gen (make-npcos 100.0 :n 10)))
  462. (do ((i 0 (+ i 1)))
  463. ((= i 20000))
  464. (outa i (* .5 (npcos gen))))))
  465. |#
  466. #|
  467. ;;; ncos5 and nsin5 are minor variants of nsin and ncos -- the last component is at half amplitude
  468. (defgenerator (ncos5
  469. :make-wrapper (lambda (g)
  470. (set! (g 'frequency) (hz->radians (g 'frequency)))
  471. g))
  472. (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm)
  473. (define ncos5
  474. (let ((documentation "(make-ncos5 frequency (n 1)) creates an ncos5 generator. (ncos5 gen (fm 0.0))
  475. returns n cosines spaced by frequency. All are equal amplitude except the first and last at half amp."))
  476. ;; from "Chebyshev Polynomials", Mason and Handscomb, p87
  477. (lambda* (gen (fm 0.0))
  478. (let-set! gen 'fm fm)
  479. (with-let gen
  480. (let* ((x angle)
  481. (den (tan (* 0.5 x))))
  482. (set! angle (+ angle fm frequency))
  483. (if (< (abs den) nearly-zero)
  484. 1.0
  485. (/ (- (/ (sin (* n x))
  486. (* 2 den))
  487. 0.5)
  488. (- n 0.5))))))))
  489. (with-sound (:clipped #f :statistics #t)
  490. (let ((gen (make-ncos5 100.0 :n 10)))
  491. (do ((i 0 (+ i 1)))
  492. ((= i 20000))
  493. (outa i (* .5 (ncos5 gen))))))
  494. (define (find-nsin5-max n)
  495. (define (find-mid-max n lo hi)
  496. (define (ns x n)
  497. (let* ((den (tan (* 0.5 x))))
  498. (if (< (abs den) nearly-zero)
  499. 0.0
  500. (/ (- 1.0 (cos (* n x)))
  501. den))))
  502. (let ((mid (/ (+ lo hi) 2)))
  503. (let ((ylo (ns lo n))
  504. (yhi (ns hi n)))
  505. (if (< (abs (- ylo yhi)) 1e-9)
  506. (ns mid n)
  507. (if (> ylo yhi)
  508. (find-mid-max n lo mid)
  509. (find-mid-max n mid hi))))))
  510. (find-mid-max n 0.0 (/ pi (+ n .5))))
  511. (defgenerator (nsin5
  512. :make-wrapper (lambda (g)
  513. (set! (g 'frequency) (hz->radians (g 'frequency)))
  514. (set! (g 'n) (max 2 (g 'n)))
  515. (set! (g 'norm) (find-nsin5-max (g 'n)))
  516. g))
  517. (frequency *clm-default-frequency*) (n 2) (angle 0.0) (norm 1.0) fm)
  518. (define nsin5
  519. (let ((documentation "(make-nsin5 frequency (n 1)) creates an nsin5 generator. (nsin5 gen (fm 0.0))
  520. returns n sines spaced by frequency. All are equal amplitude except last at half amp."))
  521. ;; from "Chebyshev Polynomials", Mason and Handscomb, p100
  522. (lambda* (gen (fm 0.0))
  523. (let-set! gen 'fm fm)
  524. (with-let gen
  525. (let* ((x angle)
  526. (den (tan (* 0.5 x))))
  527. (set! angle (+ angle fm frequency))
  528. (if (< (abs den) nearly-zero)
  529. 0.0
  530. (/ (- 1.0 (cos (* n x)))
  531. (* den norm))))))))
  532. (define (find-nsin-max n)
  533. (define (find-mid-max n lo hi)
  534. (define (ns x n)
  535. (let* ((a2 (/ x 2))
  536. (den (sin a2)))
  537. (if (= den 0.0)
  538. 0.0
  539. (/ (* (sin (* n a2)) (sin (* (+ 1 n) a2))) den))))
  540. (let ((mid (/ (+ lo hi) 2)))
  541. (let ((ylo (ns lo n))
  542. (yhi (ns hi n)))
  543. (if (< (abs (- ylo yhi)) 1e-14)
  544. (ns mid n) ; rationalize (/ mid pi) for location
  545. (if (> ylo yhi)
  546. (find-mid-max n lo mid)
  547. (find-mid-max n mid hi))))))
  548. (find-mid-max n 0.0 (/ pi (+ n .5))))
  549. (with-sound (:clipped #f :statistics #t)
  550. (let ((gen (make-nsin5 100.0 :n 10)))
  551. (do ((i 0 (+ i 1)))
  552. ((= i 20000))
  553. (outa i (nsin5 gen)))))
  554. (let ((norms (list 1.0 0.0)))
  555. (do ((i 2 (+ i 1)))
  556. ((= i 40))
  557. (let* ((res (with-sound (:clipped #f)
  558. (let ((gen (make-nsin5 100.0 :n i)))
  559. (do ((i 0 (+ i 1)))
  560. ((= i 20000))
  561. (outa i (nsin5 gen))))))
  562. (snd (find-sound res)))
  563. (format () ";~D: ~A" i (maxamp snd 0))
  564. (set! norms (cons (maxamp snd 0) norms))))
  565. (reverse norms))
  566. ;;; from the same book p 110 is atan(x)/x, if x=cos we get:
  567. (with-sound (:clipped #f :statistics #t)
  568. (let* ((x 0.0)
  569. (freq (hz->radians 100.0)))
  570. (do ((i 0 (+ i 1)))
  571. ((= i 20000))
  572. (outa i (/ (- (/ (atan (cos x))
  573. (cos x))
  574. (* 0.5 1.76275))
  575. -0.1187))
  576. (set! x (+ x freq)))))
  577. (let ((sum 0.0))
  578. (do ((s 1 (+ s 2)))
  579. ((>= s 100))
  580. (set! sum (+ sum (* 4 (/ (expt (- (sqrt 2.0) 1.0) (+ (* 2 s) 1))
  581. (+ (* 2 s) 1))))))
  582. sum) ; ~ 0.096
  583. ;;; the evens cancel, each of the odds gets through once
  584. |#
  585. (define generator-max-r 0.999999)
  586. (define generator-min-r -0.999999)
  587. (define (generator-clamp-r r)
  588. (min generator-max-r (max generator-min-r r)))
  589. ;;; --------------------------------------------------------------------------------
  590. ;;;
  591. ;;; n sinusoids scaled by r: nrsin, nrcos, nrssb
  592. #|
  593. (define nrsin-methods
  594. (list
  595. (cons 'mus-frequency
  596. (dilambda
  597. (lambda (g) (mus-frequency (g 'gen)))
  598. (lambda (g val) (set! (mus-frequency (g 'gen)) val))))
  599. (cons 'mus-scaler
  600. (dilambda
  601. (lambda (g) (mus-scaler (g 'gen)))
  602. (lambda (g val) (set! (mus-scaler (g 'gen)) val))))))
  603. (defgenerator (nrsin
  604. :make-wrapper (lambda (g)
  605. (set! (g 'r) (generator-clamp-r (g 'r)))
  606. (set! (g 'gen) (make-nrxysin (g 'frequency) 1.0 (g 'n) (g 'r)))
  607. g)
  608. :methods nrsin-methods)
  609. (frequency *clm-default-frequency*) (n 1) (r 0.5)
  610. (gen #f))
  611. |#
  612. (define make-nrsin make-nrxysin)
  613. (define nrsin nrxysin)
  614. (define nrsin? nrxysin?)
  615. ;; "(make-nrsin frequency (n 1) (r 0.5)) creates an nrsin generator.\n\
  616. ;; (nrsin gen (fm 0.0)) returns n sines spaced by frequency with amplitudes scaled by r^k."
  617. (define (nrcos-set-scaler g val)
  618. (set! (g 'r) (min 0.999999 (max -0.999999 val)))
  619. (with-let g
  620. (let ((absr (abs r)))
  621. (set! rr (* r r))
  622. (set! r1 (+ 1.0 rr))
  623. (set! norm (- (/ (- (expt absr n) 1) (- absr 1)) 1.0))
  624. (set! trouble (or (= n 1)
  625. (< absr 1.0e-12)))))
  626. val)
  627. (define nrcos-methods
  628. (list
  629. (cons 'mus-order
  630. (dilambda
  631. (lambda (g) (- (g 'n) 1))
  632. (lambda (g val)
  633. (set! (g 'n) (+ 1 val))
  634. (set! (g 'e1) (expt (g 'r) (g 'n)))
  635. (set! (g 'e2) (expt (g 'r) (+ (g 'n) 1)))
  636. (set! (g 'norm) (- (/ (- (expt (abs (g 'r)) (g 'n)) 1) (- (abs (g 'r)) 1)) 1.0))
  637. (set! (g 'trouble) (or (= (g 'n) 1) (< (abs (g 'r)) nearly-zero)))
  638. val)))
  639. (cons 'mus-frequency
  640. (dilambda
  641. (lambda (g) (radians->hz (g 'frequency)))
  642. (lambda (g val) (set! (g 'frequency) (hz->radians val)))))
  643. (cons 'mus-scaler
  644. (dilambda
  645. (lambda (g) (g 'r))
  646. nrcos-set-scaler))))
  647. (defgenerator (nrcos
  648. :make-wrapper (lambda (g)
  649. (set! (g 'frequency) (hz->radians (g 'frequency)))
  650. (set! (g 'n) (+ 1 (g 'n)))
  651. (set! (g 'r) (generator-clamp-r (g 'r)))
  652. (set! (g 'rr) (* (g 'r) (g 'r)))
  653. (set! (g 'r1) (+ 1.0 (g 'rr)))
  654. (set! (g 'e1) (expt (g 'r) (g 'n)))
  655. (set! (g 'e2) (expt (g 'r) (+ (g 'n) 1)))
  656. (set! (g 'norm) (- (/ (- (expt (abs (g 'r)) (g 'n)) 1) (- (abs (g 'r)) 1)) 1.0)) ; n+1??
  657. (set! (g 'trouble) (or (= (g 'n) 1) (< (abs (g 'r)) nearly-zero)))
  658. g)
  659. :methods nrcos-methods)
  660. (frequency *clm-default-frequency*) (n 1) (r 0.5) (angle 0.0) fm rr r1 e1 e2 norm trouble)
  661. (define nrcos
  662. (let ((documentation "(make-nrcos frequency (n 1) (r 0.5)) creates an nrcos generator. (nrcos gen (fm 0.0))
  663. returns n cosines spaced by frequency with amplitudes scaled by r^k."))
  664. (lambda* (gen (fm 0.0))
  665. (let-set! gen 'fm fm)
  666. (with-let gen
  667. (let ((x angle)
  668. (rcos (* r (cos angle))))
  669. (set! angle (+ angle fm frequency))
  670. (if trouble
  671. 0.0
  672. (/ (- (+ rcos (* e2 (cos (* (- n 1) x))))
  673. (* e1 (cos (* n x))) rr)
  674. (* norm (+ r1 (* -2.0 rcos))))))))))
  675. ;; it's faster to use polywave here and nrcos->polywave for the partials list (animals.scm) if n is not enormous
  676. ;;; formula changed to start at k=1 and n increased so we get 1 to n
  677. ;;; here is the preoptimization form:
  678. #|
  679. (with-let gen
  680. (let ((x angle))
  681. (set! angle (+ angle fm frequency))
  682. (if (or (= n 1)
  683. (< (abs r) nearly-zero))
  684. 0.0
  685. (let ((norm (- (/ (- (expt (abs r) n) 1) (- (abs r) 1)) 1.0))) ; n+1??
  686. (/ (+ (- (* r (cos x))
  687. (* (expt r n) (cos (* n x))) (* r r))
  688. (* (expt r (+ n 1)) (cos (* (- n 1) x))))
  689. (* norm (+ 1.0 (* -2.0 r (cos x)) (* r r))))))))
  690. |#
  691. #|
  692. (with-sound (:clipped #f :statistics #t :play #t)
  693. (let ((gen (make-nrcos 400.0 :n 5 :r 0.5)))
  694. (do ((i 0 (+ i 1)))
  695. ((= i 10000))
  696. (outa i (* .5 (nrcos gen))))))
  697. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .1)
  698. (let ((gen (make-nrcos 1200.0 :n 3 :r 0.99))
  699. (mod (make-oscil 400.0)) ; multi-carrier fm
  700. (index 0.01))
  701. (do ((i 0 (+ i 1)))
  702. ((= i 30000))
  703. (outa i (nrcos gen (* index (oscil mod)))))))
  704. (with-sound (:clipped #f :statistics #t :play #t)
  705. (let ((gen (make-nrcos 2000.0 :n 3 :r 0.5))
  706. (mod (make-oscil 400.0)) ; multi-carrier fm
  707. (index 0.02))
  708. (do ((i 0 (+ i 1)))
  709. ((= i 30000))
  710. (outa i (* .5 (nrcos gen (* index (oscil mod))))))))
  711. (with-sound (:clipped #f :statistics #t :play #t)
  712. (let ((gen (make-nrcos 2000.0 :n 3 :r 0.5))
  713. (mod (make-oscil 400.0))
  714. (index (make-env '(0 0 1 .1) :length 30000))) ; or '(0 .4 1 0)
  715. (do ((i 0 (+ i 1)))
  716. ((= i 30000))
  717. (outa i (* .5 (nrcos gen (* (env index) (oscil mod))))))))
  718. |#
  719. (definstrument (lutish beg dur freq amp)
  720. (let ((res1 (max 1 (round (/ 1000.0 (max 1.0 (min 1000.0 freq))))))
  721. (maxind (max .01 (min .3 (/ (- (log freq) 3.5) 8.0)))))
  722. (let ((gen (make-nrcos (* freq res1) :n (max 1 (- res1 2))))
  723. (mod (make-oscil freq))
  724. (start (seconds->samples beg))
  725. (stop (seconds->samples (+ beg dur)))
  726. (index (make-env (list 0 maxind 1 (* maxind .25) (max dur 2.0) 0.0) :duration dur))
  727. (amplitude (make-env (list 0 0 .01 1 .2 1 .5 .5 1 .25 (max dur 2.0) 0.0) :duration dur :scaler amp)))
  728. (do ((i start (+ i 1)))
  729. ((= i stop))
  730. (let ((ind (env index)))
  731. (set! (gen 'r) ind)
  732. (outa i (* (env amplitude)
  733. (nrcos gen (* ind (oscil mod))))))))))
  734. #|
  735. (with-sound (:clipped #f :statistics #t :play #t)
  736. (lutish 0 1 440 .1))
  737. (with-sound (:clipped #f :statistics #t :play #t)
  738. (do ((i 0 (+ i 1)))
  739. ((= i 10))
  740. (lutish (* i .1) 2 (* 100 (+ i 1)) .05)))
  741. |#
  742. ;;; G&R second col first and second rows
  743. (defgenerator (nrssb
  744. :make-wrapper (lambda (g)
  745. (set! (g 'frequency) (hz->radians (g 'frequency)))
  746. (set! (g 'r) (generator-clamp-r (g 'r)))
  747. (set! (g 'r) (max (g 'r) 0.0))
  748. (set! (g 'rn) (- (expt (g 'r) (g 'n))))
  749. (set! (g 'rn1) (expt (g 'r) (+ (g 'n) 1)))
  750. (set! (g 'norm) (/ (- (g 'rn) 1) (- (g 'r) 1)))
  751. g))
  752. (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (r 0.5) (angle 0.0) fm interp rn rn1 norm)
  753. (define nrssb
  754. (let ((documentation "(make-nrssb frequency (ratio 1.0) (n 1) (r 0.5)) creates an nrssb generator. (nrssb gen (fm 0.0))
  755. returns n sinusoids from frequency spaced by frequency * ratio with amplitudes scaled by r^k."))
  756. (lambda* (gen (fm 0.0))
  757. (let-set! gen 'fm fm)
  758. (with-let gen
  759. (let* ((cx angle)
  760. (mx (* cx ratio)))
  761. (let ((nmx (* n mx))
  762. (n1mx (* (- n 1) mx))
  763. (den (* norm (+ 1.0 (* -2.0 r (cos mx)) (* r r)))))
  764. (set! angle (+ angle fm frequency))
  765. (/ (- (* (sin cx)
  766. (+ (* r (sin mx))
  767. (* rn (sin nmx))
  768. (* rn1 (sin n1mx))))
  769. (* (cos cx)
  770. (+ 1.0
  771. (* -1.0 r (cos mx))
  772. (* rn (cos nmx))
  773. (* rn1 (cos n1mx)))))
  774. den)))))))
  775. (define nrssb-interp
  776. (let ((documentation "(make-nrssb frequency (ratio 1.0) (n 1) (r 0.5)) creates an nrssb generator for use with
  777. nrssb-interp. (nrssb-interp gen fm interp) returns n sinusoids from frequency spaced by frequency * ratio with amplitudes
  778. scaled by r^k. The 'interp' argument determines whether the sidebands are above (1.0) or below (-1.0) frequency."))
  779. (lambda (gen fm interp)
  780. (let-set! gen 'fm fm)
  781. (let-set! gen 'interp interp)
  782. (with-let gen
  783. (let* ((cx angle)
  784. (mx (* cx ratio)))
  785. (let ((nmx (* n mx))
  786. (n1mx (* (- n 1) mx))
  787. (den (* norm (+ 1.0 (* -2.0 r (cos mx)) (* r r)))))
  788. (set! angle (+ angle fm frequency))
  789. (/ (- (* interp
  790. (sin cx)
  791. (+ (* r (sin mx))
  792. (* rn (sin nmx))
  793. (* rn1 (sin n1mx))))
  794. (* (cos cx)
  795. (+ 1.0
  796. (* -1.0 r (cos mx))
  797. (* rn (cos nmx))
  798. (* rn1 (cos n1mx)))))
  799. den)))))))
  800. #|
  801. (with-sound (:clipped #f :statistics #t :play #t)
  802. (let ((gen (make-nrssb 1000 0.1 5 0.5)))
  803. (do ((i 0 (+ i 1)))
  804. ((= i 10000))
  805. (outa i (nrssb gen)))))
  806. (with-sound (:clipped #f :statistics #t :play #t)
  807. (let ((gen (make-nrssb 1000 0.1 5 0.5))
  808. (vib (make-oscil 5)))
  809. (do ((i 0 (+ i 1)))
  810. ((= i 10000))
  811. (outa i (nrssb gen (* (hz->radians 100) (oscil vib)))))))
  812. |#
  813. (definstrument (oboish beg dur freq amp aenv)
  814. (let ((res1 (max 1 (round (/ 1400.0 (max 1.0 (min 1400.0 freq))))))
  815. (mod1 (make-oscil 5.0))
  816. (res2 (max 1 (round (/ 2400.0 (max 1.0 (min 2400.0 freq))))))
  817. (gen3 (make-oscil freq))
  818. (start (seconds->samples beg))
  819. (amplitude (make-env aenv :duration dur :base 4 :scaler amp))
  820. (skenv (make-env (list 0.0 0.0 1 1 2.0 (mus-random 1.0) 3.0 0.0 (max 4.0 (* dur 20.0)) 0.0)
  821. :duration dur :scaler (hz->radians (random (* freq .05)))))
  822. (relamp (+ .85 (random .1)))
  823. (avib (make-rand-interp 5 .2))
  824. (hfreq (hz->radians freq))
  825. (h3freq (hz->radians (* .003 freq)))
  826. (scl (/ 0.05 amp)))
  827. (let ((gen (make-nrssb (* freq res1) (/ res1) :n res1 :r 0.75))
  828. (gen2 (make-oscil (* freq res2)))
  829. (stop (+ start (seconds->samples dur))))
  830. (do ((i start (+ i 1)))
  831. ((= i stop))
  832. (let ((result (let* ((vol (* (+ .8 (rand-interp avib))
  833. (env amplitude)))
  834. (vola (* scl vol))
  835. (vib (+ (* h3freq (oscil mod1))
  836. (env skenv))))
  837. (* vol
  838. (+ (* (- relamp vola)
  839. (nrssb-interp gen (* res1 vib) -1.0))
  840. (* (- (+ 1.0 vola) relamp)
  841. (oscil gen2 (+ (* vib res2)
  842. (* hfreq (oscil gen3 vib))))))))))
  843. (outa i result)
  844. (if *reverb* (outa i (* .01 result) *reverb*)))))))
  845. #|
  846. (with-sound (:clipped #f :statistics #t :play #t)
  847. (oboish 0 1 300 .1 '(0 0 1 1 2 0)))
  848. (with-sound (:clipped #f :statistics #t :play #t)
  849. (do ((i 0 (+ i 1)))
  850. ((= i 10))
  851. (oboish (* i .3) .4 (+ 100 (* 50 i)) .05 '(0 0 1 1 2 1 3 0))))
  852. (with-sound (:clipped #f :statistics #t :play #t)
  853. (let ((rats (vector 1 256/243 9/8 32/27 81/64 4/3 1024/729 3/2 128/81 27/16 16/9 243/128 2))
  854. (mode (vector 0 0 2 4 11 11 5 6 7 9 2 12 0)))
  855. (do ((i 0 (+ i 1)))
  856. ((= i 20))
  857. (oboish (/ (random 32) 8)
  858. (/ (+ 3 (random 8)) 8)
  859. (* 16.351 16 (rats (mode (random 12))))
  860. (+ .25 (random .25))
  861. (let* ((pt1 (random 1.0))
  862. (pt2 (+ pt1 (random 1.0)))
  863. (pt3 (+ pt2 (random 1.0))))
  864. (list 0 0 pt1 1 pt2 .5 pt3 0))))))
  865. ;;; .85 .15 (* 2 freq) 300, 2400 + 0.5*vib
  866. |#
  867. ;;; --------------------------------------------------------------------------------
  868. ;;;
  869. ;;; n sinusoids scaled by k: nkssb
  870. ;;; G&R first col ksinkx cases
  871. (define nkssb-methods
  872. (list
  873. (cons 'mus-order
  874. (dilambda
  875. (lambda (g) (- (g 'n) 1))
  876. (lambda (g val)
  877. (set! (g 'n) (+ 1 val))
  878. (set! (g 'norm) (/ (* 0.5 val (- val 1))))))))) ; nominal n is off by 1
  879. (defgenerator (nkssb
  880. :make-wrapper (lambda (g)
  881. (set! (g 'frequency) (hz->radians (g 'frequency)))
  882. (set! (g 'n) (+ 1 (g 'n))) ; sum goes 1 to n-1
  883. (set! (g 'norm) (/ (* 0.5 (g 'n) (- (g 'n) 1))))
  884. g)
  885. :methods nkssb-methods)
  886. (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm interp norm)
  887. (define nkssb
  888. (let ((documentation "(make-nkssb frequency (ratio 1.0) (n 1)) creates an nkssb generator. (nkssb gen (fm 0.0))
  889. returns n sinusoids from frequency spaced by frequency * ratio with amplitude k."))
  890. (lambda* (gen (fm 0.0))
  891. (let-set! gen 'fm fm)
  892. (with-let gen
  893. (let ((x (* angle ratio)))
  894. (let ((cxx (- angle x))
  895. (sx2 (sin (* 0.5 x)))
  896. (nx (* n x))
  897. (nx2 (* 0.5 (- (* 2 n) 1) x)))
  898. (let ((sx22 (* 2 sx2))
  899. (sxsx (* 4 sx2 sx2)))
  900. (set! angle (+ angle fm frequency))
  901. (if (< (abs sx2) 1.0e-8)
  902. -1.0
  903. (let ((s1 (- (/ (sin nx) sxsx)
  904. (/ (* n (cos nx2)) sx22)))
  905. (c1 (- (/ (* n (sin nx2)) sx22)
  906. (/ (- 1.0 (cos nx)) sxsx))))
  907. (* (- (* s1 (sin cxx))
  908. (* c1 (cos cxx)))
  909. norm))))))))))
  910. (define nkssb-interp
  911. (let ((documentation " (make-nkssb-interp frequency (ratio 1.0) (n 1)) creates an nkssb generator for
  912. nkssb-interp. (nkssb-interp gen fm interp) returns n sinusoids from frequency spaced by frequency * ratio
  913. with amplitude k. The 'interp' argument determines whether the sidebands are above (1.0) or below (-1.0) frequency."))
  914. (lambda (gen fm interp)
  915. (let-set! gen 'fm fm)
  916. (let-set! gen 'interp interp)
  917. (with-let gen
  918. (let ((x (* angle ratio)))
  919. (let ((cxx (- angle x))
  920. (sx2 (sin (* 0.5 x))))
  921. (let ((sx22 (* 2 sx2))
  922. (sxsx (* 4 sx2 sx2))
  923. (nx (* n x))
  924. (nx2 (* 0.5 (- (* 2 n) 1) x)))
  925. (set! angle (+ angle fm frequency))
  926. (if (< (abs sx2) 1.0e-8)
  927. 1.0
  928. (let ((s1 (- (/ (sin nx) sxsx)
  929. (/ (* n (cos nx2)) sx22)))
  930. (c1 (- (/ (* n (sin nx2)) sx22)
  931. (/ (- 1.0 (cos nx)) sxsx))))
  932. (* (- (* c1 (cos cxx))
  933. (* interp (sin cxx) s1))
  934. norm)))))))))) ; peak seems to be solid right through the interpolation
  935. #|
  936. (with-sound (:clipped #f :statistics #t :play #t)
  937. (let ((gen (make-nkssb 1000.0 0.1 5)))
  938. (do ((i 0 (+ i 1)))
  939. ((= i 10000))
  940. (outa i (nkssb gen)))))
  941. (with-sound (:clipped #f :statistics #t :play #t)
  942. (let ((gen (make-nkssb 1000.0 0.1 5))
  943. (vib (make-oscil 5.0))
  944. (vibamp (hz->radians 50.0)))
  945. (do ((i 0 (+ i 1)))
  946. ((= i 30000))
  947. (outa i (nkssb gen (* vibamp (oscil vib)))))))
  948. |#
  949. (definstrument (nkssber beg dur freq mfreq n vibfreq amp)
  950. (let ((start (seconds->samples beg))
  951. (stop (seconds->samples (+ beg dur)))
  952. (gen (make-nkssb freq (/ mfreq freq) n))
  953. (move (make-env '(0 1 1 -1) :duration dur))
  954. (vib (make-polywave vibfreq (list 1 (hz->radians (* (/ freq mfreq) 5.0))) mus-chebyshev-second-kind))
  955. (ampf (make-env '(0 0 1 1 5 1 6 0) :scaler amp :duration dur)))
  956. (do ((i start (+ i 1)))
  957. ((= i stop))
  958. (outa i (* (env ampf)
  959. (nkssb-interp gen
  960. (polywave vib)
  961. (env move))) ; interp env
  962. ))))
  963. #|
  964. (with-sound (:play #t)
  965. (nkssber 0 1 1000 100 5 5 0.5)
  966. (nkssber 1 2 600 100 4 1 0.5)
  967. (nkssber 3 2 1000 540 3 3 0.5)
  968. (nkssber 5 4 300 120 2 0.25 0.5)
  969. (nkssber 9 1 30 4 40 0.5 0.5)
  970. (nkssber 10 1 20 6 80 0.5 0.5))
  971. (with-sound (:clipped #f :statistics #t :play #t)
  972. (let ((gen (make-nkssb 1000.0 0.1 5))
  973. (move (make-env '(0 1 1 -1) :length 30000))
  974. (vib (make-oscil 5.0))
  975. (vibamp (hz->radians 50.0)))
  976. (do ((i 0 (+ i 1)))
  977. ((= i 30000))
  978. (outa i (* 0.5 (nkssb-interp gen
  979. (* vibamp (oscil vib))
  980. (env move))) ; interp env
  981. ))))
  982. (with-sound (:clipped #f :statistics #t :play #t)
  983. (let ((gen (make-nkssb 600.0 1/6 4))
  984. (vib (make-oscil 1.0))
  985. (vibamp (hz->radians 30.0)))
  986. (do ((i 0 (+ i 1)))
  987. ((= i 100000))
  988. (let ((intrp (oscil vib)))
  989. (outa i (* 0.5 (nkssb-interp gen
  990. (* vibamp intrp)
  991. intrp)))))))
  992. (with-sound (:clipped #f :statistics #t :play #t)
  993. (let ((gen (make-nkssb 1000.0 (/ 540 1000) 3))
  994. (vib (make-oscil 3.0)) ; 0.3 or 125 + 0.25 and 2 -> circling sound
  995. (vibamp (hz->radians (* (/ 1000 540) 5.0))))
  996. (do ((i 0 (+ i 1)))
  997. ((= i 100000))
  998. (let ((intrp (oscil vib)))
  999. (outa i (* 0.5 (nkssb-interp gen
  1000. (* vibamp intrp)
  1001. intrp)))))))
  1002. (with-sound (:clipped #f :statistics #t :play #t)
  1003. (let ((gen (make-nkssb 300.0 (/ 120 300) 2))
  1004. (vib (make-oscil 0.25))
  1005. (vibamp (hz->radians (* (/ 300 120) 5.0))))
  1006. (do ((i 0 (+ i 1)))
  1007. ((= i 300000))
  1008. (let ((intrp (oscil vib)))
  1009. (outa i (* 0.5 (nkssb-interp gen
  1010. (* vibamp intrp)
  1011. intrp)))))))
  1012. (with-sound (:clipped #f :statistics #t :play #t)
  1013. (let ((gen (make-nkssb 30.0 (/ 4 30) 40))
  1014. (vib (make-oscil 0.5))
  1015. (vibamp (hz->radians (* (/ 30 4) 5.0))))
  1016. (do ((i 0 (+ i 1)))
  1017. ((= i 300000))
  1018. (let ((intrp (oscil vib)))
  1019. (outa i (* 0.5 (nkssb-interp gen
  1020. (* vibamp intrp)
  1021. intrp)))))))
  1022. (with-sound (:clipped #f :statistics #t :play #t)
  1023. (let ((gen (make-nkssb 20.0 (/ 6 20) 80)) ; 120 8 80 (100), 6 400
  1024. (vib (make-oscil 0.5))
  1025. (vibamp (hz->radians (* (/ 20 6) 5.0))))
  1026. (do ((i 0 (+ i 1)))
  1027. ((= i 300000))
  1028. (let ((intrp (oscil vib)))
  1029. (outa i (* 0.5 (nkssb-interp gen
  1030. (* vibamp intrp)
  1031. intrp)))))))
  1032. |#
  1033. ;;; --------------------------------------------------------------------------------
  1034. ;;; n cos scaled by sin(k*pi/(n+1))/sin(pi/(n+1))
  1035. ;;; "Biased Trigonometric Polynomials", Montgomery and Vorhauer
  1036. ;;; American Math Monthly vol 114 no 9 Nov 2007
  1037. (defgenerator (nsincos
  1038. :make-wrapper (lambda (g)
  1039. (let ((n (g 'n)))
  1040. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1041. (set! (g 'n2) (/ (+ n 1) 2))
  1042. (set! (g 'cosn) (cos (/ pi (+ n 1))))
  1043. (do ((k 1 (+ k 1)))
  1044. ((> k n))
  1045. (set! (g 'norm) (+ (g 'norm)
  1046. (/ (sin (/ (* k pi) (+ n 1)))
  1047. (sin (/ pi (+ n 1)))))))
  1048. g)))
  1049. (frequency *clm-default-frequency*) (n 1)
  1050. (angle 0.0) (n2 1.0) (cosn 1.0) (norm 0.0) fm)
  1051. (define nsincos
  1052. (let ((documentation "(make-nsincos frequency (n 1)) creates an nsincos generator. (nsincos gen (fm 0.0))
  1053. returns n cosines spaced by frequency with amplitude sin(k*pi/(n+1))/sin(pi/(n+1))"))
  1054. (lambda* (gen (fm 0.0))
  1055. (let-set! gen 'fm fm)
  1056. (with-let gen
  1057. (let* ((x angle)
  1058. (num (cos (* n2 x))))
  1059. (set! angle (+ angle fm frequency))
  1060. (/ (* num num)
  1061. (* norm (- (cos x) cosn))))))))
  1062. #|
  1063. (with-sound (:clipped #f :statistics #t :play #f)
  1064. (let ((gen (make-nsincos 100.0 3)))
  1065. (do ((i 0 (+ i 1)))
  1066. ((= i 20000))
  1067. (outa i (nsincos gen)))))
  1068. |#
  1069. ;;; --------------------------------------------------------------------------------
  1070. ;;;
  1071. ;;; Ramanujan, "On certain Arithmetical Functions"
  1072. (defgenerator (n1cos
  1073. :make-wrapper (lambda (g)
  1074. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1075. g))
  1076. (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm)
  1077. (define* (n1cos gen (fm 0.0))
  1078. (let-set! gen 'fm fm)
  1079. (with-let gen
  1080. (let* ((x angle)
  1081. (tn (tan (* 0.5 x))))
  1082. (set! angle (+ angle fm frequency))
  1083. (if (< (abs tn) 1.0e-6)
  1084. 1.0
  1085. (/ (- 1.0 (cos (* n x)))
  1086. (* tn tn
  1087. n n 2)))))) ; normalization -- this still has the very large DC term
  1088. #|
  1089. (with-sound (:clipped #f)
  1090. (let ((gen (make-n1cos 100.0 10)))
  1091. (do ((i 0 (+ i 1)))
  1092. ((= i 44100))
  1093. (outa i (n1cos gen)))))
  1094. |#
  1095. #|
  1096. ;;; --------------------------------------------------------------------------------
  1097. ;;; not sure the next two are interesting -- 2 more kernels
  1098. ;;; Dimitrov and Merlo
  1099. (defgenerator (npos1cos
  1100. :make-wrapper (lambda (g)
  1101. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1102. g))
  1103. (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm)
  1104. (define npos1cos
  1105. (let ((documentation "(make-npos1cos frequency (n 1)) creates an npos1cos generator. (npos1cos gen (fm 0.0))
  1106. returns n cosines spaced by frequency."))
  1107. (lambda* (gen (fm 0.0))
  1108. (let-set! gen 'fm fm)
  1109. (with-let gen
  1110. (let* ((x angle)
  1111. (num (- (* (+ n 2) (sin (/ (* n x) 2)))
  1112. (* n (sin (/ (* (+ n 2) x) 2)))))
  1113. (sx (sin (/ x 2)))
  1114. (den (* 4 n (+ n 1) (+ n 2) sx sx sx sx)))
  1115. (set! angle (+ angle fm frequency))
  1116. (if (< (abs den) nearly-zero)
  1117. 0.0
  1118. (/ (* 3 num num)
  1119. den)))))))
  1120. ;;; needs normalization and no DC. side amps seem close
  1121. (with-sound (:clipped #f :statistics #t :play #f)
  1122. (let ((gen (make-npos1cos 100.0 3)))
  1123. (do ((i 0 (+ i 1)))
  1124. ((= i 20000))
  1125. (outa i (npos1cos gen)))))
  1126. (defgenerator (npos3cos
  1127. :make-wrapper (lambda (g)
  1128. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1129. g))
  1130. (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm)
  1131. (define npos3cos
  1132. (let ((documentation "(make-npos3cos frequency (n 1)) creates an npos3cos generator. (npos3cos gen (fm 0.0))
  1133. returns n cosines spaced by frequency."))
  1134. (lambda* (gen (fm 0.0))
  1135. (let-set! gen 'fm fm)
  1136. (with-let gen
  1137. (let* ((x angle)
  1138. (sx (sin (/ x 2)))
  1139. (den (* (+ (* 4 n) 2) sx sx)))
  1140. (set! angle (+ angle fm frequency))
  1141. (if (< (abs den) nearly-zero)
  1142. (* 1.0 n)
  1143. (/ (- 2 (cos (* n x)) (cos (* (+ n 1) x)))
  1144. den)))))))
  1145. ;;; needs normalization and no DC, peak at den=0 not right. side amps seem close
  1146. (with-sound (:clipped #f :statistics #t :play #f)
  1147. (let ((gen (make-npos3cos 100.0 3)))
  1148. (do ((i 0 (+ i 1)))
  1149. ((= i 20000))
  1150. (outa i (npos3cos gen)))))
  1151. |#
  1152. ;;; --------------------------------------------------------------------------------
  1153. ;;;
  1154. ;;; inf sinusoids scaled by r: rcos, rssb
  1155. (define rcos-methods
  1156. (list
  1157. (cons 'mus-frequency
  1158. (dilambda
  1159. (lambda (g) (mus-frequency (g 'osc)))
  1160. (lambda (g val) (set! (mus-frequency (g 'osc)) val))))
  1161. (cons 'mus-scaler
  1162. (dilambda
  1163. (lambda (g) (g 'r))
  1164. (lambda (g val)
  1165. (set! (g 'r) (generator-clamp-r val))
  1166. (set! (g 'rr) (* (g 'r) (g 'r)))
  1167. (set! (g 'rr+1) (+ 1.0 (g 'rr)))
  1168. (set! (g 'rr-1) (- 1.0 (g 'rr)))
  1169. (set! (g 'r2) (* 2.0 (g 'r)))
  1170. (let ((absr (abs (g 'r))))
  1171. (set! (g 'norm) (if (< absr nearly-zero) 0.0 (/ (- 1.0 absr) (* 2.0 absr)))))
  1172. val)))
  1173. (cons 'mus-phase
  1174. (dilambda
  1175. (lambda (g) (mus-phase (g 'osc)))
  1176. (lambda (g val) (set! (mus-phase (g 'osc)) val))))))
  1177. (defgenerator (rcos
  1178. :make-wrapper (lambda (g)
  1179. (set! (g 'osc) (make-oscil (g 'frequency) (* 0.5 pi)))
  1180. (set! (g 'r) (generator-clamp-r (g 'r)))
  1181. (set! (g 'rr) (* (g 'r) (g 'r)))
  1182. (set! (g 'rr+1) (+ 1.0 (g 'rr)))
  1183. (set! (g 'rr-1) (- 1.0 (g 'rr)))
  1184. (set! (g 'r2) (* 2.0 (g 'r)))
  1185. (let ((absr (abs (g 'r))))
  1186. (set! (g 'norm) (if (< absr nearly-zero) 0.0 (/ (- 1.0 absr) (* 2.0 absr)))))
  1187. g)
  1188. :methods rcos-methods)
  1189. (frequency *clm-default-frequency*) (r 0.5) fm
  1190. (osc #f) rr norm rr+1 rr-1 r2)
  1191. (define rcos
  1192. (let ((documentation "(make-rcos frequency (r 0.5)) creates an rcos generator. (rcos gen (fm 0.0))
  1193. returns many cosines spaced by frequency with amplitude r^k."))
  1194. ;; from Andrews, Askey, Roy "Special Functions" 5.1.16, p243. r^k cos sum
  1195. ;; a variant of the G&R second col 4th row
  1196. (lambda* (gen (fm 0.0))
  1197. (let-set! gen 'fm fm)
  1198. (with-let gen
  1199. (* (- (/ rr-1 (- rr+1 (* r2 (oscil osc fm)))) 1.0) norm)))))
  1200. #|
  1201. (with-let gen
  1202. (let ((absr (abs r))
  1203. (rr (* r r)))
  1204. (if (< absr nearly-zero)
  1205. 0.0 ; 1.0 from the formula, but we're subtracting out DC
  1206. (* (- (/ (- 1.0 rr)
  1207. (- (+ 1.0 rr)
  1208. (* 2.0 r (oscil osc fm))))
  1209. 1.0)
  1210. (/ (- 1.0 absr) (* 2.0 absr))))))) ; normalization
  1211. |#
  1212. #|
  1213. ;;; G&R form:
  1214. (define* (rcos gen (fm 0.0))
  1215. (let-set! gen 'fm fm)
  1216. (with-let gen
  1217. (let* ((absr (abs r))
  1218. (rcosx (* r (oscil osc fm))))
  1219. (* (- (/ (- 1.0 rcosx)
  1220. (+ 1.0
  1221. (* r r)
  1222. (* -2.0 rcosx)))
  1223. 1.0)
  1224. (/ (- 1.0 absr) absr))))) ; normalization
  1225. |#
  1226. ;;; if r>0 we get the spike at multiples of 2pi, since the k*pi case is flipping -1 1 -1 etc
  1227. ;;; if r<0, we get the spike at multiples of (2k-1)pi since the r sign now counteracts the cos k*pi sign
  1228. ;;; so the peak amp is the same in the two cases, so the normalization has to use abs(r)!
  1229. ;;; but in the k*pi case we tend to miss k*pi (whereas we never miss 0 since we start there),
  1230. ;;; so the actual maxamp may be less than 1.0
  1231. #|
  1232. (with-sound (:clipped #f :statistics #t :play #t)
  1233. (let ((gen (make-rcos 100.0 :r 0.5)))
  1234. (do ((i 0 (+ i 1)))
  1235. ((= i 20000))
  1236. (outa i (rcos gen)))))
  1237. |#
  1238. ;; this uses rkoddssb below
  1239. (definstrument (stringy beg dur freq amp)
  1240. (let ((n (floor (/ *clm-srate* (* 3 freq)))))
  1241. (let ((start (seconds->samples beg))
  1242. (stop (seconds->samples (+ beg dur)))
  1243. (r (expt .001 (/ n))))
  1244. (let ((carrier (make-rcos freq (* .5 r)))
  1245. (clang (make-rkoddssb (* freq 2) (/ 1.618 2) r))
  1246. (ampf (make-env '(0 0 1 1 2 .5 4 .25 10 0) :scaler amp :duration dur))
  1247. (clangf (make-env '(0 0 .1 1 .2 .1 .3 0) :scaler (* amp .5) :duration .1))
  1248. (rf (make-env '(0 1 1 0) :scaler (* 0.5 r) :duration dur))
  1249. (crf (make-env '(0 1 1 0) :scaler r :duration .1)))
  1250. (let ((set-clang-scaler (procedure-setter (clang 'mus-scaler))))
  1251. (do ((i start (+ i 1)))
  1252. ((= i stop))
  1253. (set-clang-scaler clang (env crf)) ;(set! (mus-scaler clang) (env crf))
  1254. (set! (carrier 'r) (env rf))
  1255. (outa i (+ (* (env clangf)
  1256. (rkoddssb clang 0.0))
  1257. (* (env ampf)
  1258. (rcos carrier 0.0))))))))))
  1259. #|
  1260. (with-sound (:clipped #f :statistics #t :play #t)
  1261. (stringy 0 1 1000 .5))
  1262. (with-sound (:clipped #f :statistics #t :play #t)
  1263. (do ((i 0 (+ i 1)))
  1264. ((= i 10))
  1265. (stringy (* i .3) .3 (+ 200 (* 100 i)) .5)))
  1266. |#
  1267. (define rssb-methods
  1268. (list
  1269. (cons 'mus-scaler
  1270. (dilambda
  1271. (lambda (g) (g 'r))
  1272. (lambda (g val) (set! (g 'r) (generator-clamp-r val)))))))
  1273. (defgenerator (rssb
  1274. :make-wrapper (lambda (g)
  1275. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1276. (set! (g 'r) (generator-clamp-r (g 'r)))
  1277. g)
  1278. :methods rssb-methods)
  1279. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm interp)
  1280. (define rssb
  1281. (let ((documentation "(make-rssb frequency (ratio 1.0) (r 0.5)) creates an rssb generator. (rssb gen (fm 0.0))
  1282. returns many cosines from frequency spaced by frequency * ratio with amplitude r^k."))
  1283. (lambda* (gen (fm 0.0))
  1284. (let-set! gen 'fm fm)
  1285. (with-let gen
  1286. (let* ((angle1 angle)
  1287. (angle2 (* angle1 ratio)))
  1288. (let ((carsin (sin angle1))
  1289. (canrcos (cos angle1))
  1290. (den (+ 1.0 (* r r) (* -2.0 r (cos angle2))))
  1291. (sumsin (* r (sin angle2)))
  1292. (sumcos (- 1.0 (* r (cos angle2)))))
  1293. (set! angle (+ angle1 fm frequency))
  1294. (/ (- (* carsin sumsin)
  1295. (* canrcos sumcos))
  1296. (* 2 den))))))))
  1297. (define rssb-interp
  1298. (let ((documentation "(make-rssb frequency (ratio 1.0) (r 0.5)) creates an rssb generator for
  1299. rssb-interp. (rssb-interp gen fm interp) returns many cosines from frequency spaced by frequency * ratio
  1300. with amplitude r^k. The 'interp' argument determines whether the sidebands are above (1.0) or below (-1.0) frequency."))
  1301. (lambda (gen fm interp)
  1302. (let-set! gen 'fm fm)
  1303. (let-set! gen 'interp interp)
  1304. (with-let gen
  1305. (let* ((angle1 angle)
  1306. (angle2 (* angle1 ratio)))
  1307. (let ((carsin (sin angle1))
  1308. (canrcos (cos angle1))
  1309. (den (+ 1.0 (* r r) (* -2.0 r (cos angle2))))
  1310. (sumsin (* r (sin angle2)))
  1311. (sumcos (- 1.0 (* r (cos angle2)))))
  1312. (set! angle (+ angle1 fm frequency))
  1313. (/ (- (* carsin sumsin)
  1314. (* interp canrcos sumcos))
  1315. (* 2 den))))))))
  1316. (definstrument (bump beg dur freq amp f0 f1 f2)
  1317. (let ((start (seconds->samples beg))
  1318. (stop (seconds->samples (+ beg dur)))
  1319. (res0 (round (/ f0 freq)))
  1320. (res1 (round (/ f1 freq)))
  1321. (res2 (round (/ f2 freq))))
  1322. (let ((gen1 (make-rssb (* res0 freq) (/ res0) .4))
  1323. (gen2 (make-rssb (* res1 freq) (/ res1) .5))
  1324. (gen3 (make-rssb (* res2 freq) (/ res2) .6))
  1325. (ampf (make-env '(0 0 .1 1 2 .5 3 .1 4 1 5 .4 6 .1 80 0) :scaler amp :base 32 :duration dur)) ; or 50 at end
  1326. ;; or '(0 0 .1 1 2 .5 3 .1 4 .3 5 .1 40 0)
  1327. (pervib (make-triangle-wave 5.0 (hz->radians 3.0)))
  1328. (ranvib (make-rand-interp 12.0 (hz->radians 2.0))))
  1329. (do ((i start (+ i 1)))
  1330. ((= i stop))
  1331. (let ((vib (+ (rand-interp ranvib)
  1332. (triangle-wave pervib))))
  1333. (outa i (* (env ampf)
  1334. (+ (* .85 (rssb-interp gen1 (* res0 vib) -1))
  1335. (* .1 (rssb-interp gen2 (* res1 vib) 0))
  1336. (* .05 (rssb-interp gen3 (* res2 vib) 1))))))))))
  1337. #|
  1338. (with-sound (:play #t)
  1339. (do ((k 0 (+ k 1)))
  1340. ((= k 10))
  1341. (bump (* 0.4 k) 1 (* 16.3 (expt 2.0 (+ 3 (/ k 12)))) .5 520 1190 2390))
  1342. (do ((k 0 (+ k 1)))
  1343. ((= k 10))
  1344. (let* ((freq (* 16.3 (expt 2.0 (+ 3 (/ k 12)))))
  1345. (scl (sqrt (/ freq 120))))
  1346. (bump (+ 4 (* 0.4 k)) 1 freq .5 (* scl 520) (* scl 1190) (* scl 2390)))))
  1347. (with-sound (:clipped #f :statistics #t :play #t)
  1348. (do ((k 0 (+ k 1)))
  1349. ((= k 10))
  1350. (let* ((freq (* 16.3 (expt 2.0 (+ 3 (/ k 12))))) ; if oct=5 (and env end at 100), sort of hammered string effect
  1351. (f0 520) ; "uh"
  1352. (f1 1190)
  1353. (f2 2390)
  1354. ;; "ah" is good: 730 1090 2440
  1355. ;; it might be smoother to scale the formant freqs by (sqrt (/ freq 120)) or even (expt (/ freq 120) 0.3)
  1356. (res0 (round (/ f0 freq)))
  1357. (res1 (round (/ f1 freq)))
  1358. (res2 (round (/ f2 freq)))
  1359. (gen1 (make-rssb (* res0 freq) (/ res0) .4))
  1360. (gen2 (make-rssb (* res1 freq) (/ res1) .5))
  1361. (gen3 (make-rssb (* res2 freq) (/ res2) .6))
  1362. (ampf (make-env '(0 0 .1 1 2 .5 3 .1 4 1 5 .4 6 .1 80 0) :scaler .5 :base 32 :length 60000)) ; or 50 at end
  1363. ;; or '(0 0 .1 1 2 .5 3 .1 4 .3 5 .1 40 0)
  1364. (pervib (make-triangle-wave 5.0 (hz->radians 3.0)))
  1365. (ranvib (make-rand-interp 12.0 (hz->radians 2.0))))
  1366. (do ((i 0 (+ i 1)))
  1367. ((= i 60000))
  1368. (let ((vib (+ (rand-interp ranvib)
  1369. (triangle-wave pervib))))
  1370. (outa (+ i (* k 30000)) (* (env ampf)
  1371. (+ (* .85 (rssb-interp gen1 (* res0 vib) -1))
  1372. (* .1 (rssb-interp gen2 (* res1 vib) 0))
  1373. (* .05 (rssb-interp gen3 (* res2 vib) 1))))))))))
  1374. (with-sound (:clipped #f :statistics #t :play #t)
  1375. (do ((k 0 (+ k 1)))
  1376. ((= k 10))
  1377. (let* ((freq (* 16.3 (expt 2.0 (+ 3 (/ k 12))))) ; froggy if oct=1 or 2 and "ah" (env end at 10 = cycling) ("er" is good too at oct=2)
  1378. (scl (sqrt (/ freq 120)))
  1379. (f0 (* scl 520)) ; "uh"
  1380. (f1 (* scl 1190))
  1381. (f2 (* scl 2390))
  1382. ;; "ah" is good: 730 1090 2440
  1383. (res0 (floor (/ f0 freq)))
  1384. (res1 (floor (/ f1 freq)))
  1385. (res2 (floor (/ f2 freq)))
  1386. (gen1 (make-rk!ssb (* res0 freq) (/ res0) 2.4))
  1387. (gen2 (make-rssb (* res1 freq) (/ res1) .5))
  1388. (gen3 (make-rssb (* res2 freq) (/ res2) .6))
  1389. (ampf (make-env '(0 0 .1 1 2 .5 3 .1 4 .3 5 .4 6 .1 40 0) :scaler .5 :base 32 :length 60000)) ; or 50 at end
  1390. ;; or '(0 0 .1 1 2 .5 3 .1 4 .3 5 .1 40 0)
  1391. (pervib (make-triangle-wave 5.0 (hz->radians 3.0)))
  1392. (ranvib (make-rand-interp 12.0 (hz->radians 2.0))))
  1393. (do ((i 0 (+ i 1)))
  1394. ((= i 60000))
  1395. (let ((vib (+ (rand-interp ranvib)
  1396. (triangle-wave pervib))))
  1397. (outa (+ i (* k 30000)) (* (env ampf)
  1398. (+ (* .85 (rk!ssb gen1 (* res0 vib)))
  1399. (* .1 (rssb-interp gen2 (* res1 vib) 0))
  1400. (* .05 (rssb-interp gen3 (* res2 vib) 1))))))))))
  1401. (with-sound (:clipped #f :statistics #t :play #t)
  1402. (do ((k 0 (+ k 1)))
  1403. ((= k 10))
  1404. (let* ((freq (* 16.3 (expt 2.0 (+ 3 (/ k 12)))))
  1405. (scl (sqrt (/ freq 120)))
  1406. (f0 (* scl 490)) ; "uh"
  1407. (f1 (* scl 1350))
  1408. (f2 (* scl 2440))
  1409. ;; "ah" is good: 730 1090 2440
  1410. (res0 (floor (/ f0 freq)))
  1411. (res1 (floor (/ f1 freq)))
  1412. (res2 (floor (/ f2 freq)))
  1413. (gen1 (make-rk!ssb (* res0 freq) (/ res0) 2))
  1414. (gen2 (make-rk!ssb (* res1 freq) (/ res1) 3))
  1415. (gen3 (make-rk!ssb (* res2 freq) (/ res2) 3))
  1416. (ampf (make-env '(0 0 .1 1 2 .5 3 .1 4 .3 5 .4 6 .1 40 0) :scaler .5 :base 32 :length 30000))
  1417. (pervib (make-triangle-wave 5.0 (hz->radians 3.0)))
  1418. (ranvib (make-rand-interp 12.0 (hz->radians 2.0))))
  1419. (do ((i 0 (+ i 1)))
  1420. ((= i 30000))
  1421. (let ((vib (+ (rand-interp ranvib)
  1422. (triangle-wave pervib))))
  1423. (outa (+ i (* k 30000)) (* (env ampf)
  1424. (+ (* .85 (rk!ssb gen1 (* res0 vib)))
  1425. (* .1 (rk!ssb gen2 (* res1 vib)))
  1426. (* .05 (rk!ssb gen3 (* res2 vib)))))))))))
  1427. (with-sound (:clipped #f :statistics #t :play #t)
  1428. (let ((gen (make-rssb 2000.0 (/ 103.0 2000) 0.5)))
  1429. (do ((i 0 (+ i 1)))
  1430. ((= i 10000))
  1431. (outa i (rssb gen)))))
  1432. |#
  1433. ;;; --------------------------------------------------------------------------------
  1434. ;;;
  1435. ;;; rxysin
  1436. ;;;
  1437. ;;; similar to rssb: (JO first)
  1438. (define rxysin-methods
  1439. (list
  1440. (cons 'mus-scaler
  1441. (dilambda
  1442. (lambda (g) (g 'r))
  1443. (lambda (g val)
  1444. (set! (g 'r) (generator-clamp-r val))
  1445. (set! (g 'r2) (* -2.0 (g 'r)))
  1446. (set! (g 'rr) (+ 1.0 (* (g 'r) (g 'r)))))))))
  1447. (defgenerator (rxysin
  1448. :make-wrapper (lambda (g)
  1449. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1450. (set! (g 'r) (generator-clamp-r (g 'r)))
  1451. (set! (g 'r2) (* -2.0 (g 'r)))
  1452. (set! (g 'rr) (+ 1.0 (* (g 'r) (g 'r))))
  1453. g)
  1454. :methods rxysin-methods)
  1455. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm rr r2)
  1456. (define rxysin
  1457. (let ((documentation "(make-rxysin frequency (ratio 1.0) (r 0.5)) creates an rxysin generator (similar to rssb). (rxysin gen (fm 0.0))
  1458. returns many sines from frequency spaced by frequency * ratio with amplitude r^k."))
  1459. (lambda* (gen (fm 0.0))
  1460. (let-set! gen 'fm fm)
  1461. (with-let gen
  1462. (let* ((x angle)
  1463. (y (* x ratio)))
  1464. (set! angle (+ angle fm frequency))
  1465. (/ (- (sin x)
  1466. (* r (sin (- x y))))
  1467. (+ rr (* r2 (cos y)))))))))
  1468. #|
  1469. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  1470. (let ((gen (make-rxysin 1000 0.1 0.5)))
  1471. (do ((i 0 (+ i 1)))
  1472. ((= i 10000))
  1473. (outa i (rxysin gen)))))
  1474. |#
  1475. (define rxycos-methods
  1476. (list
  1477. (cons 'mus-scaler
  1478. (dilambda
  1479. (lambda (g) (g 'r))
  1480. (lambda (g val)
  1481. (set! (g 'r) (generator-clamp-r val))
  1482. (set! (g 'r2) (* -2.0 (g 'r)))
  1483. (set! (g 'rr) (+ 1.0 (* (g 'r) (g 'r))))
  1484. (set! (g 'norm) (- 1.0 (abs (g 'r)))))))))
  1485. (defgenerator (rxycos
  1486. :make-wrapper (lambda (g)
  1487. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1488. (set! (g 'r) (generator-clamp-r (g 'r)))
  1489. (set! (g 'r2) (* -2.0 (g 'r)))
  1490. (set! (g 'rr) (+ 1.0 (* (g 'r) (g 'r))))
  1491. (set! (g 'norm) (- 1.0 (abs (g 'r)))) ; abs for negative r
  1492. g)
  1493. :methods rxycos-methods)
  1494. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm norm rr r2)
  1495. (define rxycos
  1496. (let ((documentation "(make-rxycos frequency (ratio 1.0) (r 0.5)) creates an rxycos generator. (rxycos gen (fm 0.0))
  1497. returns many cosines from frequency spaced by frequency * ratio with amplitude r^k."))
  1498. (lambda* (gen (fm 0.0))
  1499. (let-set! gen 'fm fm)
  1500. (with-let gen
  1501. (let* ((x angle)
  1502. (y (* x ratio)))
  1503. (set! angle (+ angle fm frequency))
  1504. (* (/ (- (cos x)
  1505. (* r (cos (- x y))))
  1506. (+ rr (* r2 (cos y))))
  1507. norm))))))
  1508. #|
  1509. (with-sound (:clipped #f :statistics #t)
  1510. (let ((gen (make-rxycos 1000 0.1 0.5)))
  1511. (do ((i 0 (+ i 1)))
  1512. ((= i 10000))
  1513. (outa i (rxycos gen)))))
  1514. |#
  1515. (define* (clamp-rxycos-r gen (fm 0.0))
  1516. ;; in this case we need to track ratio, as well as r, since the
  1517. ;; highest frequency goes as x+ky (y=ratio*x); we want the value of k when
  1518. ;; we reach srate/3, then solve for the corresponding r.
  1519. (let-set! gen 'fm fm)
  1520. (with-let gen
  1521. (let ((maxr (expt cutoff (/ (floor (- (/ two-pi (* 3 ratio (+ fm frequency))) (/ ratio)))))))
  1522. (if (>= r 0.0)
  1523. (min r maxr)
  1524. (max r (- maxr))))))
  1525. (define safe-rxycos-methods
  1526. (list
  1527. (cons 'mus-scaler
  1528. (dilambda
  1529. (lambda (g) (g 'r))
  1530. (lambda (g val)
  1531. (set! (g 'r) val)
  1532. (set! (g 'r) (clamp-rxycos-r g 0.0)))))
  1533. (cons 'mus-frequency
  1534. (dilambda
  1535. (lambda (g) (radians->hz (g 'frequency)))
  1536. (lambda (g val)
  1537. (set! (g 'frequency) (hz->radians val))
  1538. (set! (g 'r) (clamp-rxycos-r g 0.0))
  1539. val)))
  1540. (cons 'mus-offset ; ratio accessor in defgenerator
  1541. (dilambda
  1542. (lambda (g) (g 'ratio))
  1543. (lambda (g val)
  1544. (set! (g 'ratio) val)
  1545. (set! (g 'r) (clamp-rxycos-r g 0.0))
  1546. val)))))
  1547. (defgenerator (safe-rxycos
  1548. :make-wrapper (lambda (g)
  1549. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1550. (set! (g 'r) (clamp-rxycos-r g 0.0))
  1551. g)
  1552. :methods safe-rxycos-methods)
  1553. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) (cutoff 0.001) fm)
  1554. (define safe-rxycos
  1555. (let ((documentation "(make-safe-rxycos frequency (ratio 1.0) (r 0.5)) creates a safe-rxycos generator. (safe-rxycos gen (fm 0.0))
  1556. returns many cosines from frequency spaced by frequency * ratio with amplitude r^k where 'r' is restricted to a safe value."))
  1557. (lambda* (gen (fm 0.0))
  1558. (let-set! gen 'fm fm)
  1559. (with-let gen
  1560. (let ((x angle)
  1561. (y (* angle ratio)))
  1562. (set! angle (+ angle fm frequency))
  1563. (if (not (= fm 0.0)) ;(set! r (clamp-rxycos-r (curlet) fm))
  1564. (let ((maxr (expt cutoff (/ (floor (- (/ two-pi (* 3 ratio (+ fm frequency))) (/ ratio)))))))
  1565. (set! r (if (>= r 0.0) (min r maxr) (max r (- maxr))))))
  1566. (* (/ (- (cos x)
  1567. (* r (cos (- x y))))
  1568. (+ 1.0
  1569. (* -2.0 r (cos y))
  1570. (* r r)))
  1571. (- 1.0 (abs r)))))))) ; norm, abs for negative r
  1572. #|
  1573. (with-sound (:clipped #f :statistics #t)
  1574. (let ((gen (make-safe-rxycos 1000 0.1 0.99)))
  1575. (do ((i 0 (+ i 1)))
  1576. ((= i 10000))
  1577. (outa i (safe-rxycos gen)))))
  1578. |#
  1579. ;;; --------------------------------------------------------------------------------
  1580. ;;; inf cosines scaled by e^-r (special case of rcos): ercos, erssb
  1581. ;;; sndclm.html G&R second col last row (with normalization)
  1582. (define ercos-methods
  1583. (list
  1584. (cons 'mus-frequency
  1585. (dilambda
  1586. (lambda (g) (mus-frequency (g 'osc)))
  1587. (lambda (g val) (set! (mus-frequency (g 'osc)) val))))
  1588. (cons 'mus-phase
  1589. (dilambda
  1590. (lambda (g) (mus-phase (g 'osc)))
  1591. (lambda (g val) (set! (mus-phase (g 'osc)) val))))))
  1592. (defgenerator (ercos
  1593. :make-wrapper (lambda (g)
  1594. (if (<= (g 'r) 0.0) (set! (g 'r) 0.00001))
  1595. (set! (g 'cosh-t) (cosh (g 'r)))
  1596. (set! (g 'osc) (make-polywave (g 'frequency) (list 0 (g 'cosh-t) 1 -1.0) mus-chebyshev-second-kind))
  1597. (let ((exp-t (exp (- (g 'r)))))
  1598. (set! (g 'offset) (/ (- 1.0 exp-t) (* 2.0 exp-t)))
  1599. (set! (g 'scaler) (* (sinh (g 'r)) (g 'offset))))
  1600. g)
  1601. :methods ercos-methods)
  1602. (frequency *clm-default-frequency*) (r 1.0) fm
  1603. (osc #f) scaler offset cosh-t)
  1604. (define ercos
  1605. (let ((documentation "(make-ercos frequency (r 0.5)) creates an ercos generator (a special case of rcos). (ercos gen (fm 0.0))
  1606. returns many cosines from frequency with amplitude e^(-kr)."))
  1607. (lambda* (gen (fm 0.0))
  1608. (let-set! gen 'fm fm)
  1609. (with-let gen
  1610. (- (/ scaler (polywave osc fm)) offset)))))
  1611. #|
  1612. (with-let gen
  1613. (- (/ scaler
  1614. (- cosh-t (oscil osc fm)))
  1615. offset)))
  1616. (with-sound (:clipped #f :statistics #t :play #t)
  1617. (let ((gen (make-ercos 100 :r 1.0)))
  1618. (do ((i 0 (+ i 1)))
  1619. ((= i 10000))
  1620. (outa i (ercos gen)))))
  1621. |#
  1622. (definstrument (ercoser beg dur freq amp r)
  1623. (let ((start (seconds->samples beg))
  1624. (stop (seconds->samples (+ beg dur)))
  1625. (gen (make-ercos freq :r r))
  1626. (t-env (make-env '(0 .1 1 2) :duration dur)))
  1627. (with-let
  1628. (varlet gen
  1629. (cons 'start start) (cons 'stop stop) (cons 'amp amp) (cons 't-env t-env) (cons 'gen gen))
  1630. (do ((i start (+ i 1)))
  1631. ((= i stop))
  1632. (set! r (env t-env))
  1633. (set! cosh-t (cosh r))
  1634. (set! ((mus-data osc) 0) cosh-t)
  1635. (let ((exp-t (exp (- r))))
  1636. (set! offset (/ (- 1.0 exp-t) (* 2.0 exp-t)))
  1637. (set! scaler (* (sinh r) offset)))
  1638. (outa i (* amp (ercos gen)))))))
  1639. #|
  1640. ;;; same, but slightly slower
  1641. (definstrument (ercoser beg dur freq amp r)
  1642. (let ((start (seconds->samples beg))
  1643. (stop (seconds->samples (+ beg dur)))
  1644. (gen (make-ercos freq :r r))
  1645. (t-env (make-env '(0 .1 1 2) :duration dur)))
  1646. (do ((i start (+ i 1)))
  1647. ((= i stop))
  1648. (let ((r (env t-env)))
  1649. (set! (gen 'r) r)
  1650. (set! (gen 'cosh-t) (cosh r))
  1651. (set! ((mus-data (gen 'osc)) 0) (gen 'cosh-t))
  1652. (let ((exp-t (exp (- r))))
  1653. (set! (gen 'offset) (/ (- 1.0 exp-t) (* 2.0 exp-t)))
  1654. (set! (gen 'scaler) (* (sinh r) (gen 'offset))))
  1655. (outa i (* amp (ercos gen)))))))
  1656. |#
  1657. #|
  1658. ;; change "t" during note -- smoothly changing sum-of-cosines spectra (damped "lute-stop" effect)
  1659. (with-sound (:play #t)
  1660. (ercoser 0 1 100 .5 0.1))
  1661. |#
  1662. (defgenerator (erssb
  1663. :make-wrapper (lambda (g)
  1664. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1665. g))
  1666. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm)
  1667. (define erssb
  1668. (let ((documentation "(make-erssb frequency (ratio 1.0) (r 0.5)) creates an erssb generator (a special case of rssb). (erssb gen (fm 0.0))
  1669. returns many sinusoids from frequency spaced by frequency * ratio with amplitude e^(-kr)."))
  1670. (lambda* (gen (fm 0.0))
  1671. (let-set! gen 'fm fm)
  1672. (with-let gen
  1673. (let* ((cx angle)
  1674. (mx (* cx ratio)))
  1675. (let ((cxx (- cx mx))
  1676. (ccmx (- (cosh r) (cos mx))))
  1677. (set! angle (+ angle fm frequency))
  1678. (if (< (abs ccmx) nearly-zero)
  1679. 1.0
  1680. (/ (- (* (cos cxx)
  1681. (- (/ (sinh r) ccmx)
  1682. 1.0))
  1683. (* (sin cxx)
  1684. (/ (sin mx) ccmx)))
  1685. (* 2.0 (- (/ 1.0 (- 1.0 (exp (- r)))) 1.0)))))))))) ; normalization
  1686. #|
  1687. (with-sound (:clipped #f :statistics #t :play #t)
  1688. (let ((gen (make-erssb 1000.0 0.1 1.0)))
  1689. (do ((i 0 (+ i 1)))
  1690. ((= i 20000))
  1691. (outa i (erssb gen)))))
  1692. |#
  1693. #|
  1694. ;;; --------------------------------------------------------------------------------
  1695. ;;; removed 8-May-08 -- not useful or different from (for example) rk!cos
  1696. ;;; inf sinusoids scaled by r^2: r2cos, r2sin, r2ssb
  1697. ;;; Jolley second col second row (first row is cos tweak of this)
  1698. (defgenerator (r2sin
  1699. :make-wrapper (lambda (g)
  1700. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1701. (if (>= (* (g 'r) (g 'r)) 1.0)
  1702. (set! (g 'r) 0.9999999))
  1703. g))
  1704. (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm)
  1705. (define r2sin
  1706. (let ((documentation "(make-r2sin frequency (r 0.5)) creates an r2sin generator. (r2sin gen (fm 0.0))
  1707. returns many even-numbered sines from frequency with amplitude r^(2k)/(2k)!."))
  1708. (lambda* (gen (fm 0.0))
  1709. (let-set! gen 'fm fm)
  1710. (with-let gen
  1711. (let* ((x angle))
  1712. (set! angle (+ angle fm frequency))
  1713. (* (sinh (* r (cos x)))
  1714. (sin (* r (sin x)))))))))
  1715. ;;; even harmonics, but we can't push the upper partials past the (2k)! range, so not very flexible
  1716. (with-sound (:clipped #f :statistics #t :play #t)
  1717. (let ((gen (make-r2sin 100.0 :r 0.5)))
  1718. (do ((i 0 (+ i 1)))
  1719. ((= i 20000))
  1720. (outa i (r2sin gen)))))
  1721. (defgenerator (r2cos
  1722. :make-wrapper (lambda (g)
  1723. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1724. (if (>= (* (g 'r) (g 'r)) 1.0)
  1725. (set! (g 'r) 0.9999999))
  1726. g))
  1727. (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm)
  1728. (define r2cos
  1729. (let ((documentation "(make-r2cos frequency (r 0.5)) creates an r2cos generator. (r2cos gen (fm 0.0))
  1730. returns many even-numbered cosines from frequency with amplitude r^(2k)/(2k)!."))
  1731. (lambda* (gen (fm 0.0))
  1732. (let-set! gen 'fm fm)
  1733. (with-let gen
  1734. (let* ((x angle))
  1735. (set! angle (+ angle fm frequency))
  1736. (/ (- (* (cosh (* r (cos x)))
  1737. (cos (* r (sin x))))
  1738. 1.0) ; omit DC
  1739. (- (cosh r) 1.0))))))) ; normalize
  1740. ;;; odd harmonics, but we can't push the upper partials past the (2k)! range, so not very flexible
  1741. (with-sound (:clipped #f :statistics #t :play #t)
  1742. (let ((gen (make-r2cos 100.0 :r 0.5)))
  1743. (do ((i 0 (+ i 1)))
  1744. ((= i 20000))
  1745. (outa i (r2cos gen)))))
  1746. (defgenerator (r2ssb
  1747. :make-wrapper (lambda (g)
  1748. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1749. g))
  1750. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm)
  1751. (define r2ssb
  1752. (let ((documentation "(make-r2ssb frequency (ratio 1.0) (r 0.5)) creates an r2ssb generator. (r2ssb gen (fm 0.0))
  1753. returns many even-numbered sinusoids from frequency spaced by frequency * ratio, if that makes any sense, with amplitude r^(2k)/(2k)!."))
  1754. (lambda* (gen (fm 0.0))
  1755. (let-set! gen 'fm fm)
  1756. (with-let gen
  1757. (let* ((cx angle)
  1758. (mx (* cx ratio))
  1759. (a r)
  1760. (asinx (* a (sin mx)))
  1761. (acosx (* a (cos mx))))
  1762. (set! angle (+ angle fm frequency))
  1763. (/ (- (* (cos cx)
  1764. (cosh acosx)
  1765. (cos asinx))
  1766. (* (sin cx)
  1767. (sinh acosx)
  1768. (sin asinx)))
  1769. (cosh a))))))) ; normalization
  1770. (with-sound (:clipped #f :statistics #t :play #t)
  1771. (let ((gen (make-r2ssb 1000.0 0.1 0.5)))
  1772. (do ((i 0 (+ i 1)))
  1773. ((= i 20000))
  1774. (outa i (r2ssb gen)))))
  1775. (with-sound (:clipped #f :statistics #t :play #t)
  1776. (let ((gen (make-r2ssb 1000.0 0.1 0.5))
  1777. (vib (make-oscil 5)))
  1778. (do ((i 0 (+ i 1)))
  1779. ((= i 20000))
  1780. (outa i (r2ssb gen (* (hz->radians 100.0) (oscil vib)))))))
  1781. |#
  1782. ;;; --------------------------------------------------------------------------------
  1783. ;;;
  1784. ;;; inf odd cosines scaled by e^-r: eoddcos
  1785. ;;; Jolley first col second row
  1786. ;;; heads toward a square wave as "r" -> 0.0 (odd harmonics, 1/k amp)
  1787. ;;; this is the cos side of rkoddssb with r=e^-a
  1788. (define eoddcos-methods
  1789. (list
  1790. (cons 'mus-frequency
  1791. (dilambda
  1792. (lambda (g) (mus-frequency (g 'osc)))
  1793. (lambda (g val) (set! (mus-frequency (g 'osc)) val))))
  1794. (cons 'mus-phase
  1795. (dilambda
  1796. (lambda (g) (mus-phase (g 'osc)))
  1797. (lambda (g val) (set! (mus-phase (g 'osc)) val))))))
  1798. (defgenerator (eoddcos
  1799. :make-wrapper (lambda (g)
  1800. (set! (g 'osc) (make-oscil (g 'frequency) (* 0.5 pi)))
  1801. g)
  1802. :methods eoddcos-methods)
  1803. (frequency *clm-default-frequency*) (r 1.0) fm
  1804. (osc #f))
  1805. (define eoddcos
  1806. (let ((documentation "(make-eoddcos frequency (r 0.5)) creates an eoddcos generator. (eoddcos gen (fm 0.0))
  1807. returns many cosines from spaced by frequency with amplitude e^(-r)."))
  1808. (lambda* (gen (fm 0.0))
  1809. (let-set! gen 'fm fm)
  1810. (with-let gen
  1811. (let ((sinha (sinh r)))
  1812. (if (zero? sinha)
  1813. 0.0 ; just a guess
  1814. (/ (atan (oscil osc fm) sinha)
  1815. (atan 1.0 sinha)))))))) ; normalization
  1816. #|
  1817. (with-sound (:clipped #f :statistics #t :play #t)
  1818. (let ((gen (make-eoddcos 400.0 :r 1.0)))
  1819. (do ((i 0 (+ i 1)))
  1820. ((= i 10000))
  1821. (outa i (eoddcos gen)))))
  1822. (with-sound (:clipped #f :statistics #t :play #t)
  1823. (let ((gen (make-eoddcos 400.0 :r 0.0))
  1824. (a-env (make-env '(0 0 1 1) :length 10000)))
  1825. (do ((i 0 (+ i 1)))
  1826. ((= i 10000))
  1827. (set! (gen 'r) (env a-env))
  1828. (outa i (eoddcos gen)))))
  1829. (with-sound (:clipped #f :statistics #t :play #t)
  1830. (let ((gen1 (make-eoddcos 400.0 :r 0.0))
  1831. (gen2 (make-oscil 400.0))
  1832. (a-env (make-env '(0 0 1 1) :length 10000)))
  1833. (do ((i 0 (+ i 1)))
  1834. ((= i 10000))
  1835. (set! (gen 'r1) (env a-env))
  1836. (outa i (* .5 (eoddcos gen1 (* .1 (oscil gen2))))))))
  1837. |#
  1838. #|
  1839. ;;; --------------------------------------------------------------------------------
  1840. ;;; removed 6-May-08
  1841. ;;; inf odd cosines scaled by complicated mess: koddcos
  1842. ;;; Jolley first col 5th row
  1843. (define make-koddcos make-oscil)
  1844. (define koddcos
  1845. (let ((documentation "(make-koddcos frequency) creates a koddcos generator. (koddcos gen (fm 0.0))
  1846. returns many cosines from spaced by frequency with amplitude too messy to write down, and the output looks wrong anyway."))
  1847. (lambda* (gen (fm 0.0))
  1848. (let ((arg (* 2.0 (oscil gen fm))))
  1849. (if (>= arg 0.0)
  1850. (/ (acos (- 1.0 arg)) pi)
  1851. (/ (acos (+ 1.0 arg)) (- pi)))))))
  1852. (with-sound (:clipped #f :statistics #t :play #t)
  1853. (let ((gen (make-koddcos 400.0)))
  1854. (do ((i 0 (+ i 1)))
  1855. ((= i 10000))
  1856. (outa i (* .3 (koddcos gen))))))
  1857. ;;; as printed in J, this is not usable -- 1-2sin can be 3 so acos will be complex -- looks like we're missing: x < pi
  1858. ;;; we get odd harmonics but wrong amps
  1859. |#
  1860. ;;; --------------------------------------------------------------------------------
  1861. ;;; inf cosines scaled by r^k/k: rkcos, rksin, rkssb
  1862. ;;; G&R second col 6th row, also J 536
  1863. ;;; r^k/k -- this sums to ln(1/(1-x)) if x<1 (J 118)
  1864. (define rkcos-methods
  1865. (list
  1866. (cons 'mus-frequency
  1867. (dilambda
  1868. (lambda (g) (mus-frequency (g 'osc)))
  1869. (lambda (g val) (set! (mus-frequency (g 'osc)) val))))
  1870. (cons 'mus-scaler
  1871. (dilambda
  1872. (lambda (g) (g 'r))
  1873. (lambda (g val) (set! (g 'r) (generator-clamp-r val)))))
  1874. (cons 'mus-phase
  1875. (dilambda
  1876. (lambda (g) (mus-phase (g 'osc)))
  1877. (lambda (g val) (set! (mus-phase (g 'osc)) val))))))
  1878. (defgenerator (rkcos
  1879. :make-wrapper (lambda (g)
  1880. (set! (g 'osc) (make-oscil (g 'frequency) (* 0.5 pi)))
  1881. (set! (g 'r) (generator-clamp-r (g 'r))) ; or clip at 0.0?
  1882. (set! (g 'norm) (log (- 1.0 (abs (g 'r)))))
  1883. g)
  1884. :methods rkcos-methods)
  1885. (frequency *clm-default-frequency*) (r 0.5) norm fm
  1886. (osc #f))
  1887. ;;; not very flexible, and very similar to others in the r^k mold
  1888. (define rkcos
  1889. (let ((documentation "(make-rkcos frequency (r 0.5)) creates an rkcos generator. (rkcos gen (fm 0.0))
  1890. returns many cosines from spaced by frequency with amplitude (r^k)/k."))
  1891. (lambda* (gen (fm 0.0))
  1892. (let-set! gen 'fm fm)
  1893. (with-let gen
  1894. (let ((cs (oscil osc fm)))
  1895. (/ (* 0.5 (log (+ 1.0 (* -2.0 r cs) (* r r))))
  1896. norm))))))
  1897. #|
  1898. (with-sound (:clipped #f :statistics #t :play #t)
  1899. (let ((gen (make-rkcos 440.0 :r 0.5)))
  1900. (do ((i 0 (+ i 1)))
  1901. ((= i 10000))
  1902. (outa i (rkcos gen)))))
  1903. |#
  1904. (define rksin-methods
  1905. (list
  1906. (cons 'mus-scaler
  1907. (dilambda
  1908. (lambda (g) (g 'r))
  1909. (lambda (g val) (set! (g 'r) (generator-clamp-r val)))))))
  1910. (defgenerator (rksin
  1911. :make-wrapper (lambda (g)
  1912. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1913. g)
  1914. :methods rksin-methods)
  1915. (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm)
  1916. ;;; normalization based on 0 of derivative of atan arg (for max) at cos x = r,
  1917. ;;; so we get a maxamp here of (atan (/ (* r (sin (acos r))) (- 1.0 (* r r))))
  1918. (define rksin
  1919. (let ((documentation "(make-rksin frequency (r 0.5)) creates an rksin generator. (rksin gen (fm 0.0))
  1920. returns many sines from spaced by frequency with amplitude (r^k)/k."))
  1921. (lambda* (gen (fm 0.0))
  1922. (let-set! gen 'fm fm)
  1923. (with-let gen
  1924. (let ((x angle))
  1925. (set! angle (+ angle fm frequency))
  1926. (/ (atan (* r (sin x))
  1927. (- 1.0 (* r (cos x))))
  1928. (atan (* r (sin (acos r))) ; normalization
  1929. (- 1.0 (* r r)))))))))
  1930. #|
  1931. (with-sound (:clipped #f :statistics #t :play #t)
  1932. (let ((gen (make-rksin 100.0 :r 0.5)))
  1933. (do ((i 0 (+ i 1)))
  1934. ((= i 10000))
  1935. (outa i (rksin gen)))))
  1936. |#
  1937. (define rkssb-methods
  1938. (list
  1939. (cons 'mus-scaler
  1940. (dilambda
  1941. (lambda (g) (g 'r))
  1942. (lambda (g val) (set! (g 'r) (generator-clamp-r val)))))))
  1943. (defgenerator (rkssb
  1944. :make-wrapper (lambda (g)
  1945. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1946. g)
  1947. :methods rkssb-methods)
  1948. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm)
  1949. (define rkssb
  1950. (let ((documentation "(make-rkssb frequency (ratio 1.0) (r 0.5)) creates an rkssb generator. (rkssb gen (fm 0.0))
  1951. returns many sinusoids from frequency from spaced by frequency * ratio with amplitude (r^k)/k."))
  1952. (lambda* (gen (fm 0.0))
  1953. (let-set! gen 'fm fm)
  1954. (with-let gen
  1955. (let* ((cx angle)
  1956. (mx (* cx ratio)))
  1957. (let ((cxx (* (- 1.0 ratio) cx))
  1958. (rcosmx (* r (cos mx))))
  1959. (set! angle (+ angle fm frequency))
  1960. (/ (- (* (cos cxx)
  1961. -0.5 (log (+ 1.0 (* -2.0 rcosmx) (* r r))))
  1962. (* (sin cxx)
  1963. (atan (* r (sin mx))
  1964. (- 1.0 rcosmx))))
  1965. (- (log (- 1.0 (abs r))))))))))) ; normalization
  1966. #|
  1967. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  1968. (let ((gen (make-rkssb 1000.0 0.5 :r 0.75)) ; (make-rkssb 300.0 3.0 :r 0.5)
  1969. (ampf (make-env '(0 0 1 1 2 1 3 0) :length 20000)))
  1970. (do ((i 0 (+ i 1)))
  1971. ((= i 20000))
  1972. (outa i (* (env ampf)
  1973. (rkssb gen))))))
  1974. |#
  1975. ;;; --------------------------------------------------------------------------------
  1976. ;;; inf cosines scaled by r^k/k!: rk!cos, rk!ssb
  1977. ;;; G&R second col third from last (simplified)
  1978. (define rk!cos-methods
  1979. (list
  1980. (cons 'mus-phase
  1981. (dilambda
  1982. (lambda (g) (g 'angle))
  1983. (lambda (g val) (set! (g 'angle) val))))))
  1984. (defgenerator (rk!cos
  1985. :make-wrapper (lambda (g)
  1986. (set! (g 'frequency) (hz->radians (g 'frequency)))
  1987. (set! (g 'norm) (/ 1.0 (- (exp (abs r)) 1.0)))
  1988. g)
  1989. :methods rk!cos-methods)
  1990. (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm norm)
  1991. (define rk!cos
  1992. (let ((documentation "(make-rk!cos frequency (r 0.5)) creates an rk!cos generator. (rk!cos gen (fm 0.0))
  1993. returns many cosines spaced by frequency with amplitude (r^k)/k!."))
  1994. (lambda* (gen (fm 0.0))
  1995. (let-set! gen 'fm fm)
  1996. (with-let gen
  1997. (let ((x angle))
  1998. (set! angle (+ angle fm frequency))
  1999. (* (- (* (exp (* r (cos x)))
  2000. (cos (* r (sin x))))
  2001. 1.0) ; omit DC
  2002. norm))))))
  2003. #|
  2004. (with-sound (:clipped #f :statistics #t :play #t)
  2005. (let ((gen (make-rk!cos 440.0 :r 0.5)))
  2006. (do ((i 0 (+ i 1)))
  2007. ((= i 10000))
  2008. (outa i (* .5 (rk!cos gen))))))
  2009. |#
  2010. ;;; the k! denominator dominates, so r * ratio = formant center approximately; (n!)^(1/n)
  2011. ;;; so freq=100, r=30, the center of the spectrum is around 3kHz:
  2012. #|
  2013. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2014. (let ((gen (make-rk!cos 100.0 :r 40.0))
  2015. (r 40.0)
  2016. (incr (/ -40.0 100000)))
  2017. (do ((i 0 (+ i 1)))
  2018. ((= i 100000))
  2019. (set! (gen 'r) r)
  2020. (set! r (+ r incr))
  2021. (outa i (rk!cos gen)))))
  2022. (with-sound (:clipped #f :statistics #t :play #t)
  2023. (let ((gen (make-rk!cos 300.0 :r 10.0))
  2024. (ampf (make-env '(0 0 .1 1 .2 1 3 .5 5 .25 10 0) :scaler .5 :length 10000))
  2025. (r 10.0)
  2026. (incr (/ -10.0 10000)))
  2027. (do ((i 0 (+ i 1)))
  2028. ((= i 10000))
  2029. (set! (gen 'r) r)
  2030. (set! r (+ r incr))
  2031. (outa i (* (env ampf) (rk!cos gen))))))
  2032. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2033. (let ((gen (make-rk!cos 1000.0 :r 8.0))
  2034. (frqf (make-env '(0 1 1 0) :base 32 :scaler (hz->radians 1000) :length 10000)))
  2035. (do ((i 0 (+ i 1)))
  2036. ((= i 10000))
  2037. (outa i (rk!cos gen (env frqf))))))
  2038. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2039. (let ((gen (make-rk!cos 3000.0 :r 1.0)) (ampf (make-env '(0 0 1 1 10 1 11 0) :length 10000))
  2040. (frqf (make-env '(0 1 1 0 2 .25 3 0) :base 3 :scaler (hz->radians 2000) :length 10000)))
  2041. (do ((i 0 (+ i 1)))
  2042. ((= i 10000))
  2043. (outa i (* (env ampf) (rk!cos gen (env frqf)))))))
  2044. (with-sound (:play #t :scaled-to .5)
  2045. (do ((k 0 (+ k 1)))
  2046. ((= k 6))
  2047. (let ((gen (make-rk!cos 3000.0 :r 0.6)) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 3000))
  2048. (frqf (make-env '(0 0 1 1) :base .1 :scaler (hz->radians 2000) :length 3000))) ; '(0 .5 1 1 2 0 3 0) '(0 1 1 0 2 1 6 -1)
  2049. (do ((i 0 (+ i 1)))
  2050. ((= i 3000))
  2051. (outa (+ i (* k 4000))
  2052. (* (env ampf)
  2053. (rk!cos gen (env frqf))))))))
  2054. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2055. (do ((k 0 (+ k 1)))
  2056. ((= k 6))
  2057. (let ((gen (make-rk!cos 1000.0 :r 1.0)) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 3000))
  2058. (frqf (make-env '(0 .9 1 1 2 -1) :base .1 :scaler (hz->radians 500) :length 3000)))
  2059. (do ((i 0 (+ i 1)))
  2060. ((= i 3000))
  2061. (outa (+ i (* k 10000)) (* (env ampf) (rk!cos gen (env frqf))))))))
  2062. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2063. (do ((k 0 (+ k 1)))
  2064. ((= k 6))
  2065. (let ((gen (make-rk!cos 500.0 :r 1.5)) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 3000))
  2066. (frqf (make-env '(0 1 1 1 2 -1) :base .5 :scaler (hz->radians 400) :length 3000)))
  2067. (do ((i 0 (+ i 1)))
  2068. ((= i 3000))
  2069. (outa (+ i (* k 10000)) (* (env ampf) (rk!cos gen (env frqf))))))))
  2070. |#
  2071. (defgenerator (rk!ssb
  2072. :make-wrapper (lambda (g)
  2073. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2074. g))
  2075. (frequency *clm-default-frequency*) (ratio 1.0) (r 1.0) (angle 0.0) fm)
  2076. (define rk!ssb
  2077. (let ((documentation "(make-rk!ssb frequency (ratio 1.0) (r 0.5)) creates an rk!ssb generator. (rk!ssb gen (fm 0.0))
  2078. returns many sinusoids from frequency spaced by frequency * ratio with amplitude (r^k)/k!."))
  2079. (lambda* (gen (fm 0.0))
  2080. (let-set! gen 'fm fm)
  2081. (with-let gen
  2082. (let* ((cx angle)
  2083. (mx (* cx ratio)))
  2084. (let ((ercosmx (exp (* r (cos mx))))
  2085. (rsinmx (* r (sin mx))))
  2086. (set! angle (+ angle fm frequency))
  2087. (/ (- (* (cos cx) ercosmx (cos rsinmx))
  2088. (* (sin cx) ercosmx (sin rsinmx)))
  2089. (exp (abs r))))))))) ; normalization (keeping DC term here to get "carrier")
  2090. #|
  2091. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2092. (let ((gen (make-rk!ssb 1000.0 0.1 :r 0.5)) ; (make-rk!ssb 200.0 3.0 :r 2)
  2093. (ampf (make-env '(0 0 1 1 2 1 3 0) :length 20000)))
  2094. (do ((i 0 (+ i 1)))
  2095. ((= i 20000))
  2096. (outa i (* (env ampf) (rk!ssb gen))))))
  2097. ; (make-rk!ssb 0.0 120.0 :r 15) gives a widely separated wave-train of pulses
  2098. ; so (make-rk!ssb 0.0 40.0 :r 70) is insecty (:r 100)
  2099. ; (make-rk!ssb 0.0 10.0 :r 100) -- some bird? (make-rk!ssb 0.0 15.0 :r 300)
  2100. ; (make-rk!ssb 1000.0 25.0 :r 10) (make-rk!ssb 3000.0 25.0 :r 100) -- another bird (5000)
  2101. |#
  2102. (definstrument (bouncy beg dur freq amp (bounce-freq 5) (bounce-amp 20))
  2103. (let ((len (seconds->samples dur))
  2104. (start (seconds->samples beg)))
  2105. (let ((gen (make-rk!ssb (* freq 4) 1/4 :r 1.0))
  2106. (gen1 (make-oscil bounce-freq))
  2107. (bouncef (make-env '(0 1 1 0) :base 32 :scaler bounce-amp :duration 1.0))
  2108. (rf (make-env (list 0 0 1 1 (max 2.0 dur) 0) :base 32 :scaler 3 :duration dur))
  2109. (ampf (make-env (list 0 0 .01 1 .03 1 1 .15 (max 2 dur) 0.0) :base 32 :scaler amp :duration dur))
  2110. (stop (+ start len))
  2111. (fv (make-float-vector len)))
  2112. (do ((i 0 (+ i 1)))
  2113. ((= i len))
  2114. (float-vector-set! fv i (+ (env rf) (abs (* (env bouncef) (oscil gen1))))))
  2115. (do ((i start (+ i 1))
  2116. (j 0 (+ j 1)))
  2117. ((= i stop))
  2118. (set! (gen 'r) (float-vector-ref fv j))
  2119. (outa i (* (env ampf)
  2120. (rk!ssb gen)))))))
  2121. #|
  2122. (with-sound (:statistics #t :play #t :clipped #f)
  2123. (bouncy 0 2 300 .5 5 10))
  2124. (with-sound (:statistics #t :play #t :clipped #f)
  2125. (bouncy 0 2 200 .5 3 2))
  2126. |#
  2127. #|
  2128. ;;; --------------------------------------------------------------------------------
  2129. ;;; rxyk!cos
  2130. ;;; moved to clm.c 18-Apr-13)
  2131. (defgenerator (rxyk!sin
  2132. :make-wrapper (lambda (g)
  2133. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2134. g))
  2135. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm)
  2136. (define rxyk!sin
  2137. (let ((documentation "(make-rxyk!sin frequency (ratio 1.0) (r 0.5)) creates an rxyk!sin generator. (rxyk!sin gen (fm 0.0))
  2138. returns many sines from frequency spaced by frequency * ratio with amplitude r^k/k!."))
  2139. (lambda* (gen (fm 0.0))
  2140. (let-set! gen 'fm fm)
  2141. (with-let gen
  2142. (let* ((x angle)
  2143. (y (* x ratio)))
  2144. (set! angle (+ angle fm frequency))
  2145. (/ (* (exp (* r (cos y)))
  2146. (sin (+ x (* r (sin y))))) ; was cos by mistake (18-Apr-13)
  2147. (exp (abs r))))))))
  2148. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2149. (let ((gen (make-rxyk!sin 1000 0.1 0.5)))
  2150. (do ((i 0 (+ i 1)))
  2151. ((= i 10000))
  2152. (outa i (rxyk!sin gen)))))
  2153. (defgenerator (rxyk!cos
  2154. :make-wrapper (lambda (g)
  2155. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2156. (set! (g 'ar) (/ 1.0 (exp (abs (g 'r)))))
  2157. g))
  2158. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm ar)
  2159. (define rxyk!cos
  2160. (let ((documentation "(make-rxyk!cos frequency (ratio 1.0) (r 0.5)) creates an rxyk!cos generator. (rxyk!cos gen (fm 0.0))
  2161. returns many cosines from frequency spaced by frequency * ratio with amplitude r^k/k!."))
  2162. (lambda* (gen (fm 0.0))
  2163. (let-set! gen 'fm fm)
  2164. (with-let gen
  2165. (let* ((x angle)
  2166. (y (* x ratio)))
  2167. (set! angle (+ angle fm frequency))
  2168. (* (exp (* r (cos y)))
  2169. (cos (+ x (* r (sin y))))
  2170. ar))))))
  2171. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2172. (let ((gen (make-rxyk!cos 1000 0.1 0.5)))
  2173. (do ((i 0 (+ i 1)))
  2174. ((= i 10000))
  2175. (outa i (rxyk!cos gen)))))
  2176. |#
  2177. (definstrument (brassy beg dur freq amp ampf freqf gliss)
  2178. (let ((pitch-time .05)
  2179. (amp-time .1))
  2180. (let ((gen (make-rxyk!cos freq :r 0.0))
  2181. (start (seconds->samples beg))
  2182. (end (seconds->samples (+ beg dur)))
  2183. (amp-env (make-env ampf :duration dur :scaler amp))
  2184. (pitch-env (make-env freqf :scaler (/ gliss freq) :duration dur))
  2185. (slant (make-moving-average (seconds->samples pitch-time)))
  2186. (vib (make-polywave 5 (list 1 (hz->radians 4.0)) mus-chebyshev-second-kind))
  2187. (harmfrq 0.0)
  2188. (harmonic 0)
  2189. (dist 0.0))
  2190. (set! (mus-increment slant) (* (hz->radians freq) (mus-increment slant)))
  2191. (do ((i start (+ i 1)))
  2192. ((= i end))
  2193. (set! harmfrq (env pitch-env))
  2194. (set! harmonic (floor harmfrq))
  2195. (set! dist (abs (- harmfrq harmonic)))
  2196. (set! (mus-scaler gen) (* 20.0 (min amp-time dist (- 1.0 dist))))
  2197. (outa i (* (env amp-env)
  2198. (rxyk!cos gen (+ (moving-average slant harmonic)
  2199. (polywave vib)))))))))
  2200. #|
  2201. (with-sound (:statistics #t :play #t)
  2202. (brassy 0 4 50 .05 '(0 0 1 1 10 1 11 0) '(0 1 1 0) 1000))
  2203. |#
  2204. ;;; --------------------------------------------------------------------------------
  2205. ;;; inf cosines scaled by complicated mess: r2k!cos
  2206. ;;; from Askey "Ramanujan and Hypergeometric Series" in Berndt and Rankin "Ramanujan: Essays and Surveys" p283
  2207. ;;;
  2208. ;;; this gives a sum of cosines of decreasing amp where the "k" parameter determines
  2209. ;;; the "index" (in FM nomenclature) -- higher k = more cosines
  2210. (define r2k!cos-methods
  2211. (list
  2212. (cons 'mus-frequency
  2213. (dilambda
  2214. (lambda (g) (mus-frequency (g 'osc)))
  2215. (lambda (g val) (set! (mus-frequency (g 'osc)) val))))
  2216. (cons 'mus-phase
  2217. (dilambda
  2218. (lambda (g) (mus-phase (g 'osc)))
  2219. (lambda (g val) (set! (mus-phase (g 'osc)) val))))
  2220. (cons 'mus-copy copy)))
  2221. (defgenerator (r2k!cos
  2222. :make-wrapper (lambda (g)
  2223. (set! (g 'rr1) (+ 1.0 (* (g 'r) (g 'r))))
  2224. (set! (g 'r2) (* 2.0 (abs (g 'r))))
  2225. (set! (g 'norm) (expt (- (g 'rr1) (g 'r2)) (g 'k)))
  2226. (set! (g 'osc) (make-polywave (g 'frequency) (list 0 (g 'rr1) 1 (- (g 'r2))) mus-chebyshev-second-kind))
  2227. (set! (g 'k) (- (g 'k)))
  2228. g)
  2229. :methods r2k!cos-methods)
  2230. (frequency *clm-default-frequency*) (r 0.5) (k 0.0) rr1 r2 norm fm
  2231. (osc #f))
  2232. (define r2k!cos
  2233. (let ((documentation "(make-2rk!cos frequency (r 0.5) (k 0.0)) creates an r2k!cos generator. (r2k!cos gen (fm 0.0))
  2234. returns many cosines spaced by frequency with amplitude too messy to write down."))
  2235. (lambda* (gen (fm 0.0))
  2236. (let-set! gen 'fm fm)
  2237. (with-let gen
  2238. (* (expt (polywave osc fm) k) norm)))))
  2239. #|
  2240. ;;; old form
  2241. (with-let gen
  2242. (let ((rr1 (+ 1.0 (* r r)))
  2243. (r2 (* 2 (abs r)))) ; abs for negative r
  2244. (* (expt (- rr1
  2245. (* r2 (oscil osc fm)))
  2246. (- k))
  2247. (expt (- rr1 r2) k))))) ; amplitude normalization
  2248. |#
  2249. ;;; there is still noticable DC offset if r != 0.5 -- could precompute it and subtract (and there's lots of DC anyway)
  2250. #|
  2251. (with-sound (:clipped #f :statistics #t :play #t)
  2252. (let ((gen (make-r2k!cos 440.0 :r 0.5 :k 3.0)))
  2253. (do ((i 0 (+ i 1)))
  2254. ((= i 10000))
  2255. (outa i (r2k!cos gen)))))
  2256. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2257. (let ((gen (make-r2k!cos 440.0 :r 0.5 :k 3.0))
  2258. (indf (make-env '(0 1 1 0 10 0) :length 80000 :scaler 10.0 :offset 1)))
  2259. (do ((i 0 (+ i 1)))
  2260. ((= i 80000))
  2261. (set! (gen 'k) (env indf))
  2262. (outa i (r2k!cos gen)))))
  2263. |#
  2264. (definstrument (pianoy beg dur freq amp)
  2265. (let ((gen (make-r2k!cos freq :r 0.5 :k 3.0))
  2266. (ampf (make-env (list 0 0 .01 1 .03 1 1 .15 (max 2 dur) 0.0) :base 32 :scaler amp :duration dur))
  2267. (start (seconds->samples beg))
  2268. (stop (seconds->samples (+ beg dur))))
  2269. (do ((i start (+ i 1)))
  2270. ((= i stop))
  2271. (outa i (* (env ampf)
  2272. (r2k!cos gen))))))
  2273. ;;; (with-sound (:statistics #t :play #t :clipped #f) (pianoy 0 3 100 .5))
  2274. ;;; this can be combined with bouncy-like changes to get an evolving sound
  2275. (definstrument (pianoy1 beg dur freq amp (bounce-freq 5) (bounce-amp 20))
  2276. (let ((len (seconds->samples dur))
  2277. (start (seconds->samples beg)))
  2278. (let ((gen (make-r2k!cos freq :r 0.5 :k 3.0))
  2279. (gen1 (make-oscil bounce-freq))
  2280. (bouncef (make-env '(0 1 1 0) :base 32 :scaler bounce-amp :duration 1.0))
  2281. (rf (make-env (list 0 0 1 1 (max 2.0 dur) 0) :base 32 :scaler .1 :offset .25 :duration dur))
  2282. (ampf (make-env (list 0 0 .01 1 .03 1 1 .15 (max 2 dur) 0.0) :base 32 :scaler amp :duration dur))
  2283. (stop (+ start len))
  2284. (fv (make-float-vector len)))
  2285. (do ((i 0 (+ i 1)))
  2286. ((= i len))
  2287. (float-vector-set! fv i (+ (env rf) (abs (* (env bouncef) (oscil gen1))))))
  2288. (do ((i start (+ i 1))
  2289. (j 0 (+ j 1)))
  2290. ((= i stop))
  2291. (set! (gen 'r) (float-vector-ref fv j))
  2292. (outa i (* (env ampf)
  2293. (r2k!cos gen)))))))
  2294. #|
  2295. (with-sound (:statistics #t :play #t :clipped #f)
  2296. (pianoy1 0 4 200 .5 1 .1))
  2297. |#
  2298. (definstrument (pianoy2 beg dur freq amp)
  2299. (let ((gen (make-r2k!cos freq :r 0.5 :k 3.0))
  2300. (ampf (make-env (list 0 0 .01 1 .03 1 1 .15 (max 2 dur) 0.0) :base 32 :scaler amp :duration dur))
  2301. (knock (make-fmssb 10.0 20.0 :index 1.0))
  2302. (kmpf (make-env '(0 0 1 1 3 1 100 0) :base 3 :scaler .05 :length 30000))
  2303. (indf (make-env '(0 1 1 0) :length 30000 :base 3 :scaler 10))
  2304. (start (seconds->samples beg))
  2305. (stop (seconds->samples (+ beg dur))))
  2306. (do ((i start (+ i 1)))
  2307. ((= i stop))
  2308. (set! (knock 'index) (env indf))
  2309. (outa i (+ (* (env ampf)
  2310. (r2k!cos gen))
  2311. (* (env kmpf)
  2312. (fmssb knock 0.0)))))))
  2313. #|
  2314. (with-sound (:clipped #f :statistics #t :play #t)
  2315. (pianoy2 0 1 100 .5))
  2316. |#
  2317. ;;; --------------------------------------------------------------------------------
  2318. ;;; inf sines scaled by 1/2^k: k2sin
  2319. ;;; Jolley first col first row
  2320. ;;; not flexible -- very similar to several others
  2321. (defgenerator (k2sin
  2322. :make-wrapper (lambda (g)
  2323. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2324. g))
  2325. (frequency *clm-default-frequency*) (angle 0.0) fm)
  2326. (define k2sin
  2327. (let ((documentation "(make-k2sin frequency) creates a k2sin generator. (k2sin gen (fm 0.0))
  2328. returns many sines spaced by frequency with amplitude 1/(2^k)."))
  2329. (lambda* (gen (fm 0.0))
  2330. (let-set! gen 'fm fm)
  2331. (with-let gen
  2332. (let ((x angle))
  2333. (set! angle (+ angle fm frequency))
  2334. (/ (* 3.0 (sin x)) ; 3 rather than 4 for normalization
  2335. (- 5.0 (* 4.0 (cos x)))))))))
  2336. #|
  2337. (with-sound (:clipped #f :statistics #t :play #t)
  2338. (let ((gen (make-k2sin 440.0)))
  2339. (do ((i 0 (+ i 1)))
  2340. ((= i 10000))
  2341. (outa i (k2sin gen)))))
  2342. |#
  2343. ;;; using the second Sansone formula, we get the sum of cos case by using a=-5b/4 or 3/(4cosx-5)
  2344. (defgenerator (k2cos
  2345. :make-wrapper (lambda (g)
  2346. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2347. g))
  2348. (frequency *clm-default-frequency*) (angle 0.0) fm)
  2349. (define k2cos
  2350. (let ((documentation "(make-k2cos frequency) creates a k2cos generator. (k2cos gen (fm 0.0))
  2351. returns many cosines spaced by frequency with amplitude 1/(2^k)."))
  2352. (lambda* (gen (fm 0.0))
  2353. (let-set! gen 'fm fm)
  2354. (with-let gen
  2355. (let ((x angle))
  2356. (set! angle (+ angle fm frequency))
  2357. (* 0.5 (- (/ 3.0
  2358. (- 5.0 (* 4.0 (cos x))))
  2359. 1.0)))))))
  2360. #|
  2361. (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  2362. (let ((gen (make-k2cos 440.0)))
  2363. (do ((i 0 (+ i 1)))
  2364. ((= i 10000))
  2365. (outa i (k2cos gen)))))
  2366. |#
  2367. (defgenerator (k2ssb
  2368. :make-wrapper (lambda (g)
  2369. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2370. g))
  2371. (frequency *clm-default-frequency*) (ratio 1.0) (angle 0.0) fm)
  2372. (define k2ssb
  2373. (let ((documentation "(make-k2ssb frequency (ratio 1.0)) creates a k2ssb generator. (k2ssb gen (fm 0.0))
  2374. returns many sinusoids from frequency spaced by frequency * ratio with amplitude 1/(2^k)."))
  2375. (lambda* (gen (fm 0.0))
  2376. (let-set! gen 'fm fm)
  2377. (with-let gen
  2378. (let* ((cx angle)
  2379. (mx (* cx ratio)))
  2380. (set! angle (+ angle fm frequency))
  2381. (/ (- (* 3 (cos cx))
  2382. (* (sin cx) 4.0 (sin mx)))
  2383. (* 3.0 (- 5.0 (* 4.0 (cos mx))))))))))
  2384. #|
  2385. (with-sound (:clipped #f :statistics #t :play #t)
  2386. (let ((gen (make-k2ssb 1000.0 0.1)))
  2387. (do ((i 0 (+ i 1)))
  2388. ((= i 10000))
  2389. (outa i (* .5 (k2ssb gen))))))
  2390. |#
  2391. ;;; --------------------------------------------------------------------------------
  2392. ;;; this was inspired by Andrews, Askey, Roy "Special Functions" p396, but there's an error somewhere...
  2393. ;;; it produces sum r^k sin(2k-1)x
  2394. ;;; (not normalized)
  2395. (define dblsum-methods
  2396. (list
  2397. (cons 'mus-frequency
  2398. (dilambda
  2399. (lambda (g) (radians->hz (* 0.5 (g 'frequency))))
  2400. (lambda (g val) (set! (g 'frequency) (hz->radians (* 2 val))) val)))))
  2401. (defgenerator (dblsum
  2402. :make-wrapper (lambda (g)
  2403. (set! (g 'frequency) (hz->radians (* 2 (g 'frequency))))
  2404. g)
  2405. :methods dblsum-methods)
  2406. (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm)
  2407. (define dblsum
  2408. (let ((documentation "(make-dblsum frequency (r 0.5)) creates a dblsum generator. (dblsum gen (fm 0.0))
  2409. returns many sines from frequency spaced by frequency * (2k -1) with amplitude r^k (this is buggy)."))
  2410. (lambda* (gen (fm 0.0))
  2411. (let-set! gen 'fm fm)
  2412. (with-let gen
  2413. (let ((x angle))
  2414. (set! angle (+ angle fm frequency))
  2415. (/ (* (+ 1 r) (sin (* 0.5 x)))
  2416. (* (- 1 r) (+ 1.0 (* -2.0 r (cos x)) (* r r)))))))))
  2417. #|
  2418. (with-sound (:clipped #f :statistics #t :play #t)
  2419. (let ((gen (make-dblsum 100 0.5)))
  2420. (do ((i 0 (+ i 1)))
  2421. ((= i 10000))
  2422. (outa i (* .25 (dblsum gen))))))
  2423. |#
  2424. ;;; --------------------------------------------------------------------------------
  2425. ;;; inf odd sinusoids scaled by r^odd-k/odd-k: rkoddssb
  2426. ;;; G&R second col rows 7&8 (odd r^k/k)
  2427. (define rkoddssb-methods
  2428. (list
  2429. (cons 'mus-scaler
  2430. (dilambda
  2431. (lambda (g) (g 'r))
  2432. (lambda (g val)
  2433. (set! (g 'r) (generator-clamp-r val))
  2434. (set! (g 'rr1) (+ 1.0 (* (g 'r) (g 'r))))
  2435. (set! (g 'norm) (/ 1.0 (- (log (+ 1.0 (g 'r))) (log (- 1.0 (g 'r)))))))))))
  2436. (defgenerator (rkoddssb
  2437. :make-wrapper (lambda (g)
  2438. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2439. (set! (g 'r) (generator-clamp-r (g 'r)))
  2440. (set! (g 'rr1) (+ 1.0 (* (g 'r) (g 'r))))
  2441. (set! (g 'norm) (/ 1.0 (- (log (+ 1.0 (g 'r))) (log (- 1.0 (g 'r))))))
  2442. g)
  2443. :methods rkoddssb-methods)
  2444. (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm rr1 norm)
  2445. (define rkoddssb
  2446. (let ((documentation "(make-rkoddssb frequency (ratio 1.0) (r 0.5)) creates an rkoddssb generator. (rkoddssb gen (fm 0.0))
  2447. returns many sinusoids from frequency spaced by frequency * 2 * ratio with amplitude (r^(2k-1))/(2k-1)."))
  2448. (lambda* (gen (fm 0.0))
  2449. (let-set! gen 'fm fm)
  2450. (with-let gen
  2451. (let* ((cx angle)
  2452. (mx (* cx ratio)))
  2453. (let ((cxx (- cx mx))
  2454. (cmx (* 2.0 r (cos mx))))
  2455. (set! angle (+ angle fm frequency))
  2456. (* (- (* (cos cxx)
  2457. 0.5
  2458. (log (/ (+ rr1 cmx) (- rr1 cmx))))
  2459. (* (sin cxx)
  2460. (atan (* 2.0 r (sin mx))
  2461. (- 1.0 (* r r)))))
  2462. norm)))))))
  2463. #|
  2464. (with-sound (:clipped #f :statistics #t :play #t)
  2465. (let ((gen (make-rkoddssb 1000.0 0.1 0.5)))
  2466. (do ((i 0 (+ i 1)))
  2467. ((= i 10000))
  2468. (outa i (* .5 (rkoddssb gen))))))
  2469. |#
  2470. (definstrument (glassy beg dur freq amp)
  2471. (let ((r (expt .001 (/ (floor (/ *clm-srate* (* 3 freq)))))))
  2472. (let ((start (seconds->samples beg))
  2473. (stop (seconds->samples (+ beg dur)))
  2474. (clang (make-rkoddssb (* freq 2) (/ 1.618 2) r))
  2475. (clangf (make-env (list 0 0 .01 1 .1 1 .2 .4 (max .3 dur) 0) :scaler amp :duration dur))
  2476. (crf (make-env '(0 1 1 0) :scaler r :duration dur)))
  2477. (do ((i start (+ i 1)))
  2478. ((= i stop))
  2479. (set! (clang 'r) (env crf))
  2480. (outa i (* (env clangf)
  2481. (rkoddssb clang 0.0)))))))
  2482. #|
  2483. (with-sound (:clipped #f :statistics #t :play #t)
  2484. (glassy 0 .1 1000 .5))
  2485. (with-sound (:clipped #f :statistics #t :play #t)
  2486. (do ((i 0 (+ i 1)))
  2487. ((= i 10))
  2488. (glassy (* i .3) .1 (+ 400 (* 100 i)) .5)))
  2489. (with-sound (:statistics #t :play #t :scaled-to .5)
  2490. (let ((gen (make-rkoddssb 5000.0 0.1 0.95))
  2491. (ampf (make-env '(0 0 9 1 10 0) :base 32 :length 10000))
  2492. (noi (make-rand 10000 .1)))
  2493. (do ((i 0 (+ i 1)))
  2494. ((= i 10000))
  2495. (outa i (* (env ampf) (sin (rkoddssb gen (rand noi))))))))
  2496. |#
  2497. ;;; --------------------------------------------------------------------------------
  2498. ;;; inf sinusoids scaled by kr^k: krksin
  2499. ;;; Zygmund first
  2500. ;;; this looks interesting, but how to normalize? sum of sines is bad enough, kr^k -> r/(1-r)^2 if x^2<1 (since n=inf)
  2501. ;;; for low n, we could use the Tn roots stuff (clm.c)
  2502. ;;; the formula must be assuming r<1.0 -- if greater than 1 it's acting like r2k! above
  2503. (defgenerator (krksin
  2504. :make-wrapper (lambda (g)
  2505. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2506. g))
  2507. (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm)
  2508. (define krksin
  2509. (let ((documentation "(make-krksin frequency (r 0.5)) creates a krksin generator. (krksin gen (fm 0.0))
  2510. returns many sines spaced by frequency with amplitude kr^k."))
  2511. (lambda* (gen (fm 0.0))
  2512. (let-set! gen 'fm fm)
  2513. (with-let gen
  2514. (let ((x angle)
  2515. (r1 (- 1.0 r)))
  2516. (let ((r3 (if (> r .9) r1 1.0)) ; not right yet...
  2517. (den (+ 1.0 (* -2.0 r (cos x)) (* r r))))
  2518. (set! angle (+ angle fm frequency))
  2519. (/ (* r1 r1 r3 (sin x))
  2520. (* den den))))))))
  2521. #|
  2522. (with-sound (:clipped #f :statistics #t :play #t)
  2523. (let ((gen (make-krksin 440.0 0.5)))
  2524. (do ((i 0 (+ i 1)))
  2525. ((= i 10000))
  2526. (outa i (krksin gen)))))
  2527. (with-sound (:clipped #f :statistics #t :scaled-to .5 :play #t)
  2528. (let ((gen (make-krksin 6.0 0.965))) ; 60 .6 also
  2529. (do ((i 0 (+ i 1)))
  2530. ((= i 100000))
  2531. (outa i (krksin gen)))))
  2532. (do ((i 0 (+ i 1)))
  2533. ((= i 10))
  2534. (let ((mx (maxamp (with-sound (:clipped #f :output (make-float-vector 10000))
  2535. (let ((gen (make-krksin 20.0 (* i 0.1))))
  2536. (do ((i 0 (+ i 1)))
  2537. ((= i 10000))
  2538. (outa i (krksin gen))))))))
  2539. (format () ";~A: ~A" (* 0.1 i) mx)))
  2540. ;;; relation between 1/(1-x)^2 and peak amp:
  2541. (with-sound (:clipped #f)
  2542. (do ((i 0 (+ i 1))
  2543. (r 0.0 (+ r .01)))
  2544. ((= i 100))
  2545. (let ((val (/ 1.0 (expt (- 1 r) 2))))
  2546. (let ((pk 0.0))
  2547. (let ((gen (make-krksin 1.0 r)))
  2548. (do ((k 0 (+ k 1)))
  2549. ((= k 100000))
  2550. (let ((x (abs (krksin gen))))
  2551. (if (> x pk) (set! pk x)))))
  2552. (outa i (/ pk val))))))
  2553. ;;; r 0: 1.0 (sin(x) in this case)
  2554. ;;; else min den is (1-2r+r^2) so peak should be around (/ (expt (+ 1 (* - 2 r) (* r r)) 2))
  2555. ;;; but at that point sin(x)->0 as x
  2556. |#
  2557. #|
  2558. ;;; --------------------------------------------------------------------------------
  2559. ;;; absolute value of oscil: abssin
  2560. ;;; Zygmund second -- not actually very useful, but shows cos 2nx of abs
  2561. (define abssin-methods
  2562. (list
  2563. (cons 'mus-frequency
  2564. (dilambda
  2565. (lambda (g) (mus-frequency (g 'osc)))
  2566. (lambda (g val) (set! (mus-frequency (g 'osc)) val))))
  2567. (cons 'mus-phase
  2568. (dilambda
  2569. (lambda (g) (mus-phase (g 'osc)))
  2570. (lambda (g val) (set! (mus-phase (g 'osc)) val))))))
  2571. (defgenerator (abssin
  2572. :make-wrapper (lambda (g)
  2573. (set! (g 'osc) (make-oscil (g 'frequency)))
  2574. g)
  2575. :methods abssin-methods)
  2576. (frequency *clm-default-frequency*) fm
  2577. (osc #f))
  2578. (define abssin
  2579. (let ((documentation "(make-abssin frequency) creates an abssin generator. (abssin gen (fm 0.0)) returns (abs oscil)."))
  2580. (lambda* (gen (fm 0.0))
  2581. (let-set! gen 'fm fm)
  2582. (with-let gen
  2583. (/ (- (abs (oscil osc fm))
  2584. (/ 2.0 pi))
  2585. (/ 2.0 pi)))))) ; original went from 0 to 1.0, subtract 2/pi, and we get peak at -2/pi
  2586. ;; DC: sin^2 x = 1/2 - cos 2x,
  2587. ;; so every term in the sum adds 1/(2(4k^2-1)) -> 1/4 (J 397 or 373)
  2588. ;; so DC is 2/pi = 0.6366
  2589. (with-sound (:clipped #f :statistics #t :play #t)
  2590. (let ((gen (make-abssin 440.0)))
  2591. (do ((i 0 (+ i 1)))
  2592. ((= i 10000))
  2593. (outa i (abssin gen)))))
  2594. (with-sound (:clipped #f :statistics #t :play #t)
  2595. (let ((vib (make-abssin 100.0)) ; spacing will be 200, if FM you get index-proportional amount as constant offset
  2596. (gen (make-oscil 1000.0))
  2597. (ampf (make-env '(0 0 1 1 2 1 3 0) :scaler .5 :length 20000)))
  2598. (do ((i 0 (+ i 1)))
  2599. ((= i 10000))
  2600. (outa i
  2601. (* (env ampf)
  2602. (oscil gen 0.0 (* 3 (abssin vib 0.0))))))))
  2603. ;;; pitch is 2*freq, 200 1, 400 .203, 600 .087, 800 .049, 1000 .031, 1200 .021
  2604. ;;; 1 .2 .086 .048 .030 .021 -- (/ 3.0 (- (* 4 (* 6 6)) 1))
  2605. |#
  2606. ;;; --------------------------------------------------------------------------------
  2607. ;;; inf cosines, scaled by (-a+sqrt(a^2-b^2))^n/b^n: abcos
  2608. ;;; from Sansone, p182, assumptions: a not 0, b not 0, b/a real, abs(b/a)<1 (b less than a)
  2609. (defgenerator (abcos
  2610. :make-wrapper (lambda (g)
  2611. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2612. (set! (g 'ab) (sqrt (- (* (g 'a) (g 'a)) (* (g 'b) (g 'b)))))
  2613. (set! (g 'norm) (/ 0.5 (- (/ 1.0 (- 1.0 (/ (abs (- (g 'ab) (g 'a))) (g 'b)))) 1.0)))
  2614. ;; i.e. 1/(1-r) -1 because we start at k=1, r=the complicated a/b business
  2615. g))
  2616. (frequency *clm-default-frequency*) (a 0.5) (b 0.25) (angle 0.0) ab norm fm)
  2617. (define abcos
  2618. (let ((documentation "(make-abcos frequency (a 0.5) (b 0.25)) creates an abcos generator. (abcos gen (fm 0.0))
  2619. returns many cosines spaced by frequency with amplitude (-a+sqrt(a^2-b^2))^k/b^k."))
  2620. (lambda* (gen (fm 0.0))
  2621. (let-set! gen 'fm fm)
  2622. (with-let gen
  2623. (let ((x angle))
  2624. (set! angle (+ angle fm frequency))
  2625. (* norm (- (/ ab (+ a (* b (cos x)))) 1.0)))))))
  2626. #|
  2627. (with-sound (:clipped #f :statistics #t :play #t)
  2628. (let ((gen (make-abcos 100.0 0.5 0.25)))
  2629. (do ((i 0 (+ i 1)))
  2630. ((= i 10000))
  2631. (outa i (abcos gen)))))
  2632. |#
  2633. (defgenerator (absin
  2634. :make-wrapper (lambda (g)
  2635. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2636. (set! (g 'ab) (sqrt (- (* (g 'a) (g 'a)) (* (g 'b) (g 'b)))))
  2637. g))
  2638. (frequency *clm-default-frequency*) (a 0.5) (b 0.25) (angle 0.0) ab fm)
  2639. (define absin
  2640. (let ((documentation "(make-absin frequency (a 0.5) (b 0.25)) creates an absin generator. (absin gen (fm 0.0))
  2641. returns many sines spaced by frequency with amplitude (-a+sqrt(a^2-b^2))^k/b^k."))
  2642. (lambda* (gen (fm 0.0))
  2643. (let-set! gen 'fm fm)
  2644. (with-let gen
  2645. (let ((x angle))
  2646. (set! angle (+ angle fm frequency))
  2647. (/ (* ab (sin x) )
  2648. (+ a (* b (cos x)))))))))
  2649. #|
  2650. (with-sound (:clipped #f :statistics #t :play #t)
  2651. (let ((gen (make-absin 100.0 0.5 0.25)))
  2652. (do ((i 0 (+ i 1)))
  2653. ((= i 10000))
  2654. (outa i (* .5 (absin gen))))))
  2655. |#
  2656. ;;; --------------------------------------------------------------------------------
  2657. ;;; inf cosines scaled by 1/(r^2+k^2): r2k2cos
  2658. ;;; J second col third row
  2659. (defgenerator (r2k2cos
  2660. :make-wrapper (lambda (g)
  2661. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2662. g))
  2663. (frequency *clm-default-frequency*) (r 1.0) (angle 0.0) fm)
  2664. (define (r2k2cos-norm a)
  2665. ;; J 124
  2666. (- (/ (* pi (cosh (* pi a)))
  2667. (* 2 a (sinh (* pi a))))
  2668. (/ 1.0 (* 2 a a))))
  2669. (define r2k2cos
  2670. (let ((documentation "(make-r2k2cos frequency (r 1.0)) creates an r2k2cos generator. (r2k2cos gen (fm 0.0))
  2671. returns many cosines spaced by frequency with amplitude 1/(r^2+k^2)."))
  2672. (lambda* (gen (fm 0.0))
  2673. (let-set! gen 'fm fm)
  2674. (with-let gen
  2675. (let ((x angle))
  2676. (if (> x (* 2 pi))
  2677. (set! x (modulo x (* 2 pi))))
  2678. (set! angle (+ x fm frequency))
  2679. (/ (- (* pi (/ (cosh (* r (- pi x)))
  2680. (sinh (* r pi))))
  2681. (/ r))
  2682. (* 2 r (r2k2cos-norm r))))))))
  2683. #|
  2684. (with-sound (:clipped #f :statistics #t :play #t)
  2685. (let ((gen (make-r2k2cos 100.0 1.0))) ; 400 .25 -- this isn't very flexible
  2686. (do ((i 0 (+ i 1)))
  2687. ((= i 10000))
  2688. (outa i (* .5 (r2k2cos gen))))))
  2689. |#
  2690. ;;; --------------------------------------------------------------------------------
  2691. ;;; coskx/k = -ln(2sin(x/2)) or 1/2ln(1/(2-2cosx))
  2692. ;;; sinkx/k = (pi-x)/2 both 0..2pi
  2693. ;;; similarly -1^k : x/2 and ln(2cos(x/2)) (p44..46)
  2694. ;;; 2k-1: pi/x and 1/2ln cot (x/2) 0..2pi and 0..pi
  2695. ;;; but all of these are unbounded, and discontinuous
  2696. ;;; --------------------------------------------------------------------------------
  2697. #|
  2698. ;;; from Stilson/Smith apparently -- was named "Discrete Summation Formula" which doesn't convey anything to me
  2699. ;;; Alexander Kritov suggests time-varying "a" is good (this is a translation of his code)
  2700. (defgenerator (blsaw
  2701. :make-wrapper (lambda (g)
  2702. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2703. g))
  2704. (frequency *clm-default-frequency*) (n 1) (r 0.5) (angle 0.0) fm)
  2705. (define blsaw
  2706. (let ((documentation "(make-blsaw frequency (n 1) (r 0.5)) creates a blsaw generator. (blsaw gen (fm 0.0)) returns a band-limited sawtooth wave."))
  2707. (lambda* (gen (fm 0.0))
  2708. (let-set! gen 'fm fm)
  2709. (with-let gen
  2710. (let* ((a r)
  2711. (N n)
  2712. (x angle)
  2713. (incr frequency)
  2714. (den (+ 1.0 (* -2.0 a (cos x)) (* a a))))
  2715. (set! angle (+ angle fm incr))
  2716. (if (< (abs den) nearly-zero)
  2717. 0.0
  2718. (let* ((s1 (* (expt a (- N 1.0)) (sin (+ (* (- N 1.0) x) incr))))
  2719. (s2 (* (expt a N) (sin (+ (* N x) incr))))
  2720. (s3 (* a (sin (+ x incr)))))
  2721. (/ (+ (sin incr)
  2722. (- s3)
  2723. (- s2)
  2724. s1)
  2725. den))))))))
  2726. (with-sound (:clipped #f :statistics #t :play #t)
  2727. (let ((gen (make-blsaw 440.0 :r 0.5 :n 3)))
  2728. (do ((i 0 (+ i 1)))
  2729. ((= i 10000))
  2730. (outa i (blsaw gen)))))
  2731. |#
  2732. ;;; --------------------------------------------------------------------------------
  2733. ;;; asymmetric fm gens
  2734. (defgenerator (asyfm
  2735. :make-wrapper (lambda (g)
  2736. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2737. g))
  2738. (frequency *clm-default-frequency*) (ratio 1.0) (r 1.0) (index 1.0) (phase 0.0) fm)
  2739. (define asyfm-J
  2740. (let ((documentation "(asyfm-J gen fm) is the same as the CLM asymmetric-fm generator (index=1.0), set r != 1.0 to get the asymmetric spectra"))
  2741. (lambda* (gen (fm 0.0))
  2742. (let-set! gen 'fm fm)
  2743. (with-let gen
  2744. (let ((result (let ((r1 (/ r))
  2745. (one (if (or (> r 1.0)
  2746. (< -1.0 r 0.0))
  2747. -1.0 1.0))
  2748. (modphase (* ratio phase)))
  2749. (* (exp (* 0.5 index (- r r1) (+ one (cos modphase))))
  2750. (cos (+ phase (* 0.5 index (+ r r1) (sin modphase)))))))) ; use cos, not sin, to get predictable amp
  2751. (set! phase (+ phase fm frequency))
  2752. result)))))
  2753. #|
  2754. (with-sound (:clipped #f :statistics #t :play #t)
  2755. (let ((gen (make-asyfm 2000.0 :ratio .1)))
  2756. (do ((i 0 (+ i 1)))
  2757. ((= i 10000))
  2758. (outa i (* .5 (asyfm-J gen))))))
  2759. (with-sound (:clipped #f :statistics #t :play #t)
  2760. (let ((gen (make-asyfm 2000.0 :ratio .1 :index 1))
  2761. (r-env (make-env '(0 -4 1 -1) :length 20000)))
  2762. (do ((i 0 (+ i 1)))
  2763. ((= i 20000))
  2764. (set! (gen 'r) (env r-env))
  2765. (outa i (asyfm-J gen)))))
  2766. (define (val index r)
  2767. (let ((sum 0.0))
  2768. (do ((i -20 (+ i 1)))
  2769. ((= i 21))
  2770. (set! sum (+ sum (* (expt r i) (bes-jn i index)))))
  2771. (let ((norm (exp (* 0.5 index (- r (/ r))))))
  2772. (list sum norm))))
  2773. (for-each
  2774. (lambda (index)
  2775. (for-each
  2776. (lambda (r)
  2777. (let ((peak (maxamp (with-sound (:clipped #f :output (make-float-vector 1000))
  2778. (let ((gen (make-asymmetric-fm 2000.0 :ratio .1 :r r)))
  2779. (do ((i 0 (+ i 1)))
  2780. ((= i 1000))
  2781. (outa i (asymmetric-fm gen index))))))))
  2782. (if (> (abs (- peak 1.0)) .1)
  2783. (format () ";asymmetric-fm peak: ~A, index: ~A, r: ~A" peak index r))))
  2784. (list -10.0 -1.5 -0.5 0.5 1.0 1.5 10.0)))
  2785. (list 1.0 3.0 10.0))
  2786. |#
  2787. (define asyfm-I
  2788. (let ((documentation "(asyfm-I gen fm) is the I0 case of the asymmetric-fm generator"))
  2789. (lambda* (gen (fm 0.0))
  2790. (let-set! gen 'fm fm)
  2791. (with-let gen
  2792. (let ((result (let ((r1 (/ r))
  2793. (modphase (* ratio phase)))
  2794. (* (exp (* 0.5 index (+ r r1) (- (cos modphase) 1.0)))
  2795. (cos (+ phase (* 0.5 index (- r r1) (sin modphase))))))))
  2796. (set! phase (+ phase fm frequency))
  2797. result)))))
  2798. #|
  2799. (with-sound (:clipped #f :statistics #t :play #t)
  2800. (let ((gen (make-asyfm 2000.0 :ratio .1)))
  2801. (do ((i 0 (+ i 1)))
  2802. ((= i 10000))
  2803. (outa i (* .5 (asyfm-I gen))))))
  2804. |#
  2805. ;;; --------------------------------------------------------------------------------
  2806. ;;; bess (returns bes-jn, like oscil returns sin) normalized to peak at 1.0
  2807. ;;; frequency here is the frequency in Hz of the damped sinusoid part of the bessel function
  2808. (define bessel-peaks (vector 1.000 0.582 0.487 0.435 0.400 0.375 0.355 0.338 0.325 0.313 0.303 0.294 0.286 0.279 0.273 0.267 0.262 0.257 0.252 0.248))
  2809. (defgenerator (bess
  2810. :make-wrapper (lambda (g)
  2811. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2812. (set! (g 'norm) (if (>= (g 'n) (length bessel-peaks))
  2813. (/ 0.67 (expt (g 'n) 1/3))
  2814. ;; this formula comes from V P Krainov, "Selected Mathetical Methods in Theoretical Physics"
  2815. (bessel-peaks (g 'n))))
  2816. g))
  2817. (frequency *clm-default-frequency*) (n 0) (angle 0.0) (norm 1.0) fm)
  2818. (define bess
  2819. (let ((documentation "(make-bess frequency (n 0)) creates a bessel function (Jn) generator. (bess gen (fm 0.0)) returns Jn."))
  2820. (lambda* (gen (fm 0.0))
  2821. (let-set! gen 'fm fm)
  2822. (with-let gen
  2823. (let ((result (/ (bes-jn n angle) norm)))
  2824. (set! angle (+ angle frequency fm))
  2825. result)))))
  2826. #|
  2827. (with-sound (:clipped #f :statistics #t :play #t)
  2828. (let ((gen (make-bess 100.0 :n 0)))
  2829. (do ((i 0 (+ i 1)))
  2830. ((= i 1000))
  2831. (outa i (bess gen)))))
  2832. (with-sound (:clipped #f :statistics #t :play #t)
  2833. (let ((gen1 (make-bess 400.0 :n 1))
  2834. (gen2 (make-bess 400.0 :n 1))
  2835. (vol (make-env '(0 0 1 1 9 1 10 0) :scaler 2.0 :length 20000)))
  2836. (do ((i 0 (+ i 1)))
  2837. ((= i 20000))
  2838. (outa i (bess gen1 (* (env vol) (bess gen2 0.0)))))))
  2839. ;;; max amps:
  2840. (do ((i 1 (+ i 1)))
  2841. ((= i 100))
  2842. (let ((mx 0.0))
  2843. (do ((k 0.0 (+ k .001)))
  2844. ((> k 200))
  2845. (let ((val (bes-jn i k)))
  2846. (if (> (abs val) mx)
  2847. (set! mx (abs val)))))
  2848. (format () ";~A" (+ mx .001))))
  2849. (with-sound (:clipped #f :statistics #t :play #t)
  2850. (let ((gen1 (make-bess 400.0 :n 1))
  2851. (gen2 (make-oscil 400.0))
  2852. (vol (make-env '(0 1 1 0) :scaler 1.0 :length 20000)))
  2853. (do ((i 0 (+ i 1)))
  2854. ((= i 20000))
  2855. (outa i (bess gen1 (* (env vol) (oscil gen2 0.0)))))))
  2856. ;;; also gen2 800, env scl 0.2
  2857. |#
  2858. ;;; --------------------------------------------------------------------------------
  2859. ;;; Watson "Bessel Functions" p358 127 128 (J0(k sqrt(r^2+a^2- 2ar cos x)) = sum em Jm(ka)Jm(kr) cos mx
  2860. ;;; em here is "Neumann's factor" (p22) = 1 if m=0, 2 otherwise
  2861. (defgenerator (jjcos
  2862. :make-wrapper (lambda (g)
  2863. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2864. g))
  2865. (frequency *clm-default-frequency*) (r 0.5) (a 1.0) (k 1.0) (angle 0.0) fm)
  2866. (define jjcos
  2867. (let ((documentation "(make-jjcos frequency (r 0.5) (a 1.0) (k 1)) creates a jjcos generator. (jjcos gen (fm 0.0))
  2868. returns a sum of cosines scaled by a product of Bessel functions."))
  2869. (lambda* (gen (fm 0.0))
  2870. (let-set! gen 'fm fm)
  2871. (with-let gen
  2872. (let ((x angle)
  2873. (dc (* (bes-j0 (* k a)) (bes-j0 (* k r)))))
  2874. (let ((norm (- (bes-j0 (* k (sqrt (+ (* a a) (* r r) (* -2 a r))))) dc)))
  2875. ;; this norm only works if the a/r/k values all small enough that the initial J0 bump dominates
  2876. ;; if they're large (k=10 for example), later maxes come into play.
  2877. ;; we need a formula for a sum of JJ's
  2878. ;;
  2879. ;; the resultant spectra are similar to FM (we can get sharper bumps, or low-passed bumps, etc)
  2880. (set! angle (+ angle fm frequency))
  2881. (/ (- (bes-j0 (* k (sqrt (+ (* r r)
  2882. (* a a)
  2883. (* a -2.0 r (cos x))))))
  2884. dc) ; get rid of DC component
  2885. norm)))))))
  2886. #|
  2887. (with-sound (:clipped #f :statistics #t :play #t)
  2888. (let ((gen (make-jjcos 100.0 :a 1.0 :r 1.0 :k 1)))
  2889. (do ((i 0 (+ i 1)))
  2890. ((= i 10000))
  2891. (outa i (* .5 (jjcos gen))))))
  2892. ;;; example:
  2893. (with-sound (:clipped #f :statistics #t :play #t)
  2894. (let ((gen (make-jjcos 100.0 :a 2.0 :r 1.0 :k 1)))
  2895. (do ((i 0 (+ i 1)))
  2896. ((= i 20000))
  2897. (outa i (jjcos gen)))))
  2898. :(* (bes-jn 1 1) (bes-jn 1 2))
  2899. 0.253788089467046
  2900. :(* (bes-jn 2 1) (bes-jn 2 2))
  2901. 0.0405418594904987
  2902. :(* (bes-jn 3 1) (bes-jn 3 2))
  2903. 0.00252256243314325
  2904. :(* (bes-jn 4 1) (bes-jn 4 2))
  2905. 8.41951242883886e-5
  2906. which matches perfectly
  2907. set k=10
  2908. :(* (bes-jn 1 10) (bes-jn 1 20))
  2909. 0.00290541944296873
  2910. :(* (bes-jn 2 10) (bes-jn 2 20))
  2911. -0.0408277687368493
  2912. :(* (bes-jn 3 10) (bes-jn 3 20))
  2913. -0.00577380202685643
  2914. :(* (bes-jn 4 10) (bes-jn 4 20))
  2915. -0.0286956880041051
  2916. :(* (bes-jn 5 10) (bes-jn 5 20))
  2917. -0.0353830269096024
  2918. :(* (bes-jn 6 10) (bes-jn 6 20))
  2919. 7.96480491715688e-4
  2920. :(* (bes-jn 7 10) (bes-jn 7 20))
  2921. -0.0399227881572529
  2922. :(* (bes-jn 8 10) (bes-jn 8 20))
  2923. -0.0234795438775677
  2924. :(* (bes-jn 9 10) (bes-jn 9 20))
  2925. 0.0365188087949483
  2926. :(* (bes-jn 10 10) (bes-jn 10 20))
  2927. 0.0386925399194178
  2928. :(* (bes-jn 11 10) (bes-jn 11 20))
  2929. 0.00755397504265978
  2930. :(* (bes-jn 12 10) (bes-jn 12 20))
  2931. -0.00754046620160803
  2932. :(* (bes-jn 13 10) (bes-jn 13 20))
  2933. -0.00591450759566936
  2934. :(* (bes-jn 14 10) (bes-jn 14 20))
  2935. -0.00175050411436045
  2936. :(* (bes-jn 15 10) (bes-jn 15 20))
  2937. -3.66078549147997e-6
  2938. which again matches
  2939. (define* (jjsin gen (fm 0.0))
  2940. (let-set! gen 'fm fm)
  2941. (with-let gen
  2942. (let ((x angle))
  2943. (set! angle (+ angle fm frequency))
  2944. (* (sin x)
  2945. (bes-j0 (* k (sqrt (+ (* r r)
  2946. (* a a)
  2947. (* a (* -2.0 r (cos x)))))))))))
  2948. (with-sound (:clipped #f :statistics #t :play #t)
  2949. (let ((gen (make-jjcos 100.0 :a 1.0 :r 1.0 :k 1)))
  2950. (do ((i 0 (+ i 1)))
  2951. ((= i 10000))
  2952. (outa i (jjsin gen)))))
  2953. (define* (jjesin gen (fm 0.0))
  2954. (let-set! gen 'fm fm)
  2955. (with-let gen
  2956. (let ((x angle))
  2957. (set! angle (+ angle fm frequency))
  2958. (* (exp (* r (- (cos x) 1.0))) ; -1 for norm , but there's huge DC offset
  2959. (bes-j0 (* r (sin x)))))))
  2960. (with-sound (:clipped #f :statistics #t :play #t)
  2961. (let ((gen (make-jjcos 100.0 :a 1.0 :r 1.0 :k 1)))
  2962. (do ((i 0 (+ i 1)))
  2963. ((= i 10000))
  2964. (outa i (jjesin gen)))))
  2965. |#
  2966. ;;; --------------------------------------------------------------------------------
  2967. ;;; check J0(zsinx) formula
  2968. ;;; main difference from FM: index is divided by 2, J value is squared, else just like cos(sin)
  2969. (defgenerator (j0evencos
  2970. :make-wrapper (lambda (g)
  2971. (set! (g 'frequency) (hz->radians (g 'frequency)))
  2972. g))
  2973. (frequency *clm-default-frequency*) (index 1.0) (angle 0.0) fm)
  2974. (define j0evencos
  2975. (let ((documentation "(make-j0evencos frequency (index 1.0)) creates a j0evencos generator. (j0evencos gen (fm 0.0))
  2976. returns a sum of cosines scaled Jk^2(index/2)."))
  2977. (lambda* (gen (fm 0.0))
  2978. (let-set! gen 'fm fm)
  2979. (with-let gen
  2980. (let ((x angle)
  2981. (dc (let ((j0 (bes-j0 (* 0.5 index))))
  2982. (* j0 j0))))
  2983. (set! angle (+ angle fm frequency))
  2984. (if (= dc 1.0)
  2985. 1.0
  2986. (/ (- (bes-j0 (* index (sin x)))
  2987. dc) ; get rid of DC component
  2988. (- 1.0 dc)))))))) ; normalize
  2989. #|
  2990. (with-sound (:clipped #f :statistics #t :play #t)
  2991. (let ((gen (make-j0evencos 100.0 1.0)))
  2992. (do ((i 0 (+ i 1)))
  2993. ((= i 30000))
  2994. (outa i (* .5 (j0evencos gen))))))
  2995. index 10 (so 10/2 is the bes-jn arg):
  2996. (let ((base (* (bes-jn 4 5.0) (bes-jn 4 5.0)))) ; max (fft norms -> 1.0)
  2997. (do ((i 1 (+ i 1)))
  2998. ((= i 11))
  2999. (format () ";~A: ~A ~A" i (* (bes-jn i 5.0) (bes-jn i 5.0)) (/ (* (bes-jn i 5.0) (bes-jn i 5.0)) base))))
  3000. ;1: 0.107308091385168 0.701072497819036
  3001. ;2: 0.00216831005396058 0.0141661502497507
  3002. ;3: 0.133101826831083 0.86958987897572
  3003. ;4: 0.153062759870046 1.0
  3004. ;5: 0.0681943848279407 0.445532178342005
  3005. ;6: 0.0171737701015899 0.112200839160164
  3006. ;7: 0.00284904116112987 0.0186135488707298
  3007. ;8: 3.38752000110201e-4 0.00221315753353599
  3008. ;9: 3.04735259399795e-5 1.99091705688911e-4
  3009. ;10: 2.15444461145164e-6 1.4075563600714e-5
  3010. (with-sound (:clipped #f :statistics #t :play #t)
  3011. (let ((gen (make-j0evencos 100.0 0.0))
  3012. (indf (make-env '(0 0 1 20) :length 30000)))
  3013. (do ((i 0 (+ i 1)))
  3014. ((= i 30000))
  3015. (set! (gen 'index) (env indf))
  3016. (outa i (* 0.5 (j0evencos gen))))))
  3017. (with-sound (:clipped #f :statistics #t :play #t)
  3018. (let ((gen (make-j0evencos 100.0 0.0))
  3019. (indf (make-env '(0 0 1 20) :length 30000))
  3020. (carrier (make-oscil 2000.0)))
  3021. (do ((i 0 (+ i 1)))
  3022. ((= i 30000))
  3023. (set! (gen 'index) (env indf))
  3024. (outa i (* 0.5 (oscil carrier) (j0evencos gen))))))
  3025. ;;; why no "carrier"? I subtracted DC out above -- to make this look right, I need to use the bes(sin) without any fixup.
  3026. (with-sound (:clipped #f :statistics #t :play #t)
  3027. (let ((gen (make-j0evencos 100.0 0.0))
  3028. (indf (make-env '(0 20 1 0) :length 30000))
  3029. (carrier (make-oscil 2000.0)))
  3030. (do ((i 0 (+ i 1)))
  3031. ((= i 30000))
  3032. (set! (gen 'index) (env indf))
  3033. (outa i (* 0.5 (j0evencos gen (oscil carrier)))))))
  3034. (with-sound (:clipped #f :statistics #t :play #t)
  3035. (let ((gen (make-j0evencos 100.0 0.0)) ; also 20 800, 20 200 (less index mvt), or 200 50
  3036. (indf (make-env '(0 10 1 0) :length 30000))
  3037. (carrier (make-oscil 2000.0)))
  3038. (do ((i 0 (+ i 1)))
  3039. ((= i 30000))
  3040. (set! (gen 'index) (env indf))
  3041. (outa i (* 0.5 (j0evencos gen (* .1 (oscil carrier))))))))
  3042. (define (j0even beg dur freq amp mc-ratio index)
  3043. (let* ((gen (make-j0evencos (* mc-ratio freq) 0.0))
  3044. (indf (make-env '(0 10 1 0) :duration dur))
  3045. (carrier (make-oscil freq))
  3046. (start (seconds->samples beg))
  3047. (end (+ start (seconds->samples dur))))
  3048. (do ((i start (+ i 1)))
  3049. ((= i end))
  3050. (set! (gen 'index) (env indf))
  3051. (outa i (* 0.5 (j0evencos gen (* index (oscil carrier))))))))
  3052. (with-sound (:clipped #f :statistics #t :play #t)
  3053. (do ((i 0 (+ i 1)))
  3054. ((= i 10))
  3055. (j0even i 1.0 2000.0 0.5 (+ .1 (* .05 i)) 0.1)))
  3056. (define* (jfm beg dur freq amp mc-ratio index (index-env '(0 1 1 1 2 0)))
  3057. (let* ((start (seconds->samples beg))
  3058. (end (+ start (seconds->samples dur)))
  3059. (md (make-j0evencos (* freq mc-ratio)))
  3060. (cr (make-oscil 2000))
  3061. (vib (make-oscil 5))
  3062. (vibamp (hz->radians (* freq .01)))
  3063. (ampf (make-env '(0 0 1 1 20 1 21 0) :scaler amp :duration dur))
  3064. (indf (make-env index-env :scaler index :duration dur)))
  3065. (do ((i start (+ i 1)))
  3066. ((= i end))
  3067. (let ((vb (* vibamp (oscil vib))))
  3068. (set! (md 'index) (env indf))
  3069. (outa i (* (env ampf)
  3070. (oscil cr vb)
  3071. (j0evencos md (* vb mc-ratio))))))))
  3072. (with-sound ("test1.snd" :play #t) (jfm 0 3.0 400.0 0.5 .5 4.0 '(0 1 1 2 2 .5)))
  3073. |#
  3074. ;;; --------------------------------------------------------------------------------
  3075. (defgenerator (j2cos
  3076. :make-wrapper (lambda (g)
  3077. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3078. (set! (g 'n) (max (g 'n) 1))
  3079. g))
  3080. (frequency *clm-default-frequency*) (r 0.5) (n 1) (angle 0.0) fm)
  3081. (define j2cos
  3082. (let ((documentation "(make-j2cos frequency (r 0.5) (n 1)) creates a j2cos generator. (j2cos gen (fm 0.0))
  3083. returns a sum of cosines scaled in a very complicated way."))
  3084. (lambda* (gen (fm 0.0))
  3085. (let-set! gen 'fm fm)
  3086. (with-let gen
  3087. (let ((rsinx2 (* 2.0 r (sin (* 0.5 angle)))))
  3088. (set! angle (+ angle fm frequency))
  3089. (if (< (abs rsinx2) nearly-zero)
  3090. 1.0
  3091. (/ (bes-jn n rsinx2)
  3092. rsinx2)))))))
  3093. ;;; this goes berserk if n=0, needs normalization, dc omission, doc/test
  3094. ;;; if n=1, sample 0 = 1, the rest are in the .5 range!
  3095. ;;; maybe j2cos isn't all that useful...
  3096. #|
  3097. (with-sound (:clipped #f :statistics #t :play #t)
  3098. (let ((gen (make-j2cos 100.0 :r 1.0 :n 0)))
  3099. (do ((i 0 (+ i 1)))
  3100. ((= i 10000))
  3101. (outa i (* .5 (j2cos gen))))))
  3102. |#
  3103. ;;; --------------------------------------------------------------------------------
  3104. (defgenerator (jpcos
  3105. :make-wrapper (lambda (g)
  3106. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3107. (if (= (g 'r) (g 'a))
  3108. (begin
  3109. (snd-warning (format #f ";jpcos r and a can't be equal (~A)" (g 'r)))
  3110. (set! (g 'r) (+ (g 'a) .01))))
  3111. g))
  3112. (frequency *clm-default-frequency*) (r 0.5) (a 0.0) (k 1.0) (angle 0.0) fm)
  3113. (define jpcos
  3114. (let ((documentation "(make-jpcos frequency (r 0.5) (a 0.0) (k 1)) creates a jpcos generator. (jpcos gen (fm 0.0))
  3115. returns a sum of cosines scaled in a very complicated way."))
  3116. (lambda* (gen (fm 0.0))
  3117. (let-set! gen 'fm fm)
  3118. (with-let gen
  3119. ;; (dc (/ (* (sin (* k a)) (sin (* k r))) (* k a r)))
  3120. ;; from P0(x)=1, J[1/2](x)=sqrt(2/(pi x))sin(x), omitting original 1/pi
  3121. ;; G&R 914 (8.464), 974 (8.912), but it's missing some remaining (small) component
  3122. ;; also omitting the original divide by (* pi (sqrt arg)) -- it's just an amplitude scaler
  3123. ;; and in this context, we get -1..1 peak amps from the sin anyway.
  3124. (let ((arg (+ (* r r)
  3125. (* a a)
  3126. (* a -2.0 r (cos angle)))))
  3127. (set! angle (+ angle fm frequency))
  3128. (if (< (abs arg) nearly-zero) ; r = a, darn it! This will produce a spike, but at least it's not a NaN
  3129. 1.0
  3130. (sin (* k (sqrt arg)))))))))
  3131. #|
  3132. (with-sound (:clipped #f :statistics #t)
  3133. (let ((gen (make-jpcos 100.0 :a 1.0 :r 0.5 :k 1)))
  3134. (do ((i 0 (+ i 1)))
  3135. ((= i 210000))
  3136. (outa i (jpcos gen)))))
  3137. (with-sound (:clipped #f :statistics #t)
  3138. (let* ((gen (make-jpcos 400.0 :a 1.0 :r 0.5 :k 10))
  3139. (dur 1.0)
  3140. (samps (seconds->samples dur))
  3141. (ampf (make-env '(0 0 1 1 10 1 11 0) :duration dur :scaler 0.5))
  3142. (indf (make-env '(0 0 1 1) :duration dur :scaler 1.0)))
  3143. (do ((i 0 (+ i 1)))
  3144. ((= i samps))
  3145. (set! (gen 'r) (env indf))
  3146. (outa i (* (env ampf)
  3147. (jpcos gen))))))
  3148. ;;; -.725, 1/.275
  3149. (with-sound (:clipped #f :scaled-to .5)
  3150. (let* ((gen (make-oscil 100.0)))
  3151. (do ((i 0 (+ i 1)))
  3152. ((= i 44100))
  3153. (outa i (sqrt (+ 1.0 (oscil gen)))))))
  3154. (with-sound (:clipped #f :scaled-to .5)
  3155. (let* ((gen (make-oscil 100.0))
  3156. (indf (make-env '(0 .1 1 .9) :length 44100)))
  3157. (do ((i 0 (+ i 1)))
  3158. ((= i 44100))
  3159. (let ((ind (env indf)))
  3160. (outa i (sqrt (+ (* 1.0 1.0) (* ind ind) (* -2 1.0 ind (oscil gen)))))))))
  3161. ;;; rkcos r=.4 or so (.6?), so rkcos+indf is mostly equivalent? (k=scaler in both)
  3162. (with-sound (:clipped #f :statistics #t :play #t)
  3163. (let ((gen (make-rkcos 440.0 :r 0.6))
  3164. (gen1 (make-oscil 440.0))
  3165. (indf (make-env '(0 .1 1 .8) :length 50000)))
  3166. (do ((i 0 (+ i 1)))
  3167. ((= i 50000))
  3168. (set! (gen 'r) (env indf))
  3169. (outa i (oscil gen1 (* (gen 'r) (rkcos gen)))))))
  3170. |#
  3171. ;;; --------------------------------------------------------------------------------
  3172. (defgenerator (jncos :make-wrapper (lambda (g)
  3173. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3174. (set! (g 'ra) (+ (* (g 'a) (g 'a)) (* (g 'r) (g 'r))))
  3175. g))
  3176. (frequency *clm-default-frequency*) (r 0.5) (a 1.0) (n 0) (angle 0.0) ra fm)
  3177. (define jncos
  3178. (let ((documentation "(make-jncos frequency (r 0.5) (a 1.0) (n 0)) creates a jncos generator. (jncos gen (fm 0.0))
  3179. returns a sum of cosines scaled in a very complicated way."))
  3180. (lambda* (gen (fm 0.0))
  3181. (let-set! gen 'fm fm)
  3182. (with-let gen
  3183. (let ((arg (sqrt (+ ra (* a -2.0 r (cos angle))))))
  3184. (set! angle (+ angle fm frequency))
  3185. (if (< arg nearly-zero)
  3186. 1.0
  3187. (/ (bes-jn n arg)
  3188. (expt arg n))))))))
  3189. #|
  3190. (with-sound (:clipped #f :statistics #t :play #t)
  3191. (let ((gen (make-jncos 100.0 :a 0.5 :r 1.0 :n 0)))
  3192. (do ((i 0 (+ i 1)))
  3193. ((= i 41000))
  3194. (outa i (jncos gen)))))
  3195. |#
  3196. ;;; --------------------------------------------------------------------------------
  3197. ;;; use J0(cos)+J1(cos) to get full spectrum
  3198. (defgenerator (j0j1cos
  3199. :make-wrapper (lambda (g)
  3200. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3201. g))
  3202. (frequency *clm-default-frequency*) (index 1.0) (angle 0.0) fm)
  3203. (define j0j1cos
  3204. (let ((documentation "(make-j0j1cos frequency (index 1.0)) creates a j0j1cos generator. (j0j1cos gen (fm 0.0))
  3205. returns a sum of cosines scaled in a very complicated way."))
  3206. (lambda* (gen (fm 0.0))
  3207. (let-set! gen 'fm fm)
  3208. (with-let gen
  3209. (let ((dc (let ((j0 (bes-j0 (* 0.5 index))))
  3210. (* j0 j0)))
  3211. (arg (* index (cos angle))))
  3212. (set! angle (+ angle fm frequency))
  3213. (/ (- (+ (bes-j0 arg)
  3214. (bes-j1 arg))
  3215. dc) ; get rid of DC component
  3216. 1.215)))))) ; not the best...
  3217. ; need to normalize j0j1cos -- min depends on index, so peak depends on max and min and dc
  3218. ; (max (- 1.2154 dc)
  3219. ; (- -0.5530 dc)
  3220. #|
  3221. (let ((mx 0.0) (x 0.0) (saved-x 0.0))
  3222. (do ((i 0 (+ i 1)))
  3223. ((= i 1000))
  3224. (let ((val (+ (bes-j0 x) (bes-j1 x))))
  3225. (if (> (abs val) mx)
  3226. (begin
  3227. (set! mx (abs val))
  3228. (set! saved-x x)))
  3229. (set! x (+ x .001))))
  3230. (list mx saved-x))
  3231. (1.21533317877749 0.825000000000001)
  3232. (1.21533318495717 0.824863000002882)
  3233. (1.21533318495718 0.824863061409846)
  3234. (-0.552933995255066 4.57000000000269)
  3235. (-0.552933995483144 4.56997100028488)
  3236. (do ((i 0 (+ i 1)))
  3237. ((= i 10))
  3238. (let ((pk (maxamp
  3239. (with-sound ((make-float-vector 10000))
  3240. (let ((gen (make-j0j1cos 100.0 i)))
  3241. (do ((i 0 (+ i 1)))
  3242. ((= i 10000))
  3243. (outa i (j0j1cos gen))))))))
  3244. (format () ";~A: ~A" i pk)))
  3245. ;0: 0.0
  3246. ;1: 0.555559098720551
  3247. ;2: 0.938335597515106
  3248. ;3: 0.953315675258636
  3249. ;4: 1.16509592533112
  3250. ;5: 1.21275520324707
  3251. ;6: 1.14727067947388
  3252. ;7: 1.07083106040955
  3253. ;8: 1.05760526657104
  3254. ;9: 1.11238932609558
  3255. ;10: 1.1824289560318
  3256. ;11: 1.21528387069702
  3257. ;12: 1.19094204902649
  3258. ;13: 1.14720714092255
  3259. ;14: 1.12512302398682
  3260. |#
  3261. #|
  3262. (with-sound (:clipped #f :statistics #t :play #t)
  3263. (let ((gen (make-j0j1cos 100.0 1.0)))
  3264. (do ((i 0 (+ i 1)))
  3265. ((= i 30000))
  3266. (outa i (j0j1cos gen)))))
  3267. |#
  3268. ;;; --------------------------------------------------------------------------------
  3269. (defgenerator (jycos
  3270. :make-wrapper (lambda (g)
  3271. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3272. (set! (g 'r) (max .0001 (g 'r))) ; 0->inf in bes-y0
  3273. (let ((a (g 'a)) ; "c"
  3274. (r (g 'r))); "b"
  3275. (if (<= r a)
  3276. (format () ";jycos a: ~A must be < r: ~A" a r))
  3277. (if (<= (+ (* a a) (* r r)) (* 2 a r))
  3278. (format () ";jycos a: ~A, r: ~A will cause bes-y0 to return -inf!" a r)))
  3279. g))
  3280. (frequency *clm-default-frequency*) (r 1.0) (a 0.5) ; "b" and "c" in the docs
  3281. (angle 0.0) fm)
  3282. (define jycos
  3283. (let ((documentation "(make-jycos frequency (r 1.0) (a 0.5)) creates a jycos generator. (jycos gen (fm 0.0))
  3284. returns a sum of cosines scaled by Yn(r)*Jn(r)."))
  3285. (lambda* (gen (fm 0.0))
  3286. (let-set! gen 'fm fm)
  3287. (with-let gen
  3288. (let ((x angle)
  3289. (b2c2 (+ (* r r) (* a a)))
  3290. (dc (* (bes-y0 r) (bes-j0 a))))
  3291. (let ((norm (abs (- (bes-y0 (sqrt (+ b2c2 (* -2 r a)))) dc))))
  3292. (set! angle (+ angle fm frequency))
  3293. (/ (- (bes-y0 (sqrt (+ b2c2 (* -2.0 r a (cos x))))) dc) norm)))))))
  3294. ;;; oops -- bes-y0(0) is -inf!
  3295. ;;; norm only works for "reasonable" a and r
  3296. #|
  3297. (with-sound (:clipped #f :statistics #t :play #f)
  3298. (let ((gen (make-jycos 100.0 1.5 1.0))
  3299. (af (make-env '(0 0 1 1) :length 30000))
  3300. (rf (make-env '(0 3 1 3) :length 30000))
  3301. (ampf (make-env '(0 0 1 1 10 1 11 0) :scaler 0.5 :length 30000)))
  3302. (do ((i 0 (+ i 1)))
  3303. ((= i 30000))
  3304. (set! (gen 'a) (env af))
  3305. (set! (gen 'r) (env rf))
  3306. (outa i (* (env ampf)
  3307. (jycos gen))))))
  3308. :(* (bes-yn 1 1.5) (bes-jn 1 1.0))
  3309. -0.181436652807559
  3310. :(* (bes-yn 2 1.5) (bes-jn 2 1.0))
  3311. -0.107112311628537
  3312. :(* (bes-yn 3 1.5) (bes-jn 3 1.0))
  3313. -0.0405654243875417
  3314. :(/ .107 .181)
  3315. 0.591160220994475 [0.600]
  3316. :(/ .040 .181)
  3317. 0.220994475138122 [0.228]
  3318. |#
  3319. ;;; --------------------------------------------------------------------------------
  3320. #|
  3321. (defgenerator (jcos
  3322. :make-wrapper (lambda (g)
  3323. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3324. g))
  3325. (frequency *clm-default-frequency*) (n 0) (r 1.0) (a 0.5) ; "b" and "c" in the docs
  3326. (angle 0.0) fm)
  3327. (define jcos
  3328. (let ((documentation "(make-jcos frequency (n 0) (r 1.0) (a 0.5)) creates a jcos generator. (jcos gen (fm 0.0))
  3329. returns a sum of cosines scaled in some complex manner."))
  3330. (lambda* (gen (fm 0.0))
  3331. (let-set! gen 'fm fm)
  3332. (with-let gen
  3333. (let* ((x angle)
  3334. (b r)
  3335. (c a)
  3336. (dc (* (bes-j0 b) (bes-j0 c))))
  3337. (set! angle (+ angle fm frequency))
  3338. (- (bes-jn n (* (+ n 1) (sqrt (+ (* b b) (* c c) (* -2.0 b c (cos x))))))
  3339. dc))))))
  3340. (with-sound (:clipped #f :statistics #t :play #t)
  3341. (let ((gen (make-jcos 100.0 0 1.0 1.0)))
  3342. (do ((i 0 (+ i 1)))
  3343. ((= i 30000))
  3344. (outa i (jcos gen)))))
  3345. |#
  3346. ;;; --------------------------------------------------------------------------------
  3347. #|
  3348. (defgenerator (sin2n
  3349. :make-wrapper (lambda (g)
  3350. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3351. g))
  3352. (frequency *clm-default-frequency*) (n 1) (r 1.0) (angle 0.0) fm)
  3353. (define sin2n
  3354. (let ((documentation "(make-sin2n frequency (n 0) (r 1.0)) creates a sin2n generator. (sin2n gen (fm 0.0)) returns (r*sin)^(2n)"))
  3355. (lambda* (gen (fm 0.0))
  3356. (let-set! gen 'fm fm)
  3357. (with-let gen
  3358. (let* ((x angle))
  3359. (set! angle (+ angle fm frequency))
  3360. (expt (* r (sin x)) (* 2 n)))))))
  3361. (with-sound (:clipped #f :statistics #t :play #t)
  3362. (let ((gen (make-sin2n 100.0 2 1.0)))
  3363. (do ((i 0 (+ i 1)))
  3364. ((= i 30000))
  3365. (outa i (sin2n gen)))))
  3366. |#
  3367. ;;; --------------------------------------------------------------------------------
  3368. #|
  3369. ;;; do we need modulo 2*pi for the angles? (it is not used in clm.c)
  3370. :(let ((ph 0.0)) (do ((i 0 (+ i 1))) ((= i 22050)) (set! ph (+ ph (hz->radians 100.0)))) ph)
  3371. 628.31850751536
  3372. :(let ((ph (* 2 pi 1000000))) (do ((i 0 (+ i 1))) ((= i 22050)) (set! ph (+ ph (hz->radians 100.0)))) (- ph (* 2 pi 1000000)))
  3373. 628.318502381444
  3374. :(let ((ph (* 2 pi 1000000000))) (do ((i 0 (+ i 1))) ((= i 22050)) (set! ph (+ ph (hz->radians 100.0)))) (- ph (* 2 pi 1000000000)))
  3375. 628.311109542847
  3376. :(let ((ph (* 2 pi 1000000000000))) (do ((i 0 (+ i 1))) ((= i 22050)) (set! ph (+ ph (hz->radians 100.0)))) (- ph (* 2 pi 1000000000000)))
  3377. 624.462890625
  3378. ;; similar results from running oscil with 0.0 initial-phase, and 2*pi*1000000000, or running one
  3379. ;; oscil for 3 hours at 6000 Hz -- the sinusoid is clean even around an angle of a billion -- worst
  3380. ;; case increment is pi, so we get (say) a billion samples before we may notice a sag => ca. 8 hours.
  3381. ;; I think that's a long enough tone... (In clm.c and here, the phase and increment are both doubles;
  3382. ;; 53 bits of mantissa, billion=30, so we still have about 23 bits, which actually matches results above).
  3383. |#
  3384. ;;; --------------------------------------------------------------------------------
  3385. ;;; blackman as a waveform -- all the other fft windows could be implemented
  3386. ;;; perhaps most useful as an amplitude envelope
  3387. #|
  3388. (defgenerator (blackman
  3389. :make-wrapper (lambda (g)
  3390. (let ((n (g 'n)))
  3391. (set! n (min (max n 1) 10))
  3392. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3393. (case n
  3394. ((1) (set! (g 'coeffs) (float-vector 0.54 -0.46)))
  3395. ((2) (set! (g 'coeffs) (float-vector 0.34401 -0.49755 0.15844)))
  3396. ((3) (set! (g 'coeffs) (float-vector 0.21747 -0.45325 0.28256 -0.04672)))
  3397. ((4) (set! (g 'coeffs) (float-vector 0.084037 -0.29145 0.375696 -0.20762 0.041194)))
  3398. ((5) (set! (g 'coeffs) (float-vector 0.097167 -0.3088448 0.3626224 -0.1889530 0.04020952 -0.0022008)))
  3399. ((6) (set! (g 'coeffs) (float-vector 0.063964353 -0.239938736 0.3501594961 -0.247740954 0.0854382589
  3400. -0.012320203 0.0004377882)))
  3401. ((7) (set! (g 'coeffs) (float-vector 0.04210723 -0.18207621 0.3177137375 -0.284437984 0.1367622316
  3402. -0.033403806 0.0034167722 -0.000081965)))
  3403. ((8) (set! (g 'coeffs) (float-vector 0.027614462 -0.135382235 0.2752871215 -0.298843294 0.1853193194
  3404. -0.064888448 0.0117641902 -0.000885987 0.0000148711)))
  3405. ((9) (set! (g 'coeffs) (float-vector 0.01799071953 -0.098795950 0.2298837751 -0.294112951 0.2243389785
  3406. -0.103248745 0.0275674108 -0.003839580 0.0002189716 -0.000002630)))
  3407. ((10) (set! (g 'coeffs) (float-vector 0.0118717384 -0.071953468 0.1878870875 -0.275808066 0.2489042133
  3408. -0.141729787 0.0502002984 -0.010458985 0.0011361511 -0.000049617
  3409. 0.0000004343))))
  3410. g))
  3411. :methods (list
  3412. (cons 'mus-reset
  3413. (lambda (g)
  3414. (set! (g 'angle) 0.0)))))
  3415. (frequency *clm-default-frequency*) (n 4) (coeffs #f) (angle 0.0) fm)
  3416. (define blackman
  3417. (let ((documentation "(make-blackman frequency (n 4)) creates a blackman generator. (blackman gen (fm 0.0))
  3418. returns the nth Blackman-Harris fft data window as a periodic waveform. (n <= 10)"))
  3419. (lambda* (gen (fm 0.0))
  3420. (let-set! gen 'fm fm)
  3421. (with-let gen
  3422. (let ((x angle))
  3423. (set! angle (+ angle fm frequency))
  3424. (polynomial coeffs (cos x)))))))
  3425. |#
  3426. #|
  3427. (with-sound (:clipped #f :statistics #t :play #t)
  3428. (let ((black4 (make-blackman 440.0)))
  3429. (do ((i 0 (+ i 1)))
  3430. ((= i 20000))
  3431. (outa i (blackman black4 0.0)))))
  3432. |#
  3433. ;;; but that is the same as polyshape/polywave!
  3434. (define blackman polywave)
  3435. (define blackman? polywave?)
  3436. (define* (make-blackman (frequency 440.0) (n 4))
  3437. (make-polywave frequency
  3438. (case n
  3439. ;; this data is from clm.c
  3440. ((0) (list 0 0))
  3441. ((1) (list 0 0.54 1 -0.46))
  3442. ((2) (list 0 0.42323 1 -0.49755 2 0.078279))
  3443. ((3) (list 0 0.35875 1 0.48829 2 0.14128 3 -0.01168))
  3444. ((4) (list 0 0.287333 1 -0.44716 2 0.20844 3 -0.05190 4 0.005149))
  3445. ((5) (list 0 .293557 1 -.451935 2 .201416 3 -.047926 4 .00502619 5 -.000137555))
  3446. ((6) (list 0 .2712203 1 -.4334446 2 .2180041 3 -.0657853 4 .010761867 5 -.0007700127 6 .00001368088))
  3447. ((7) (list 0 .2533176 1 -.4163269 2 .2288396 3 -.08157508 4 .017735924 5 -.0020967027 6 .00010677413 7 -.0000012807))
  3448. ((8) (list 0 .2384331 1 -.4005545 2 .2358242 3 -.09527918 4 .025373955 5 -.0041524329 6 .00036856041 7 -.00001384355 8 .0000001161808))
  3449. ((9) (list 0 .2257345 1 -.3860122 2 .2401294 3 -.1070542 4 .03325916 5 -.00687337
  3450. 6 .0008751673 7 -.0000600859 8 .000001710716 9 -.00000001027272))
  3451. ((10) (list 0 .2151527 1 -.3731348 2 .2424243 3 -.1166907 4 .04077422 5 -.01000904
  3452. 6 .0016398069 7 -.0001651660 8 .000008884663 9 -.000000193817 10 .00000000084824)))))
  3453. ;;; --------------------------------------------------------------------------------
  3454. ;;; we can add the sin(cos) and sin(sin) cases, using -index in the latter to get
  3455. ;;; asymmetric fm since Jn(-B) = (-1)^n Jn(B)
  3456. ;;;
  3457. ;;; the same trick would work in the other two cases -- gapped spectra
  3458. (defgenerator (fmssb
  3459. :make-wrapper (lambda (g)
  3460. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3461. g))
  3462. (frequency *clm-default-frequency*) (ratio 1.0) (index 1.0) (angle 0.0) fm)
  3463. (define fmssb
  3464. (let ((documentation "(make-fmssb frequency (ratio 1.0) (index 1.0)) creates an fmssb generator. (fmssb gen (fm 0.0)) returns single-sideband FM."))
  3465. (lambda* (gen (fm 0.0))
  3466. (let-set! gen 'fm fm)
  3467. (with-let gen
  3468. (let* ((cx angle)
  3469. (mx (* cx ratio)))
  3470. (set! angle (+ angle fm frequency))
  3471. (- (* (cos cx)
  3472. (sin (* index (cos mx))))
  3473. (* (sin cx)
  3474. (sin (* index (sin mx)))))))))) ; use -index for the other side
  3475. ;;; FM with complex index
  3476. (define* (fpmc beg dur freq amp mc-ratio fm-index interp)
  3477. (let ((start (seconds->samples beg)))
  3478. (let ((end (+ start (seconds->samples dur)))
  3479. (cr 0.0)
  3480. (cr-frequency (hz->radians freq))
  3481. (md-frequency (hz->radians (* freq mc-ratio)))
  3482. (md 0.0))
  3483. (do ((i start (+ i 1)))
  3484. ((= i end))
  3485. (let ((val (sin (+ cr (* fm-index (sin md))))))
  3486. (outa i (* amp (+ (* (- 1.0 interp) (real-part val))
  3487. (* interp (imag-part val)))))
  3488. (set! cr (+ cr cr-frequency))
  3489. (set! md (+ md md-frequency)))))))
  3490. #|
  3491. (with-sound (:clipped #f :statistics #t :play #t)
  3492. (let ((gen (make-fmssb 1000.0 0.1 :index 8.0))) ; 1 3 7 11 ... -- interesting effect
  3493. (do ((i 0 (+ i 1)))
  3494. ((= i 10000))
  3495. (outa i (* .3 (fmssb gen))))))
  3496. (with-sound (:clipped #f :statistics #t :play #t)
  3497. (let ((gen (make-fmssb 1000.0 0.1 :index 8.0))
  3498. (ampf (make-env '(0 0 1 1 100 0) :base 32 :scaler .3 :length 30000))
  3499. (indf (make-env '(0 1 1 0) :length 30000 :scaler 8)))
  3500. (do ((i 0 (+ i 1)))
  3501. ((= i 30000))
  3502. (set! (gen 'index) (env indf))
  3503. (outa i (* (env ampf) (fmssb gen))))))
  3504. (with-sound (:clipped #f :statistics #t :play #t)
  3505. (let ((gen (make-fmssb 1000.0 0.05 :index 1.0))
  3506. (ampf (make-env '(0 0 1 1 100 0) :base 32 :scaler .3 :length 30000))
  3507. (indf (make-env '(0 1 1 0) :length 30000 :base 32 :scaler 10)))
  3508. (do ((i 0 (+ i 1)))
  3509. ((= i 30000))
  3510. (set! (gen 'index) (env indf))
  3511. (outa i (* (env ampf) (fmssb gen))))))
  3512. (with-sound (:clipped #f :statistics #t :play #t)
  3513. (let ((gen (make-fmssb 100.0 5.4 :index 1.0)) ; also 100 700
  3514. (ampf (make-env '(0 0 1 1 100 0) :base 32 :scaler .3 :length 30000)) ; also 0 0 1 1 3 1 100 0...
  3515. ;; '(0 0 1 .75 2 1 3 .95 4 .5 10 0) -> bowed effect, '(0 0 1 .75 2 1 3 .125 4 .25 5 1 6 .8 20 0)
  3516. ;; '(0 0 1 .75 2 1 3 .1 4 .7 5 1 6 .8 100 0) -> clickier attack (300 too)
  3517. (indf (make-env '(0 1 1 0) :length 30000 :base 32 :scaler 10)))
  3518. ;; '(0 0 1 1 3 0)
  3519. (do ((i 0 (+ i 1)))
  3520. ((= i 30000))
  3521. (set! (gen 'index) (env indf))
  3522. (outa i (* (env ampf) (fmssb gen))))))
  3523. (with-sound (:clipped #f :statistics #t :play #t)
  3524. (let ((gen (make-fmssb 10.0 2.0 :index 1.0))
  3525. (ampf (make-env '(0 0 1 1 3 1 100 0) :base 32 :scaler .3 :length 30000))
  3526. (indf (make-env '(0 1 1 0) :length 30000 :base 32 :scaler 10)))
  3527. (do ((i 0 (+ i 1)))
  3528. ((= i 30000))
  3529. (set! (gen 'index) (env indf))
  3530. (outa i (* (env ampf) (fmssb gen))))))
  3531. (with-sound (:statistics #t :scaled-to .5 :play #t)
  3532. (let ((gen1 (make-fmssb 500 1))
  3533. (gen2 (make-fmssb 1000 .2))
  3534. (ampf (make-env '(0 0 1 1 100 0) :base 32 :length 30000))
  3535. (indf (make-env '(0 1 1 1 10 0) :scaler 5.0 :base 32 :length 30000)))
  3536. (do ((i 0 (+ i 1)))
  3537. ((= i 30000))
  3538. (let ((ind (env indf)))
  3539. (set! (gen1 'index) ind)
  3540. (set! (gen2 'index) ind)
  3541. (outa i (* (env ampf)
  3542. (+ (fmssb gen1 0.0)
  3543. (fmssb gen2 0.0))))))))
  3544. ;;; imaginary machines (also imaginary beasts)
  3545. |#
  3546. (definstrument (machine1 beg dur cfreq mfreq amp index gliss)
  3547. (let ((gen (make-fmssb cfreq (/ mfreq cfreq) :index 1.0))
  3548. (start (seconds->samples beg))
  3549. (stop (seconds->samples (+ beg dur)))
  3550. (ampf (make-env '(0 0 1 .75 2 1 3 .1 4 .7 5 1 6 .8 100 0) :base 32 :scaler amp :duration dur))
  3551. (indf (make-env '(0 0 1 1 3 0) :duration dur :base 32 :scaler index))
  3552. (frqf (make-env (if (> gliss 0.0) '(0 0 1 1) '(0 1 1 0)) :duration dur :scaler (hz->radians (* (/ cfreq mfreq) (abs gliss))))))
  3553. (do ((i start (+ i 1)))
  3554. ((= i stop))
  3555. (set! (gen 'index) (env indf))
  3556. (outa i (* (env ampf) (fmssb gen (env frqf)))))))
  3557. #|
  3558. (with-sound (:statistics #t :play #t)
  3559. (do ((i 0.0 (+ i .5)))
  3560. ((>= i 2.0))
  3561. (machine1 i .3 100 540 0.5 3.0 0.0)
  3562. (machine1 i .1 100 1200 .5 10.0 200.0)
  3563. (machine1 i .3 100 50 .75 10.0 0.0)
  3564. (machine1 (+ i .1) .1 100 1200 .5 20.0 1200.0)
  3565. (machine1 (+ i .3) .1 100 1200 .5 20.0 1200.0)
  3566. (machine1 (+ i .3) .1 100 200 .5 10.0 200.0)
  3567. (machine1 (+ i .36) .1 100 200 .5 10.0 200.0)
  3568. (machine1 (+ i .4) .1 400 300 .5 10.0 -900.0)
  3569. (machine1 (+ i .4) .21 100 50 .75 10.0 1000.0)
  3570. ))
  3571. (with-sound (:statistics #t :play #t)
  3572. (do ((i 0.0 (+ i .2)))
  3573. ((>= i 2.0))
  3574. (machine1 i .3 100 540 0.5 4.0 0.0)
  3575. (machine1 (+ i .1) .3 200 540 0.5 3.0 0.0))
  3576. (do ((i 0.0 (+ i .6)))
  3577. ((>= i 2.0))
  3578. (machine1 i .3 1000 540 0.5 6.0 0.0)
  3579. (machine1 (+ i .1) .1 2000 540 0.5 1.0 0.0)
  3580. ))
  3581. (with-sound (:statistics #t :play #t :scaled-to .5)
  3582. (let ((gen (make-rkoddssb 1000.0 2.0 0.875))
  3583. (noi (make-rand 15000 .02))
  3584. (gen1 (make-rkoddssb 100.0 0.1 0.9))
  3585. (ampf (make-env '(0 0 1 1 11 1 12 0) :duration 11.0 :scaler .5))
  3586. (frqf (make-env '(0 0 1 1 2 0 10 0 11 1 12 0 20 0) :duration 11.0 :scaler (hz->radians 10.0))))
  3587. (do ((i 0 (+ i 1)))
  3588. ((= i (* 12 44100)))
  3589. (outa i (* (env ampf)
  3590. (+ (rkoddssb gen1 (env frqf))
  3591. (* .2 (sin (rkoddssb gen (rand noi)))))))))
  3592. (do ((i 0.0 (+ i 2)))
  3593. ((>= i 10.0))
  3594. (machine1 i 3 100 700 0.5 4.0 0.0)
  3595. (machine1 (+ i 1) 3 200 700 0.5 3.0 0.0))
  3596. (do ((i 0.0 (+ i 6)))
  3597. ((>= i 10.0))
  3598. (machine1 i 3 1000 540 0.5 6.0 0.0)
  3599. (machine1 (+ i 1) 1 2000 540 0.5 1.0 0.0)
  3600. ))
  3601. (with-sound (:statistics #t :play #t)
  3602. (do ((i 0.0 (+ i .2)))
  3603. ((>= i 2.0))
  3604. (machine1 i .3 1200 540 0.5 40.0 0.0)
  3605. (machine1 (+ i .1) .3 2400 540 0.5 3.0 0.0))
  3606. (do ((i 0.0 (+ i .6)))
  3607. ((>= i 2.0))
  3608. (machine1 i .3 1000 540 0.5 6.0 0.0)
  3609. (machine1 (+ i .1) .1 2000 540 0.5 10.0 100.0)
  3610. ))
  3611. ;;; same as above but up octave
  3612. (with-sound (:statistics #t :play #t)
  3613. (do ((i 0.0 (+ i .1)))
  3614. ((>= i 2.0))
  3615. (machine1 i .15 2400 1080 0.25 40.0 0.0)
  3616. (machine1 (+ i .05) .2 4800 1080 0.5 3.0 0.0))
  3617. (do ((i 0.0 (+ i .3)))
  3618. ((>= i 2.0))
  3619. (machine1 i .15 2000 1080 0.5 6.0 0.0)
  3620. (machine1 (+ i .05) .1 4000 1080 0.5 10.0 100.0)
  3621. ))
  3622. |#
  3623. (define (fm-cancellation beg dur frequency ratio amp index)
  3624. (let ((start (seconds->samples beg)))
  3625. (let ((cx 0.0)
  3626. (mx 0.0)
  3627. (car-frequency (hz->radians frequency))
  3628. (mod-frequency (hz->radians ratio))
  3629. (stop (+ start (seconds->samples dur))))
  3630. (do ((i start (+ i 1)))
  3631. ((= i stop))
  3632. (outa i (* amp (- (* (cos cx)
  3633. (sin (* index (cos mx))))
  3634. (* (sin cx)
  3635. (sin (* index (sin mx))))))
  3636. ;; use -index for reflection
  3637. )
  3638. (set! cx (+ cx car-frequency))
  3639. (set! mx (+ mx mod-frequency))))))
  3640. ;(with-sound () (fm-cancellation 0 1 1000.0 100.0 0.3 9.0))
  3641. ;;; --------------------------------------------------------------------------------
  3642. ;;; k3sin
  3643. (define k3sin-methods
  3644. (list
  3645. (cons 'mus-reset
  3646. (lambda (g)
  3647. (set! (g 'frequency) 0.0)
  3648. (set! (g 'angle) 0.0)))))
  3649. (defgenerator (k3sin
  3650. :make-wrapper (lambda (g)
  3651. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3652. (set! (g 'coeffs) (float-vector 0.0
  3653. (/ (* pi pi) 6.0)
  3654. (/ pi -4.0)
  3655. 0.08333)) ; (/ 12.0)
  3656. g)
  3657. :methods k3sin-methods)
  3658. (frequency *clm-default-frequency*) (angle 0.0) (coeffs #f) fm)
  3659. (define k3sin
  3660. (let ((documentation "(make-k3sin frequency) creates a k3sin generator. (k3sin gen (fm 0.0)) returns a sum of sines scaled by k^3."))
  3661. (lambda* (gen (fm 0.0))
  3662. (let-set! gen 'fm fm)
  3663. (with-let gen
  3664. (let ((x angle))
  3665. (if (not (<= 0.0 x two-pi))
  3666. (set! x (modulo x two-pi)))
  3667. (set! angle (+ x fm frequency))
  3668. (polynomial coeffs x))))))
  3669. #|
  3670. (with-sound (:clipped #f :statistics #t :play #t)
  3671. (let ((gen (make-k3sin 100.0)))
  3672. (do ((i 0 (+ i 1)))
  3673. ((= i 30000))
  3674. (outa i (k3sin gen)))))
  3675. |#
  3676. ;;; --------------------------------------------------------------------------------
  3677. ;;; I(z) case A&S
  3678. (define izcos-methods
  3679. (list
  3680. (cons 'mus-scaler
  3681. (dilambda
  3682. (lambda (g) (g 'r))
  3683. (lambda (g val)
  3684. (set! (g 'r) val)
  3685. (set! (g 'dc) (bes-i0 val))
  3686. (set! (g 'norm) (- (exp val) (g 'dc)))
  3687. (set! (g 'inorm) (/ (g 'norm)))
  3688. val)))))
  3689. (defgenerator (izcos
  3690. :make-wrapper (lambda (g)
  3691. (set! (g 'frequency) (hz->radians (g 'frequency)))
  3692. (set! (g 'dc) (bes-i0 (g 'r)))
  3693. (set! (g 'norm) (- (exp (g 'r)) (g 'dc)))
  3694. (set! (g 'inorm) (/ (g 'norm)))
  3695. g)
  3696. :methods izcos-methods)
  3697. (frequency *clm-default-frequency*) (r 1.0) (angle 0.0)
  3698. (dc 0.0) (norm 1.0) inorm fm)
  3699. (define izcos
  3700. (let ((documentation "(make-izcos frequency (r 1.0)) creates an izcos generator. (izcos gen (fm 0.0)) returns a sum of sines scaled by In(r)."))
  3701. (lambda* (gen (fm 0.0))
  3702. (let-set! gen 'fm fm)
  3703. (with-let gen
  3704. (let ((x angle))
  3705. (set! angle (+ angle fm frequency))
  3706. (if (< (abs norm) nearly-zero)
  3707. 1.0
  3708. (* (- (exp (* r (cos x))) dc) inorm)))))))
  3709. #|
  3710. (with-sound (:clipped #f :statistics #t :play #t)
  3711. (let ((gen (make-izcos 100.0 1.0)))
  3712. (do ((i 0 (+ i 1)))
  3713. ((= i 30000))
  3714. (outa i (* .5 (izcos gen))))))
  3715. (with-sound (:clipped #f :statistics #t)
  3716. (let ((gen (make-izcos 100.0 1.0))
  3717. (indf (make-env '(0 0 1 3) :length 30000)))
  3718. (do ((i 0 (+ i 1)))
  3719. ((= i 30000))
  3720. (set! (mus-scaler gen) (env indf))
  3721. (outa i (izcos gen)))))
  3722. |#
  3723. ;;; --------------------------------------------------------------------------------
  3724. (definstrument (organish beg dur freq amp fm-index amp-env)
  3725. ;; this has an organ-style chiff (better than fm index sweep)
  3726. (let ((start (seconds->samples beg))
  3727. (carriers (make-vector 3 #f))
  3728. (fmoscs (make-vector 3 #f))
  3729. (ampfs (make-vector 3 #f))
  3730. (pervib (make-triangle-wave 5 (hz->radians (* freq .003))))
  3731. (ranvib (make-rand-interp 6 (hz->radians (* freq .002))))
  3732. (resc (make-nrssb 340.0 1.0 5 .5))
  3733. (resf (make-env (list 0 0 .05 1 .1 0 dur 0) :scaler (* amp .05) :duration dur)))
  3734. (let ((stop (+ start (seconds->samples dur))))
  3735. (do ((i 0 (+ i 1)))
  3736. ((= i 3))
  3737. (let ((frq (* freq (expt 2 i))))
  3738. (let ((index1 (hz->radians (/ (* fm-index frq 5.0) (log frq))))
  3739. (index2 (hz->radians (/ (* fm-index frq 3.0 (- 8.5 (log frq))) (+ 3.0 (* frq 0.001)))))
  3740. (index3 (hz->radians (/ (* fm-index frq 4.0) (sqrt frq)))))
  3741. (set! (carriers i) (make-oscil frq))
  3742. (set! (fmoscs i) (make-polywave frq
  3743. :partials (list 1 index1
  3744. 3 index2
  3745. 4 index3))))))
  3746. (set! (ampfs 0) (make-env (or amp-env '(0 0 1 1 2 1 3 0)) :scaler amp :duration dur))
  3747. (set! (ampfs 1) (make-env (list 0 0 .04 1 .075 0 dur 0) :scaler (* amp .0125) :duration dur))
  3748. (set! (ampfs 2) (make-env (list 0 0 .02 1 .05 0 dur 0) :scaler (* amp .025) :duration dur))
  3749. ;; also good:
  3750. ;; (set! (ampfs 1) (make-env (list 0 0 .02 1 .05 0 (- dur .1) 0 (- dur .05) 1 dur 0) :scaler (* amp .025) :duration dur))
  3751. ;; (set! (ampfs 2) (make-env (list 0 0 .01 1 .025 0 (- dur .15) 0 (- dur .1) 1 dur 0) :scaler (* amp .05) :duration dur))
  3752. (do ((i start (+ i 1)))
  3753. ((= i stop))
  3754. (let ((vib (+ (triangle-wave pervib) (rand-interp ranvib))))
  3755. (outa i (+ (* (env resf) (nrssb resc 0.0))
  3756. (* (env (vector-ref ampfs 0))
  3757. (oscil (vector-ref carriers 0)
  3758. (+ vib (polywave (vector-ref fmoscs 0) vib))))
  3759. (* (env (vector-ref ampfs 1))
  3760. (oscil (vector-ref carriers 1)
  3761. (+ (* 2 vib) (polywave (vector-ref fmoscs 1) (* 2 vib)))))
  3762. (* (env (vector-ref ampfs 2))
  3763. (oscil (vector-ref carriers 2)
  3764. (+ (* 4 vib) (polywave (vector-ref fmoscs 2) (* 4 vib))))))))))))
  3765. #|
  3766. (with-sound (:clipped #f :statistics #t :play #t)
  3767. (do ((i 0 (+ i 1)))
  3768. ((= i 10))
  3769. (organish (* i .3) .4 (+ 100 (* 50 i)) .5 1.0 #f)))
  3770. (with-sound (:clipped #f :statistics #t :play #t)
  3771. (do ((i 0 (+ i 1)))
  3772. ((= i 10))
  3773. (organish (* i .3) .4 (+ 100 (* 50 i)) .5 1.0 '(0 0 1 1 2 .5 3 .25 4 .125 10 0))))
  3774. |#
  3775. ;;; --------------------------------------------------------------------------------
  3776. (define adjustable-square-wave-methods
  3777. (list
  3778. (cons 'mus-frequency
  3779. (dilambda
  3780. (lambda (g) (mus-frequency (g 'p1)))
  3781. (lambda (g val) (set! (mus-frequency (g 'p1)) val))))
  3782. (cons 'mus-phase
  3783. (dilambda
  3784. (lambda (g) (mus-phase (g 'p1)))
  3785. (lambda (g val) (set! (mus-phase (g 'p1)) val))))
  3786. (cons 'mus-scaler
  3787. (dilambda
  3788. (lambda (g) (g 'duty-factor))
  3789. (lambda (g val)
  3790. (set! (g 'duty-factor) val)
  3791. (set! (mus-phase (g 'p2)) (* two-pi (- 1.0 (g 'duty-factor))))
  3792. val)))))
  3793. (defgenerator (adjustable-square-wave
  3794. :make-wrapper
  3795. (lambda (g)
  3796. (set! (g 'p1) (make-pulse-train
  3797. (g 'frequency)
  3798. (g 'amplitude)))
  3799. (set! (g 'p2) (make-pulse-train
  3800. (g 'frequency)
  3801. (- (g 'amplitude))
  3802. (* two-pi (- 1.0 (g 'duty-factor)))))
  3803. g)
  3804. :methods adjustable-square-wave-methods)
  3805. (frequency *clm-default-frequency*) (duty-factor 0.5) (amplitude 1.0)
  3806. (sum 0.0) (p1 #f) (p2 #f) fm)
  3807. (define adjustable-square-wave
  3808. (let ((documentation "(make-adjustable-square-wave frequency (duty-factor 0.5) (amplitude 1.0))
  3809. creates an adjustable-square-wave generator. (adjustable-square-wave gen (fm 0.0)) returns a square-wave
  3810. where the duty-factor sets the ratio of pulse duration to pulse period."))
  3811. (lambda* (gen (fm 0.0))
  3812. (let-set! gen 'fm fm)
  3813. (with-let gen
  3814. (set! sum (+ sum
  3815. (pulse-train p1 fm)
  3816. (pulse-train p2 fm)))))))
  3817. #|
  3818. (with-sound ()
  3819. (let ((gen (make-adjustable-square-wave 100 .2 .5)))
  3820. (do ((i 0 (+ i 1)))
  3821. ((= i 22050))
  3822. (outa i (adjustable-square-wave gen)))))
  3823. |#
  3824. (define adjustable-triangle-wave-methods
  3825. (list
  3826. (cons 'mus-frequency
  3827. (dilambda
  3828. (lambda (g) (mus-frequency (g 'gen)))
  3829. (lambda (g val) (set! (mus-frequency (g 'gen)) val))))
  3830. (cons 'mus-phase
  3831. (dilambda
  3832. (lambda (g) (mus-phase (g 'gen)))
  3833. (lambda (g val) (set! (mus-phase (g 'gen)) val))))
  3834. (cons 'mus-scaler
  3835. (dilambda
  3836. (lambda (g) (g 'duty-factor))
  3837. (lambda (g val)
  3838. (set! (g 'duty-factor) val)
  3839. (set! (g 'top) (- 1.0 val))
  3840. (if (not (= val 0.0))
  3841. (set! (g 'scl) (/ (g 'amplitude) val)))
  3842. val)))))
  3843. (defgenerator (adjustable-triangle-wave
  3844. :make-wrapper
  3845. (lambda (g)
  3846. (let ((df (g 'duty-factor)))
  3847. (set! (g 'gen) (make-triangle-wave (g 'frequency)))
  3848. (set! (g 'top) (- 1.0 df))
  3849. (set! (g 'mtop) (- (g 'top)))
  3850. (if (not (= df 0.0))
  3851. (set! (g 'scl) (/ (g 'amplitude) df)))
  3852. g))
  3853. :methods adjustable-triangle-wave-methods)
  3854. (frequency *clm-default-frequency*) (duty-factor 0.5) (amplitude 1.0)
  3855. (gen #f) (top 0.0) (mtop 0.0) (scl 0.0) val fm)
  3856. (define adjustable-triangle-wave
  3857. (let ((documentation "(make-adjustable-triangle-wave frequency (duty-factor 0.5) (amplitude 1.0)) creates an
  3858. adjustable-triangle-wave generator. (adjustable-triangle-wave gen (fm 0.0)) returns a triangle-wave where the
  3859. duty-factor sets the ratio of pulse duration to pulse period."))
  3860. (lambda* (gen (fm 0.0))
  3861. (let-set! gen 'fm fm)
  3862. (with-let gen
  3863. (set! val (triangle-wave gen fm))
  3864. (* scl (- val (max mtop (min top val))))))))
  3865. #|
  3866. (with-sound ()
  3867. (let ((gen (make-adjustable-triangle-wave 100 .2 .5)))
  3868. (do ((i 0 (+ i 1)))
  3869. ((= i 22050))
  3870. (outa i (adjustable-triangle-wave gen)))))
  3871. |#
  3872. (define adjustable-sawtooth-wave-methods
  3873. (list
  3874. (cons 'mus-frequency
  3875. (dilambda
  3876. (lambda (g) (mus-frequency (g 'gen)))
  3877. (lambda (g val) (set! (mus-frequency (g 'gen)) val))))
  3878. (cons 'mus-phase
  3879. (dilambda
  3880. (lambda (g) (mus-phase (g 'gen)))
  3881. (lambda (g val) (set! (mus-phase (g 'gen)) val))))
  3882. (cons 'mus-scaler
  3883. (dilambda
  3884. (lambda (g) (g 'duty-factor))
  3885. (lambda (g val)
  3886. (set! (g 'duty-factor) val)
  3887. (set! (g 'top) (- 1.0 val))
  3888. (set! (g 'mtop) (- val 1.0))
  3889. (if (not (= val 0.0))
  3890. (set! (g 'scl) (/ (g 'amplitude) val)))
  3891. val)))))
  3892. (defgenerator (adjustable-sawtooth-wave
  3893. :make-wrapper
  3894. (lambda (g)
  3895. (let ((df (g 'duty-factor)))
  3896. (set! (g 'gen) (make-sawtooth-wave (g 'frequency)))
  3897. (set! (g 'top) (- 1.0 df))
  3898. (set! (g 'mtop) (- df 1.0))
  3899. (if (not (= df 0.0))
  3900. (set! (g 'scl) (/ (g 'amplitude) df)))
  3901. g))
  3902. :methods adjustable-sawtooth-wave-methods)
  3903. (frequency *clm-default-frequency*) (duty-factor 0.5) (amplitude 1.0)
  3904. (gen #f) (top 0.0) (mtop 0.0) (scl 0.0) val fm)
  3905. (define adjustable-sawtooth-wave
  3906. (let ((documentation "(make-adjustable-sawtooth-wave frequency (duty-factor 0.5) (amplitude 1.0)) creates
  3907. an adjustable-sawtooth-wave generator. (adjustable-sawtooth-wave gen (fm 0.0)) returns a sawtooth-wave where
  3908. the duty-factor sets the ratio of pulse duration to pulse period."))
  3909. (lambda* (gen (fm 0.0))
  3910. (let-set! gen 'fm fm)
  3911. (with-let gen
  3912. (set! val (sawtooth-wave gen fm))
  3913. (* scl (- val (max mtop (min top val))))))))
  3914. #|
  3915. (with-sound ()
  3916. (let ((gen (make-adjustable-sawtooth-wave 100 .2 .5)))
  3917. (do ((i 0 (+ i 1)))
  3918. ((= i 22050))
  3919. (outa i (adjustable-sawtooth-wave gen)))))
  3920. |#
  3921. ;;; and just for laughs... (almost anything would fit in this hack)
  3922. (define adjustable-oscil-methods
  3923. (let ((copy-func (lambda (g)
  3924. (let ((e (inlet g))) ; (copy g) without invoking (g 'copy)
  3925. (let-set! e 'gen (mus-copy (g 'gen)))
  3926. e))))
  3927. (list
  3928. (cons 'mus-frequency
  3929. (dilambda
  3930. (lambda (g) (mus-frequency (g 'gen)))
  3931. (lambda (g val) (set! (mus-frequency (g 'gen)) val))))
  3932. (cons 'mus-phase
  3933. (dilambda
  3934. (lambda (g) (mus-phase (g 'gen)))
  3935. (lambda (g val) (set! (mus-phase (g 'gen)) val))))
  3936. (cons 'mus-scaler
  3937. (dilambda
  3938. (lambda (g) (g 'duty-factor))
  3939. (lambda (g val)
  3940. (set! (g 'duty-factor) val)
  3941. (set! (g 'top) (- 1.0 val))
  3942. (set! (g 'mtop) (- val 1.0))
  3943. (if (not (= val 0.0))
  3944. (set! (g 'scl) (/ val)))
  3945. val)))
  3946. (cons 'copy copy-func)
  3947. (cons 'mus-copy copy-func))))
  3948. (defgenerator (adjustable-oscil
  3949. :make-wrapper (lambda (g)
  3950. (let ((df (g 'duty-factor)))
  3951. (set! (g 'gen) (make-oscil (g 'frequency)))
  3952. (set! (g 'top) (- 1.0 df))
  3953. (set! (g 'mtop) (- df 1.0))
  3954. (if (not (= df 0.0))
  3955. (set! (g 'scl) (/ df)))
  3956. g))
  3957. :methods adjustable-oscil-methods)
  3958. (frequency *clm-default-frequency*) (duty-factor 0.5)
  3959. (gen #f) (top 0.0) (mtop 0.0) (scl 0.0) val fm)
  3960. (define adjustable-oscil
  3961. (let ((documentation "(make-adjustable-oscil frequency (duty-factor 0.5)) creates an adjustable-oscil
  3962. generator. (adjustable-oscil gen (fm 0.0)) returns a sinusoid where the duty-factor sets the ratio of pulse duration to pulse period."))
  3963. (lambda* (g (fm 0.0))
  3964. (let-set! g 'fm fm)
  3965. (with-let g
  3966. (set! val (oscil gen fm))
  3967. (* scl (- val (max mtop (min top val))))))))
  3968. #|
  3969. (with-sound (:statistics #t)
  3970. (let ((gen (make-adjustable-oscil 100 .2)))
  3971. (do ((i 0 (+ i 1)))
  3972. ((= i 22050))
  3973. (outa i (adjustable-oscil gen)))))
  3974. |#
  3975. ;;;--------------------------------------------------------------------------------
  3976. (define* (make-table-lookup-with-env frequency pulse-env size)
  3977. (let ((len (or size *clm-table-size*)))
  3978. (do ((ve (make-float-vector len))
  3979. (e (make-env pulse-env :length len))
  3980. (i 0 (+ i 1)))
  3981. ((= i len)
  3982. (make-table-lookup frequency 0.0 ve len))
  3983. (float-vector-set! ve i (env e)))))
  3984. (define* (make-wave-train-with-env frequency pulse-env size)
  3985. (let ((len (or size *clm-table-size*)))
  3986. (do ((ve (make-float-vector len))
  3987. (e (make-env pulse-env :length len))
  3988. (i 0 (+ i 1)))
  3989. ((= i len)
  3990. (make-wave-train frequency 0.0 ve len))
  3991. (float-vector-set! ve i (env e)))))
  3992. ;;; --------------------------------------------------------------------------------
  3993. (define round-interp-methods
  3994. (list
  3995. (cons 'mus-frequency
  3996. (dilambda
  3997. (lambda (g) (mus-frequency (g 'rnd)))
  3998. (lambda (g val) (set! (mus-frequency (g 'rnd)) val))))
  3999. (cons 'mus-phase
  4000. (dilambda
  4001. (lambda (g) (mus-phase (g 'rnd)))
  4002. (lambda (g val) (set! (mus-phase (g 'rnd)) val))))))
  4003. (defgenerator (round-interp
  4004. :make-wrapper (lambda (g)
  4005. (set! (g 'rnd) (make-rand-interp (g 'frequency) (g 'amplitude)))
  4006. (set! (g 'flt) (make-moving-average (g 'n)))
  4007. g)
  4008. :methods round-interp-methods)
  4009. (frequency *clm-default-frequency*) (n 1) (amplitude 1.0)
  4010. (rnd #f) (flt #f) fm)
  4011. (define round-interp
  4012. (let ((documentation "(make-round-interp frequency (n 1) (amplitude 1.0)) creates a round-interp
  4013. generator. (round-interp gen (fm 0.0)) returns a rand-interp sequence low-pass filtered by a moving-average generator of length n."))
  4014. (lambda* (gen (fm 0.0))
  4015. (let-set! gen 'fm fm)
  4016. (with-let gen
  4017. (moving-average flt (rand-interp rnd fm))))))
  4018. #|
  4019. (with-sound (:channels 5)
  4020. (let ((gen0 (make-round-interp 100 1))
  4021. (gen1 (make-round-interp 100 10))
  4022. (gen2 (make-round-interp 100 100))
  4023. (gen3 (make-round-interp 100 1000))
  4024. (gen4 (make-round-interp 100 10000)))
  4025. (do ((i 0 (+ i 1)))
  4026. ((= i 100000))
  4027. (out-any i (round-interp gen0 0.0) 0)
  4028. (out-any i (round-interp gen1 0.0) 1)
  4029. (out-any i (round-interp gen2 0.0) 2)
  4030. (out-any i (round-interp gen3 0.0) 3)
  4031. (out-any i (round-interp gen4 0.0) 4))))
  4032. |#
  4033. ;;; --------------------------------------------------------------------------------
  4034. ;;;
  4035. ;;; env-any functions
  4036. (define (sine-env e)
  4037. (env-any e (lambda (y)
  4038. (* 0.5 (+ 1.0 (sin (* pi (- y 0.5))))))))
  4039. (define (square-env e)
  4040. (env-any e (lambda (y)
  4041. (* y y))))
  4042. (define (blackman4-env e)
  4043. (env-any e (lambda (y)
  4044. (let ((cx (cos (* pi y))))
  4045. (+ 0.084037 (* cx (- (* cx (+ 0.375696 (* cx (- (* cx 0.041194) 0.20762)))) 0.29145)))))))
  4046. (define (multi-expt-env e expts)
  4047. (env-any e (lambda (y)
  4048. (let ((b (expts (modulo (channels e) (length expts)))))
  4049. (/ (- (expt b y) 1.0) (- b 1.0))))))
  4050. ;;; --------------------------------------------------------------------------------
  4051. ;;;
  4052. ;;; pm with any generator that has mus-phase and mus-run:
  4053. (define (run-with-fm-and-pm gen fm pm)
  4054. (set! (mus-phase gen) (+ (mus-phase gen) pm))
  4055. (let ((result (mus-run gen fm 0.0)))
  4056. (set! (mus-phase gen) (- (mus-phase gen) pm))
  4057. result))
  4058. #|
  4059. (let ((gen1 (make-oscil 440.0))
  4060. (gen2 (make-oscil 440.0)))
  4061. (do ((i 0 (+ i 1)))
  4062. ((= i 1000))
  4063. (let* ((pm (mus-random 1.0))
  4064. (val1 (oscil gen1 0.0 pm))
  4065. (val2 (run-with-fm-and-pm gen2 0.0 pm)))
  4066. (if (fneq val1 val2)
  4067. (format () ";run-with-fm-and-pm: ~A ~A" val1 val2)))))
  4068. |#
  4069. ;;; --------------------------------------------------------------------------------
  4070. ;;; cos^n J 121
  4071. (defgenerator (nchoosekcos
  4072. :make-wrapper (lambda (g)
  4073. (set! (g 'frequency) (hz->radians (g 'frequency)))
  4074. g))
  4075. (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm)
  4076. (define nchoosekcos
  4077. (let ((documentation "(make-nchoosekcos frequency (ratio 1.0) (n 1)) creates an nchoosekcos generator. (nchoosekcos gen (fm 0.0))
  4078. returns a sum of cosines scaled by the binomial coeffcients."))
  4079. (lambda* (gen (fm 0.0))
  4080. (let-set! gen 'fm fm)
  4081. (with-let gen
  4082. (let* ((x angle)
  4083. (y (* x ratio)))
  4084. (set! angle (+ angle fm frequency))
  4085. (real-part (* (cos x)
  4086. (expt (cos y) n))))))))
  4087. #|
  4088. (with-sound (:clipped #f :statistics #t :play #t)
  4089. (let ((gen (make-nchoosekcos 2000.0 0.05 10)))
  4090. (do ((i 0 (+ i 1)))
  4091. ((= i 30000))
  4092. (outa i (* .5 (nchoosekcos gen))))))
  4093. |#
  4094. ;;; --------------------------------------------------------------------------------
  4095. ;;;
  4096. ;;; sinc-train
  4097. (define sinc-train-methods
  4098. (list
  4099. (cons 'mus-order
  4100. (dilambda
  4101. (lambda (g) (g 'original-n))
  4102. (lambda (g val)
  4103. (if (<= val 0)
  4104. (begin
  4105. (set! (g 'original-n) 1)
  4106. (set! (g 'n) 3))
  4107. (begin
  4108. (set! (g 'original-n) val)
  4109. (set! (g 'n) (+ 1 (* 2 val)))))
  4110. (set! (g 'frequency) (* 0.5 (g 'n) (hz->radians (g 'original-frequency))))
  4111. (g 'original-n))))
  4112. (cons 'mus-frequency
  4113. (dilambda
  4114. (lambda (g) (g 'original-frequency))
  4115. (lambda (g val)
  4116. (set! (g 'original-frequency) val)
  4117. (set! (g 'frequency) (* 0.5 (g 'n) (hz->radians val)))
  4118. val)))))
  4119. (defgenerator (sinc-train
  4120. :make-wrapper (lambda (g)
  4121. (if (<= (g 'n) 0)
  4122. (begin
  4123. (set! (g 'original-n) 1)
  4124. (set! (g 'n) 3))
  4125. (begin
  4126. (set! (g 'original-n) (g 'n))
  4127. (set! (g 'n) (+ 1 (* 2 (g 'n)))))) ; mimic ncos
  4128. (set! (g 'original-frequency) (g 'frequency))
  4129. (set! (g 'frequency) (* 0.5 (g 'n) (hz->radians (g 'frequency))))
  4130. g)
  4131. :methods sinc-train-methods)
  4132. (frequency *clm-default-frequency*) (n 1) (angle 0.0)
  4133. (original-n 1) (original-frequency 0.0) fm)
  4134. (define sinc-train
  4135. (let ((documentation "(make-sinc-train frequency (n 1)) creates a sinc-train generator with n components. (sinc-train gen (fm 0.0)) returns a sinc-train"))
  4136. (lambda* (gen (fm 0.0))
  4137. (let-set! gen 'fm fm)
  4138. (with-let gen
  4139. (let ((x angle))
  4140. (let ((max-angle (* pi 0.5 n))
  4141. (new-angle (+ x fm frequency))
  4142. (DC (/ 1.0 n))
  4143. (norm (/ n (- n 1))))
  4144. (if (> new-angle max-angle)
  4145. (set! new-angle (- new-angle (* pi n))))
  4146. (set! angle new-angle)
  4147. (if (< (abs x) nearly-zero)
  4148. 1.0
  4149. (* norm (- (/ (sin x) x) DC)))))))))
  4150. #|
  4151. (with-sound (:clipped #f :statistics #t)
  4152. (let* ((g (make-sinc-train 100.0 40)))
  4153. (do ((i 0 (+ i 1)))
  4154. ((= i 44100))
  4155. (outa i (* .5 (sinc-train g 0.0))))))
  4156. |#
  4157. ;;; --------------------------------------------------------------------------------
  4158. ;;;
  4159. ;;; pink-noise (based on rand-bank idea of Orfanidis)
  4160. #|
  4161. (defgenerator (pink-noise
  4162. :make-wrapper (lambda (g)
  4163. (if (<= (g 'n) 0) (set! (g 'n) 1))
  4164. (let ((n (g 'n)))
  4165. (set! (g 'rands) (make-vector n))
  4166. (do ((i 0 (+ i 1)))
  4167. ((= i n))
  4168. (set! ((g 'rands) i) (make-rand :frequency (/ *clm-srate* (expt 2 i))))
  4169. (set! (mus-phase ((g 'rands) i)) (random pi))))
  4170. g))
  4171. (n 1) (rands #f))
  4172. (define pink-noise
  4173. (let ((documentation "(make-pink-noise (n 1)) creates a pink-noise generator with n octaves of rand (12 is recommended). (pink-noise gen)
  4174. returns the next random value in the 1/f stream produced by gen."))
  4175. (lambda (gen)
  4176. (with-let gen
  4177. (/ (rand-bank rands) (* 2.5 (sqrt n))))))) ; this normalization is not quite right
  4178. |#
  4179. (define* (make-pink-noise (n 1))
  4180. (let ((v (make-float-vector (* n 2)))
  4181. (amp (/ (* 2.5 (sqrt n)))))
  4182. (set! (v 0) amp)
  4183. (do ((i 2 (+ i 2)))
  4184. ((= i (* 2 n)))
  4185. (set! (v i) (mus-random amp))
  4186. (set! (v (+ i 1)) (random 1.0)))
  4187. v))
  4188. (define pink-noise? float-vector?)
  4189. ;;; pink-noise func is in clm2xen.c
  4190. #|
  4191. (define (pink-noise v)
  4192. (let ((amp (v 0))
  4193. (sum 0.0)
  4194. (p 0.0)
  4195. (len (length v)))
  4196. (do ((i 2 (+ i 2))
  4197. (x 0.5 (* x 0.5)))
  4198. ((= i len)
  4199. (+ sum (mus-random amp)))
  4200. (set! sum (+ sum (v i)))
  4201. (set! p (- (v (+ i 1)) x))
  4202. (if (negative? p)
  4203. (begin
  4204. (set! (v (+ i 1)) (+ p 1.0))
  4205. (set! (v i) (mus-random amp)))
  4206. (set! (v (+ i 1)) p)))))
  4207. |#
  4208. #|
  4209. (with-sound (:clipped #f :statistics #t)
  4210. (let ((gen (make-pink-noise 12)))
  4211. (do ((i 0 (+ i 1)))
  4212. ((= i 44100))
  4213. (outa i (pink-noise gen)))))
  4214. (with-sound (:statistics #t) (let ((gen (make-pink-noise 12))) (do ((i 0 (+ i 1))) ((= i 441000)) (outa i (pink-noise gen)))))
  4215. |#
  4216. ;;; --------------------------------------------------------------------------------
  4217. ;;;
  4218. ;;; brown-noise
  4219. (defgenerator (brown-noise
  4220. :make-wrapper (lambda (g)
  4221. (set! (g 'gr) (make-rand (g 'frequency) (g 'amplitude)))
  4222. g))
  4223. (frequency *clm-default-frequency*) (amplitude 1.0) fm gr (sum 0.0) (prev 0.0))
  4224. (define brown-noise
  4225. (let ((documentation "(make-brown-noise frequency (amplitude 1.0)) returns a generator that produces
  4226. brownian noise. (brown-noise gen (fm 0.0)) returns the next brownian noise sample."))
  4227. (lambda* (gen (fm 0.0))
  4228. (let-set! gen 'fm fm)
  4229. (with-let gen
  4230. (let ((val (rand gr fm)))
  4231. (if (not (= val prev))
  4232. (begin
  4233. (set! prev val)
  4234. (set! sum (+ sum val))))
  4235. sum)))))
  4236. #|
  4237. ;; this is slightly faster, but ugly
  4238. (define* (make-brown-noise (frequency 440.0) (amplitude 1.0))
  4239. (vector 0.0 0.0 (make-rand frequency amplitude)))
  4240. (define (brown-noise? g)
  4241. (and (vector? g)
  4242. (= (length g) 3)
  4243. (rand? (g 2))))
  4244. (define* (brown-noise g (fm 0.0))
  4245. (let ((val (rand (vector-ref g 2) fm)))
  4246. (if (not (= val (vector-ref g 1)))
  4247. (begin
  4248. (vector-set! g 1 val)
  4249. (vector-set! g 0 (+ (vector-ref g 0) val))))
  4250. (vector-ref g 0)))
  4251. (with-sound (:clipped #f :statistics #t)
  4252. (let* ((gen (make-brown-noise 1000)))
  4253. (do ((i 0 (+ i 1)))
  4254. ((= i 44100))
  4255. (outa i (* .01 (brown-noise gen))))))
  4256. |#
  4257. ;;; --------------------------------------------------------------------------------
  4258. ;;;
  4259. ;;; green-noise
  4260. (defgenerator (green-noise
  4261. :make-wrapper (lambda (g)
  4262. (set! (g 'gr) (make-rand (g 'frequency) (g 'amplitude)))
  4263. (set! (g 'sum) (* 0.5 (+ (g 'low) (g 'high))))
  4264. g))
  4265. (frequency *clm-default-frequency*) (amplitude 1.0) (low -1.0) (high 1.0)
  4266. fm gr (sum 0.0) (prev 0.0))
  4267. (define green-noise
  4268. (let ((documentation "(make-green-noise frequency (amplitude 1.0) (low -1.0) (high 1.0)) returns a new
  4269. green-noise (bounded brownian noise) generator. (green-noise gen (fm 0.0)) returns the next sample in a
  4270. sequence of bounded brownian noise samples."))
  4271. (lambda* (gen (fm 0.0))
  4272. (let-set! gen 'fm fm)
  4273. (with-let gen
  4274. (let ((val (rand gr fm)))
  4275. (if (not (= val prev))
  4276. (begin
  4277. (set! prev val)
  4278. (set! sum (+ sum val))
  4279. (if (not (<= low sum high))
  4280. (set! sum (- sum (* 2 val))))))
  4281. sum)))))
  4282. #|
  4283. (define* (make-green-noise (frequency 440.0) (amplitude 1.0) (low -1.0) (high 1.0))
  4284. (vector 0.0 0.0 low high (make-rand frequency amplitude)))
  4285. (define (green-noise? g)
  4286. (and (vector? g)
  4287. (= (length g) 5)
  4288. (rand? (g 4))))
  4289. (define* (green-noise g (fm 0.0))
  4290. (let ((val (rand (g 4) fm)))
  4291. (if (not (= val (g 1)))
  4292. (begin
  4293. (set! (g 1) val)
  4294. (set! (g 0) (+ (g 0) val))
  4295. (if (not (<= (g 2) (g 0) (g 3)))
  4296. (set! (g 0) (- (g 0) (* 2.0 val))))))
  4297. (g 0)))
  4298. (with-sound (:clipped #f :statistics #t)
  4299. (let* ((gen (make-green-noise 1000)))
  4300. (do ((i 0 (+ i 1)))
  4301. ((= i 44100))
  4302. (outa i (green-noise gen)))))
  4303. |#
  4304. ;;; --------------------------------------------------------------------------------
  4305. ;;;
  4306. ;;; green-noise-interp
  4307. (defgenerator (green-noise-interp
  4308. :make-wrapper (lambda (g)
  4309. (set! (g 'sum) (* 0.5 (+ (g 'low) (g 'high))))
  4310. (set! (g 'dv) (/ 1.0 (ceiling (/ *clm-srate* (max 1.0 (g 'frequency))))))
  4311. (set! (g 'frequency) (hz->radians (g 'frequency)))
  4312. (set! (g 'incr) (* (mus-random (g 'amplitude)) dv))
  4313. g))
  4314. (frequency *clm-default-frequency*) (amplitude 1.0) (low -1.0) (high 1.0)
  4315. (angle 0.0) (sum 0.0) (incr 0.0) fm dv)
  4316. (define green-noise-interp
  4317. (let ((documentation "(make-green-noise-interp frequency (amplitude 1.0) (low -1.0) (high 1.0)) returns a new
  4318. interpolating green noise (bounded brownian noise) generator. (green-noise-interp gen (fm 0.0)) returns the next
  4319. sample in a sequence of interpolated bounded brownian noise samples."))
  4320. (lambda* (gen (fm 0.0))
  4321. (let-set! gen 'fm fm)
  4322. (with-let gen
  4323. (if (not (<= 0.0 angle two-pi))
  4324. (let ((val (mus-random amplitude)))
  4325. (set! angle (modulo angle two-pi))
  4326. (if (< angle 0.0) (set! angle (+ angle two-pi)))
  4327. (if (not (<= low (+ sum val) high))
  4328. (set! val (min (- high sum)
  4329. (max (- low sum)
  4330. (- val))))) ; at least bounce
  4331. (set! incr (* dv val))))
  4332. (set! angle (+ angle fm frequency))
  4333. (set! sum (+ sum incr))))))
  4334. #|
  4335. (with-sound (:clipped #f :statistics #t)
  4336. (let* ((gen (make-green-noise-interp 1000)))
  4337. (do ((i 0 (+ i 1)))
  4338. ((= i 44100))
  4339. (outa i (green-noise-interp gen)))))
  4340. (definstrument (green1 beg end freq amp lo hi)
  4341. (let ((grn (make-green-noise :frequency freq :amplitude amp :high hi :low lo)))
  4342. (do ((i beg (+ i 1)))
  4343. ((= i end))
  4344. (outa i (green-noise grn 0.0)))))
  4345. (definstrument (green2 beg end freq amp lo hi)
  4346. (let ((grn (make-green-noise-interp :frequency freq :amplitude amp :high hi :low lo)))
  4347. (do ((i beg (+ i 1)))
  4348. ((= i end))
  4349. (outa i (green-noise-interp grn 0.0)))))
  4350. (with-sound () (green1 0 10000 1000 0.1 -0.5 0.5) (green2 10000 20000 1000 0.1 -0.5 0.5))
  4351. (definstrument (green3 start dur freq amp amp-env noise-freq noise-width noise-max-step)
  4352. ;; brownian noise on amp env
  4353. (let ((grn (make-green-noise-interp :frequency noise-freq :amplitude noise-max-step :high (* 0.5 noise-width) :low (* -0.5 noise-width)))
  4354. (osc (make-oscil freq))
  4355. (e (make-env amp-env :scaler amp :duration dur))
  4356. (beg (seconds->samples start))
  4357. (end (seconds->samples (+ start dur))))
  4358. (do ((i beg (+ i 1)))
  4359. ((= i end))
  4360. (outa i (* (env e)
  4361. (+ 1.0 (green-noise-interp grn 0.0))
  4362. (oscil osc))))))
  4363. (with-sound () (green3 0 2.0 440 .5 '(0 0 1 1 2 1 3 0) 100 .2 .02))
  4364. (definstrument (green4 start dur freq amp freq-env gliss noise-freq noise-width noise-max-step)
  4365. ;; same but on freq env
  4366. (let ((grn (make-green-noise-interp :frequency noise-freq
  4367. :amplitude (hz->radians noise-max-step)
  4368. :high (hz->radians (* 0.5 noise-width))
  4369. :low (hz->radians (* -0.5 noise-width))))
  4370. (osc (make-oscil freq))
  4371. (e (make-env freq-env :scaler (hz->radians gliss) :duration dur))
  4372. (beg (seconds->samples start))
  4373. (end (seconds->samples (+ start dur))))
  4374. (do ((i beg (+ i 1)))
  4375. ((= i end))
  4376. (outa i (* amp (oscil osc (+ (env e) (green-noise-interp grn 0.0))))))))
  4377. (with-sound (:statistics #t) (green4 0 2.0 440 .5 '(0 0 1 1 2 1 3 0) 440 100 100 10))
  4378. |#
  4379. ;;; --------------------------------------------------------------------------------
  4380. ;;;
  4381. ;;; moving-sum
  4382. (defgenerator (moving-sum
  4383. :make-wrapper (lambda (g)
  4384. (let ((dly (make-moving-average (g 'n))))
  4385. (set! (g 'gen) dly)
  4386. (set! (mus-increment dly) 1.0) ; this is 1/n by default
  4387. g)))
  4388. (n 128) (gen #f))
  4389. (define moving-sum
  4390. (let ((documentation "(make-moving-sum (n 128)) returns a moving-sum generator. (moving-sum gen input)
  4391. returns the sum of the absolute values in a moving window over the last n inputs."))
  4392. (lambda (gen y)
  4393. (moving-average (gen 'gen) (abs y)))))
  4394. (define (make-unmoving-sum) (make-one-pole 1.0 -1.0))
  4395. (define unmoving-sum one-pole)
  4396. ;;; --------------------------------------------------------------------------------
  4397. ;;;
  4398. ;;; moving-variance
  4399. ;;;
  4400. ;;; this taken from the dsp bboard -- untested!
  4401. (defgenerator (moving-variance
  4402. :make-wrapper (lambda (g)
  4403. (let ((g1 (make-moving-average (g 'n))))
  4404. (set! (g 'gen1) g1)
  4405. (set! (mus-increment g1) 1.0))
  4406. (let ((g2 (make-moving-average (g 'n))))
  4407. (set! (g 'gen2) g2)
  4408. (set! (mus-increment g2) 1.0))
  4409. g))
  4410. (n 128) (gen1 #f) (gen2 #f) y)
  4411. (define (moving-variance gen y)
  4412. (let-set! gen 'y y)
  4413. (with-let gen
  4414. (let ((x1 (moving-average gen1 y))
  4415. (x2 (moving-average gen2 (* y y))))
  4416. (/ (- (* n x2)
  4417. (* x1 x1))
  4418. (* n (- n 1))))))
  4419. #|
  4420. (with-sound (:clipped #f)
  4421. (let ((gen (make-moving-variance 128)))
  4422. (do ((i 0 (+ i 1)))
  4423. ((= i 10000))
  4424. (outa i (moving-variance gen (random 1.0))))))
  4425. |#
  4426. ;;; similarly (moving-inner-product x y) -> (moving-sum (* x y)),
  4427. ;;; (moving-distance x y) -> (sqrt (moving-sum (* (- x y) (- x y))))
  4428. ;;; --------------------------------------------------------------------------------
  4429. ;;;
  4430. ;;; moving-rms
  4431. (defgenerator (moving-rms
  4432. :make-wrapper (lambda (g)
  4433. (set! (g 'gen) (make-moving-average (g 'n)))
  4434. g))
  4435. (n 128) (gen #f) y)
  4436. (define moving-rms
  4437. (let ((documentation "(make-moving-rms (n 128) returns a moving-rms generator. (moving-rms gen input) returns
  4438. the rms of the values in a window over the last n inputs."))
  4439. (lambda (gen y)
  4440. (let-set! gen 'y y)
  4441. (with-let gen
  4442. (sqrt (max 0.0
  4443. ;; this is tricky -- due to floating point inaccuracy, we can get negative output
  4444. ;; from moving-rms even if all the inputs are positive! The sqrt then returns
  4445. ;; a complex number and all hell breaks loose
  4446. (moving-average gen (* y y))))))))
  4447. ;;; --------------------------------------------------------------------------------
  4448. ;;;
  4449. ;;; moving-length
  4450. (defgenerator (moving-length
  4451. :make-wrapper (lambda (g)
  4452. (let ((dly (make-moving-average (g 'n))))
  4453. (set! (g 'gen) dly)
  4454. (set! (mus-increment dly) 1.0)
  4455. g)))
  4456. (n 128) (gen #f) y)
  4457. (define moving-length moving-rms)
  4458. #|
  4459. (define moving-length
  4460. (let ((documentation "(make-moving-length (n 128) returns a moving-length generator. (moving-length gen input)
  4461. returns the length of the values in a window over the last few inputs."))
  4462. (lambda (gen y)
  4463. (moving-rms gen y))))
  4464. (let-set! gen 'y y)
  4465. (with-let gen
  4466. (sqrt (max 0.0 (moving-average gen (* y y))))))))
  4467. |#
  4468. #|
  4469. (let ((ml (make-moving-length 128))
  4470. (rd (make-readin "oboe.snd")))
  4471. (with-sound ()
  4472. (do ((i 0 (+ i 1)))
  4473. ((= i 50828))
  4474. (outa i (moving-length ml (readin rd))))))
  4475. |#
  4476. #|
  4477. ;; perhaps also use moving-rms gen to avoid amplifying noise-sections (or even squlech them)
  4478. (define* (agc (ramp-speed .001) (window-size 512))
  4479. (let ((maxer (make-moving-max window-size))
  4480. (mult 1.0))
  4481. (map-channel
  4482. (lambda (y)
  4483. (let* ((curmax (moving-max maxer y))
  4484. (diff (- 0.5 (* mult curmax)))
  4485. (this-incr (* diff ramp-speed)))
  4486. (set! mult (+ mult this-incr))
  4487. (* y mult))))))
  4488. ;;; moving-mean = average
  4489. |#
  4490. ;;; --------------------------------------------------------------------------------
  4491. ;;;
  4492. ;;; weighted-moving-average
  4493. ;;;
  4494. ;;; arithmetic (1/n) weights
  4495. (defgenerator (weighted-moving-average
  4496. :make-wrapper (lambda (g)
  4497. (let ((n (g 'n)))
  4498. (let ((dly (make-moving-average n)))
  4499. (set! (mus-increment dly) 1.0)
  4500. (set! (g 'dly) dly))
  4501. (set! (g 'den) (* 0.5 (+ n 1) n)))
  4502. g))
  4503. (n 128) (dly #f) (num 0.0) (sum 0.0) y den)
  4504. (define weighted-moving-average
  4505. (let ((documentation "(make-weighted-moving-average (n 128)) returns a weighted-moving-average
  4506. generator. (weighted-moving-average gen y) returns the sum of the last n inputs weighted by 1/n"))
  4507. (lambda (gen y)
  4508. (let-set! gen 'y y)
  4509. (with-let gen
  4510. (set! num (- (+ num (* n y)) sum))
  4511. (set! sum (moving-average dly y))
  4512. (/ num den)))))
  4513. ;;; --------------------------------------------------------------------------------
  4514. ;;;
  4515. ;;; exponentially-weighted-moving-average
  4516. ;;;
  4517. ;;; geometric (r^n) weights
  4518. #|
  4519. (defgenerator (exponentially-weighted-moving-average
  4520. :make-wrapper (lambda (g)
  4521. (let* ((n (g 'n))
  4522. (flt (make-one-pole (/ 1.0 n) (/ (- n) (+ 1.0 n)))))
  4523. (set! (g 'gen) flt)
  4524. g)))
  4525. (n 128) (gen #f))
  4526. (define exponentially-weighted-moving-average
  4527. (let ((documentation "(make-exponentially-weighted-moving-average (n 128) returns an
  4528. exponentially-weighted-moving-average generator. (exponentially-weighted-moving-average gen y)
  4529. returns the sum of the last n inputs weighted by (-n/(n+1))^k"))
  4530. (lambda (gen y)
  4531. (one-pole (gen 'gen) y))))
  4532. |#
  4533. (define* (make-exponentially-weighted-moving-average (n 128)) (make-one-pole (/ 1.0 n) (/ (- n) (+ 1.0 n))))
  4534. (define exponentially-weighted-moving-average? one-pole?)
  4535. (define exponentially-weighted-moving-average one-pole)
  4536. ;;; --------------------------------------------------------------------------------
  4537. ;;;
  4538. ;;; polyoid -- Tn + Un to get arbitrary initial-phases
  4539. #|
  4540. ;;; old form, now replaced by built-in code (clm.c)
  4541. (defgenerator (polyoid
  4542. :make-wrapper (lambda (g)
  4543. (let* ((lst (g 'partial-amps-and-phases))
  4544. (len (length lst))
  4545. (topk (let ((n 0))
  4546. (do ((i 0 (+ i 3)))
  4547. ((>= i len))
  4548. (set! n (max n (floor (lst i)))))
  4549. n))
  4550. (sin-amps (make-float-vector (+ topk 1) 0.0))
  4551. (cos-amps (make-float-vector (+ topk 1) 0.0)))
  4552. (do ((j 0 (+ j 3)))
  4553. ((>= j len))
  4554. (let ((n (floor (lst j)))
  4555. (amp (lst (+ j 1)))
  4556. (phase (lst (+ j 2))))
  4557. (if (> n 0) ; constant only applies to cos side
  4558. (set! (sin-amps n) (* amp (cos phase))))
  4559. (set! (cos-amps n) (* amp (sin phase)))))
  4560. (set! (g 'tn) cos-amps)
  4561. (set! (g 'un) sin-amps)
  4562. (set! (g 'frequency) (hz->radians (g 'frequency)))
  4563. g))
  4564. :methods (list
  4565. (cons 'mus-data
  4566. (lambda (g) (g 'tn)))
  4567. (cons 'mus-xcoeffs
  4568. (lambda (g) (g 'tn)))
  4569. (cons 'mus-ycoeffs
  4570. (lambda (g) (g 'un)))
  4571. (cons 'mus-xcoeff
  4572. (dilambda
  4573. (lambda (g ind) ((g 'tn) ind))
  4574. (lambda (g ind val) (float-vector-set! (g 'tn) ind val))))
  4575. (cons 'mus-ycoeff
  4576. (dilambda
  4577. (lambda (g ind) ((g 'un) ind))
  4578. (lambda (g ind val) (float-vector-set! (g 'un) ind val))))))
  4579. (frequency *clm-default-frequency*) (partial-amps-and-phases #f) (angle 0.0)
  4580. (tn #f) (un #f) fm)
  4581. (define* (polyoid gen (fm 0.0))
  4582. (let-set! gen 'fm fm)
  4583. (with-let gen
  4584. (let ((x angle))
  4585. (set! angle (+ angle fm frequency))
  4586. (mus-chebyshev-tu-sum x tn un))))
  4587. |#
  4588. (define polyoid polywave)
  4589. (define (polyoid? g) (and (polywave? g) (= (mus-channel g) mus-chebyshev-both-kinds)))
  4590. (define polyoid-tn mus-xcoeffs)
  4591. (define polyoid-un mus-ycoeffs)
  4592. (define* (make-polyoid (frequency *clm-default-frequency*) partial-amps-and-phases)
  4593. (let* ((len (length partial-amps-and-phases))
  4594. (topk (do ((n 0)
  4595. (i 0 (+ i 3)))
  4596. ((>= i len)
  4597. (+ n 1))
  4598. (set! n (max n (floor (partial-amps-and-phases i)))))))
  4599. (let ((sin-amps (make-float-vector topk))
  4600. (cos-amps (make-float-vector topk)))
  4601. (do ((j 0 (+ j 3)))
  4602. ((>= j len))
  4603. (let ((n (floor (partial-amps-and-phases j)))
  4604. (amp (partial-amps-and-phases (+ j 1)))
  4605. (phase (partial-amps-and-phases (+ j 2))))
  4606. (if (> n 0) ; constant only applies to cos side
  4607. (set! (sin-amps n) (* amp (cos phase))))
  4608. (set! (cos-amps n) (* amp (sin phase)))))
  4609. (make-polywave frequency :xcoeffs cos-amps :ycoeffs sin-amps))))
  4610. (define (polyoid-env gen fm amps phases)
  4611. ;; amps and phases are the envelopes, one for each harmonic, setting the sample-wise amp and phase
  4612. (let ((original-data (polyoid-partial-amps-and-phases gen)))
  4613. (let ((data-len (length original-data))
  4614. (amps-len (length amps))
  4615. (tn (polyoid-tn gen))
  4616. (un (polyoid-un gen)))
  4617. (do ((i 0 (+ i 3))
  4618. (j 0 (+ j 1)))
  4619. ((or (= j amps-len)
  4620. (= i data-len)))
  4621. (let ((hn (floor (original-data i)))
  4622. (amp (env (amps j)))
  4623. (phase (env (phases j))))
  4624. (set! (tn hn) (* amp (sin phase)))
  4625. (set! (un hn) (* amp (cos phase)))))
  4626. (polyoid gen fm))))
  4627. #|
  4628. (with-sound (:clipped #f)
  4629. (let ((samps 44100)
  4630. (gen (make-polyoid 100.0 (vector 1 1 0.0))))
  4631. (do ((i 0 (+ i 1)))
  4632. ((= i samps))
  4633. (outa i (polyoid gen)))))
  4634. (with-sound (:clipped #f)
  4635. (let ((samps 44100)
  4636. (gen (make-polywave 100.0 '(1 1) mus-chebyshev-second-kind))
  4637. (gen1 (make-oscil 100.0)))
  4638. (set! (mus-phase gen) (* 0.5 pi))
  4639. (do ((i 0 (+ i 1)))
  4640. ((= i samps))
  4641. (outa i (* (oscil gen1) (polywave gen))))))
  4642. (with-sound (:clipped #f :statistics #t)
  4643. (let ((samps 44100)
  4644. (gen (make-polyoid 100.0 (vector 1 0.5 0.0 51 0.25 0.0 64 .25 (/ pi 2)))))
  4645. (do ((i 0 (+ i 1)))
  4646. ((= i samps))
  4647. (outa i (polyoid gen)))))
  4648. (define (test-polyoid n)
  4649. (let* ((res (with-sound (:channels 2 :clipped #f)
  4650. (let ((freqs (make-float-vector n))
  4651. (phases (make-float-vector n)) ; for oscil-bank
  4652. (cur-phases (make-float-vector (* 3 n))) ; for polyoid
  4653. (amp (/ 1.0 n)))
  4654. (do ((i 0 (+ i 1))
  4655. (j 0 (+ j 3)))
  4656. ((= i n))
  4657. (set! (cur-phases j) (+ i 1))
  4658. (set! (cur-phases (+ j 1)) (/ 1.0 n))
  4659. (set! (cur-phases (+ j 2)) (random (* 2 pi)))
  4660. (set! (freqs i) (hz->radians (+ i 1.0)))
  4661. (set! (phases i) (cur-phases (+ j 2))))
  4662. (let ((gen (make-polyoid 1.0 cur-phases))
  4663. (obank (make-oscil-bank freqs phases (make-float-vector n 1.0) #t)))
  4664. (do ((i 0 (+ i 1)))
  4665. ((= i 88200))
  4666. (outa i (* amp (oscil-bank obank))))
  4667. (do ((i 0 (+ i 1)))
  4668. ((= i 88200))
  4669. (outb i (polyoid gen 0.0)))))))
  4670. (snd (find-sound res)))
  4671. (channel-distance snd 0 snd 1)))
  4672. ;;; 0 diff up to 4096 so far (unopt and opt) -- 1.0e-12 at 4096, opt is more than 20 times as fast
  4673. (with-sound (:clipped #f :channels 2 :statistics #t)
  4674. (let* ((samps 44100)
  4675. (gen1 (make-polyoid 100.0 (vector 1 0.5 0.0 3 0.25 0.0 4 .25 0.0)))
  4676. (gen2 (make-polyoid 100.0 (vector 1 0.5 0.0 3 0.25 0.0 4 .25 0.0)))
  4677. (amps1 (vector (make-env '(0 0 1 1 2 0) :end samps :scaler 0.5)
  4678. (make-env '(0 1 1 0 2 1) :end samps :scaler 0.25)
  4679. (make-env '(0 1 1 0) :end samps :scaler 0.25)))
  4680. (phases1 (vector (make-env '(0 0 1 1) :end samps :scaler (/ pi 2))
  4681. (make-env '(0 0 1 1) :end samps :scaler (/ pi 2))
  4682. (make-env '(0 1 1 0) :end samps :scaler (/ pi 2))))
  4683. (amps2 (vector (make-env '(0 0 1 1 2 0) :end samps :scaler 0.5)
  4684. (make-env '(0 1 1 0 2 1) :end samps :scaler 0.25)
  4685. (make-env '(0 1 1 0) :end samps :scaler 0.25)))
  4686. (phases2 (vector (make-env '(0 0 1 0) :end samps)
  4687. (make-env '(0 0 1 0) :end samps)
  4688. (make-env '(0 0 1 0) :end samps))))
  4689. (do ((i 0 (+ i 1)))
  4690. ((= i samps))
  4691. (outa i (polyoid-env gen1 0.0 amps1 phases1))
  4692. (outb i (polyoid-env gen2 0.0 amps2 phases2)))))
  4693. (with-sound (:clipped #f :channels 2 :channels 3 :statistics #t)
  4694. (let* ((samps 44100)
  4695. (gen1 (make-polyoid 100.0 (vector 1 1 0 2 1 0 3 1 0)))
  4696. (gen2 (make-polyoid 100.0 (vector 1 1 0 2 1 0 3 1 0)))
  4697. (gen3 (make-polyoid 100.0 (vector 1 1 (/ pi 2) 2 1 (/ pi 2) 3 1 (/ pi 2))))
  4698. (amps1 (vector (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps)))
  4699. (amps2 (vector (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps)))
  4700. (amps3 (vector (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps)))
  4701. (phases1 (vector (make-env '(0 0 1 0) :end samps) (make-env '(0 0 1 0) :end samps) (make-env '(0 0 1 0) :end samps)))
  4702. (phases2 (vector (make-env '(0 0 .1 0 .9 1 1 1) :end samps :scaler (/ pi 2))
  4703. (make-env '(0 0 .1 0 .9 1 1 1) :end samps :scaler (/ pi 2))
  4704. (make-env '(0 0 .1 0 .9 1 1 1) :end samps :scaler (/ pi 2))))
  4705. (phases3 (vector (make-env '(0 1 1 1) :end samps :scaler (/ pi 2))
  4706. (make-env '(0 1 1 1) :end samps :scaler (/ pi 2))
  4707. (make-env '(0 1 1 1) :end samps :scaler (/ pi 2)))))
  4708. (do ((i 0 (+ i 1)))
  4709. ((= i samps))
  4710. (outa i (* .1 (polyoid-env gen1 0.0 amps1 phases1)))
  4711. (outb i (* .1 (polyoid-env gen2 0.0 amps2 phases2)))
  4712. (outc i (* .1 (polyoid-env gen3 0.0 amps3 phases3))))))
  4713. |#
  4714. ;;; --------------------------------------------------------------------------------
  4715. ;;;
  4716. ;;; noid -- sum of n sinusoids at arbitrary (default=random) initial phases
  4717. ;;;
  4718. ;;; for max peak (all cos), set phases arg to (make-vector n (/ pi 2))
  4719. ;;; for min peak, use one of the sets in peak-phases.scm (multiplied through by pi)
  4720. ;;;
  4721. ;;; since initial phases are 0 or pi in peak-phases.scm if n>20, this code could be optimized
  4722. (define* (make-noid (frequency 0.0) (n 1) phases (choice 'all))
  4723. (make-polyoid frequency
  4724. (let ((amps (make-vector (* 3 n) 0.0)))
  4725. (do ((i 1 (+ i 1))
  4726. (j 0 (+ j 3)))
  4727. ((> i n))
  4728. (case choice
  4729. ((all) (set! (amps j) i))
  4730. ((odd) (set! (amps j) (- (* 2 i) 1)))
  4731. ((prime) (set! (amps j) (some-primes (- i 1)))) ; defined below up to 1024th or so -- probably should use low-primes.scm
  4732. ((even) (set! (amps j) (max 1 (* 2 (- i 1))))))
  4733. (set! (amps (+ j 1)) (/ 1.0 n))
  4734. (cond ((vector? phases) (set! (amps (+ j 2)) (phases (- i 1))))
  4735. ((not phases) (set! (amps (+ j 2)) (random (* 2 pi))))
  4736. ((eq? phases 'max-peak) (set! (amps (+ j 2)) (/ pi 2)))))
  4737. (when (eq? phases 'min-peak)
  4738. (let ((vector-find-if (lambda (func vect)
  4739. (let ((len (length vect))
  4740. (result #f))
  4741. (do ((i 0 (+ i 1)))
  4742. ((or (= i len)
  4743. result)
  4744. result)
  4745. (set! result (func (vect i))))))))
  4746. (if (not (defined? 'noid-min-peak-phases))
  4747. (load "peak-phases.scm"))
  4748. (let ((min-dat (vector-find-if
  4749. (lambda (val)
  4750. (and (vector? val)
  4751. (= (val 0) n)
  4752. (let* ((a-val (val 1))
  4753. (a-len (length val))
  4754. (a-data (list a-val (val 2))))
  4755. (do ((k 2 (+ k 1)))
  4756. ((= k a-len))
  4757. (if (and (real? (val k))
  4758. (< (val k) a-val))
  4759. (begin
  4760. (set! a-val (val k))
  4761. (set! a-data (list a-val (val (+ k 1)))))))
  4762. a-data)))
  4763. (case choice
  4764. ((all) noid-min-peak-phases)
  4765. ((odd) nodd-min-peak-phases)
  4766. ((prime) primoid-min-peak-phases)
  4767. ((even) neven-min-peak-phases)))))
  4768. (if min-dat
  4769. (do ((rats (cadr min-dat))
  4770. (i 1 (+ i 1))
  4771. (j 0 (+ j 3)))
  4772. ((> i n))
  4773. (set! (amps (+ j 1)) (/ 1.0 n)) ;(/ 0.999 norm)) -- can't decide about this -- I guess it should be consistent with the #f case
  4774. (set! (amps (+ j 2)) (* pi (rats (- i 1)))))))))
  4775. amps)))
  4776. (define noid polyoid)
  4777. (define noid? polyoid?)
  4778. (define some-primes (vector 1
  4779. 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61
  4780. 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151
  4781. 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251
  4782. 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359
  4783. 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463
  4784. 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593
  4785. 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701
  4786. 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827
  4787. 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953
  4788. 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069
  4789. 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193 1201 1213
  4790. 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 1291 1297 1301 1303 1307 1319 1321
  4791. 1327 1361 1367 1373 1381 1399 1409 1423 1427 1429 1433 1439 1447 1451 1453 1459 1471 1481
  4792. 1483 1487 1489 1493 1499 1511 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 1597 1601
  4793. 1607 1609 1613 1619 1621 1627 1637 1657 1663 1667 1669 1693 1697 1699 1709 1721 1723 1733
  4794. 1741 1747 1753 1759 1777 1783 1787 1789 1801 1811 1823 1831 1847 1861 1867 1871 1873 1877
  4795. 1879 1889 1901 1907 1913 1931 1933 1949 1951 1973 1979 1987 1993 1997 1999 2003 2011 2017
  4796. 2027 2029 2039 2053 2063 2069 2081 2083 2087 2089 2099 2111 2113 2129 2131 2137 2141 2143
  4797. 2153 2161 2179 2203 2207 2213 2221 2237 2239 2243 2251 2267 2269 2273 2281 2287 2293 2297
  4798. 2309 2311 2333 2339 2341 2347 2351 2357 2371 2377 2381 2383 2389 2393 2399 2411 2417 2423
  4799. 2437 2441 2447 2459 2467 2473 2477 2503 2521 2531 2539 2543 2549 2551 2557 2579 2591 2593
  4800. 2609 2617 2621 2633 2647 2657 2659 2663 2671 2677 2683 2687 2689 2693 2699 2707 2711 2713
  4801. 2719 2729 2731 2741 2749 2753 2767 2777 2789 2791 2797 2801 2803 2819 2833 2837 2843 2851
  4802. 2857 2861 2879 2887 2897 2903 2909 2917 2927 2939 2953 2957 2963 2969 2971 2999 3001 3011
  4803. 3019 3023 3037 3041 3049 3061 3067 3079 3083 3089 3109 3119 3121 3137 3163 3167 3169 3181
  4804. 3187 3191 3203 3209 3217 3221 3229 3251 3253 3257 3259 3271 3299 3301 3307 3313 3319 3323
  4805. 3329 3331 3343 3347 3359 3361 3371 3373 3389 3391 3407 3413 3433 3449 3457 3461 3463 3467
  4806. 3469 3491 3499 3511 3517 3527 3529 3533 3539 3541 3547 3557 3559 3571 3581 3583 3593 3607
  4807. 3613 3617 3623 3631 3637 3643 3659 3671 3673 3677 3691 3697 3701 3709 3719 3727 3733 3739
  4808. 3761 3767 3769 3779 3793 3797 3803 3821 3823 3833 3847 3851 3853 3863 3877 3881 3889 3907
  4809. 3911 3917 3919 3923 3929 3931 3943 3947 3967 3989 4001 4003 4007 4013 4019 4021 4027 4049
  4810. 4051 4057 4073 4079 4091 4093 4099 4111 4127 4129 4133 4139 4153 4157 4159 4177 4201 4211
  4811. 4217 4219 4229 4231 4241 4243 4253 4259 4261 4271 4273 4283 4289 4297 4327 4337 4339 4349
  4812. 4357 4363 4373 4391 4397 4409 4421 4423 4441 4447 4451 4457 4463 4481 4483 4493 4507 4513
  4813. 4517 4519 4523 4547 4549 4561 4567 4583 4591 4597 4603 4621 4637 4639 4643 4649 4651 4657
  4814. 4663 4673 4679 4691 4703 4721 4723 4729 4733 4751 4759 4783 4787 4789 4793 4799 4801 4813
  4815. 4817 4831 4861 4871 4877 4889 4903 4909 4919 4931 4933 4937 4943 4951 4957 4967 4969 4973
  4816. 4987 4993 4999 5003 5009 5011 5021 5023 5039 5051 5059 5077 5081 5087 5099 5101 5107 5113
  4817. 5119 5147 5153 5167 5171 5179 5189 5197 5209 5227 5231 5233 5237 5261 5273 5279 5281 5297
  4818. 5303 5309 5323 5333 5347 5351 5381 5387 5393 5399 5407 5413 5417 5419 5431 5437 5441 5443
  4819. 5449 5471 5477 5479 5483 5501 5503 5507 5519 5521 5527 5531 5557 5563 5569 5573 5581 5591
  4820. 5623 5639 5641 5647 5651 5653 5657 5659 5669 5683 5689 5693 5701 5711 5717 5737 5741 5743
  4821. 5749 5779 5783 5791 5801 5807 5813 5821 5827 5839 5843 5849 5851 5857 5861 5867 5869 5879
  4822. 5881 5897 5903 5923 5927 5939 5953 5981 5987 6007 6011 6029 6037 6043 6047 6053 6067 6073
  4823. 6079 6089 6091 6101 6113 6121 6131 6133 6143 6151 6163 6173 6197 6199 6203 6211 6217 6221
  4824. 6229 6247 6257 6263 6269 6271 6277 6287 6299 6301 6311 6317 6323 6329 6337 6343 6353 6359
  4825. 6361 6367 6373 6379 6389 6397 6421 6427 6449 6451 6469 6473 6481 6491 6521 6529 6547 6551
  4826. 6553 6563 6569 6571 6577 6581 6599 6607 6619 6637 6653 6659 6661 6673 6679 6689 6691 6701
  4827. 6703 6709 6719 6733 6737 6761 6763 6779 6781 6791 6793 6803 6823 6827 6829 6833 6841 6857
  4828. 6863 6869 6871 6883 6899 6907 6911 6917 6947 6949 6959 6961 6967 6971 6977 6983 6991 6997
  4829. 7001 7013 7019 7027 7039 7043 7057 7069 7079 7103 7109 7121 7127 7129 7151 7159 7177 7187
  4830. 7193 7207 7211 7213 7219 7229 7237 7243 7247 7253 7283 7297 7307 7309 7321 7331 7333 7349
  4831. 7351 7369 7393 7411 7417 7433 7451 7457 7459 7477 7481 7487 7489 7499 7507 7517 7523 7529
  4832. 7537 7541 7547 7549 7559 7561 7573 7577 7583 7589 7591 7603 7607 7621 7639 7643 7649 7669
  4833. 7673 7681 7687 7691 7699 7703 7717 7723 7727 7741 7753 7757 7759 7789 7793 7817 7823 7829
  4834. 7841 7853 7867 7873 7877 7879 7883 7901 7907 7919 7927 7933 7937 7949 7951 7963 7993 8009
  4835. 8011 8017 8039 8053 8059 8069 8081 8087 8089 8093 8101 8111 8117 8123 8147 8161 8167 8171))
  4836. #|
  4837. (with-sound (:clipped #f)
  4838. (let ((samps 44100)
  4839. (gen (make-noid 100.0 3)))
  4840. (do ((i 0 (+ i 1)))
  4841. ((= i samps))
  4842. (outa i (noid gen)))))
  4843. (with-sound (:clipped #f :channels 2)
  4844. (let* ((samps 44100)
  4845. (n 10)
  4846. (gen (make-noid 1.0 n 'min-peak))
  4847. (gen2 (make-oscil n ((polyoid-partial-amps-and-phases gen) (- (length (polyoid-partial-amps-and-phases gen)) 1)))))
  4848. (do ((i 0 (+ i 1)))
  4849. ((= i samps))
  4850. (outa i (noid gen))
  4851. (outb i (oscil gen2)))))
  4852. (with-sound (:clipped #f)
  4853. (let ((samps 44100)
  4854. (gen (make-noid 100.0 10 'min-peak)))
  4855. (do ((i 0 (+ i 1)))
  4856. ((= i samps))
  4857. (outa i (noid gen)))))
  4858. (with-sound (:clipped #f :statistics #t)
  4859. (let ((samps 44100)
  4860. (gen (make-noid 10.0 1024 'min-peak)))
  4861. (do ((i 0 (+ i 1)))
  4862. ((= i samps))
  4863. (outa i (noid gen)))))
  4864. (with-sound (:clipped #f :channels 4)
  4865. (let ((samps 44100)
  4866. (gen1 (make-noid 100.0 32 'max-peak))
  4867. (gen2 (make-noid 100.0 32 (make-vector 32 0.0)))
  4868. (gen3 (make-noid 100.0 32))
  4869. (gen4 (make-noid 100.0 32 'min-peak)))
  4870. (do ((i 0 (+ i 1)))
  4871. ((= i samps))
  4872. (outa i (noid gen1 0.0))
  4873. (outb i (noid gen2 0.0))
  4874. (outc i (noid gen3 0.0))
  4875. (outd i (noid gen4 0.0)))))
  4876. (do ((i 0 (+ i 1)))
  4877. ((= i 4))
  4878. (with-sound (:clipped #f :output (string-append "test-noid-" (number->string i) ".snd"))
  4879. (let ((samps 44100)
  4880. (gen (make-noid 100.0 32 (if (= i 0) 'max-peak
  4881. (if (= i 1) (make-vector 32 0.0)
  4882. (if (= i 2) #f
  4883. 'min-peak))))))
  4884. (do ((i 0 (+ i 1)))
  4885. ((= i samps))
  4886. (outa i (noid gen))))))
  4887. (define (knoid n)
  4888. (with-sound (:channels 4 :statistics #t)
  4889. (let ((samps 100000)
  4890. (gen1 (make-noid 10.0 n 'min-peak 'all))
  4891. (gen2 (make-noid 10.0 n 'min-peak 'odd))
  4892. (gen3 (make-noid 10.0 n 'min-peak 'even))
  4893. (gen4 (make-noid 10.0 n 'min-peak 'prime)))
  4894. (do ((i 0 (+ i 1)))
  4895. ((= i samps))
  4896. (outa i (* 0.5 (noid gen1 0.0)))
  4897. (outb i (* 0.5 (noid gen2 0.0)))
  4898. (outc i (* 0.5 (noid gen3 0.0)))
  4899. (outd i (* 0.5 (noid gen4 0.0)))))))
  4900. (with-sound (:clipped #f)
  4901. (let ((samps 44100)
  4902. (gen (make-noid 100.0 19 (apply vector (map (lambda (n) (* pi n)) (list 0 1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 0 1) )))))
  4903. (do ((i 0 (+ i 1)))
  4904. ((= i samps))
  4905. (outa i (noid gen)))))
  4906. |#
  4907. #|
  4908. ;;; --------------------------------------------------------------------------------
  4909. ;;;
  4910. ;;; roid -- sum of n sinusoids at arbitrary (default=random) initial phases and amp r^n
  4911. (define* (make-roid (frequency 0.0) (n 1) (r 1.0) (phases #f))
  4912. (make-polyoid frequency
  4913. (let ((amps (make-vector (* 3 n) 0.0))
  4914. (rn (/ 1.0 n)))
  4915. (do ((i 1 (+ i 1))
  4916. (j 0 (+ j 3)))
  4917. ((> i n))
  4918. (set! (amps j) i)
  4919. (set! (amps (+ j 1)) rn)
  4920. (set! rn (* rn r))
  4921. (if (vector? phases)
  4922. (set! (amps (+ j 2)) (phases (- i 1)))
  4923. (if (not phases)
  4924. (set! (amps (+ j 2)) (random (* 2 pi)))
  4925. (if (eq? phases 'max-peak)
  4926. (set! (amps (+ j 2)) (/ pi 2))
  4927. ;; else min-peak, handled separately
  4928. ))))
  4929. (if (eq? phases 'min-peak)
  4930. (let ((vector-find-if (lambda (func vect)
  4931. (let ((len (length vect))
  4932. (result #f))
  4933. (do ((i 0 (+ i 1)))
  4934. ((or (= i len)
  4935. result)
  4936. result)
  4937. (set! result (func (vect i))))))))
  4938. (if (not (defined? 'roid-min-peak-phases))
  4939. (load "peak-phases.scm"))
  4940. (let ((min-dat (vector-find-if
  4941. (lambda (val)
  4942. (and val
  4943. (vector? val)
  4944. (= (val 0) n)
  4945. (let* ((a-val (val 1))
  4946. (a-len (length val))
  4947. (a-data (list a-val (val 2))))
  4948. (do ((k 2 (+ k 1)))
  4949. ((= k a-len))
  4950. (if (and (number? (val k))
  4951. (< (val k) a-val))
  4952. (begin
  4953. (set! a-val (val k))
  4954. (set! a-data (list a-val (val (+ k 1)))))))
  4955. a-data)))
  4956. roid-min-peak-phases)))
  4957. (if min-dat
  4958. (let* ((norm (car min-dat))
  4959. (rats (cadr min-dat))
  4960. (rn (/ 0.999 norm)))
  4961. (do ((i 1 (+ i 1))
  4962. (j 0 (+ j 3)))
  4963. ((> i n))
  4964. (set! (amps (+ j 1)) rn)
  4965. (set! rn (* rn r))
  4966. (set! (amps (+ j 2)) (* pi (rats (- i 1))))))))))
  4967. amps)))
  4968. (define roid polyoid)
  4969. (define roid? polyoid?)
  4970. |#
  4971. #|
  4972. (with-sound (:clipped #f)
  4973. (let ((samps 44100)
  4974. (gen (make-roid 100.0 6 0.5 'min-peak)))
  4975. (do ((i 0 (+ i 1)))
  4976. ((= i samps))
  4977. (outa i (roid gen)))))
  4978. |#
  4979. ;;; ---------------- old waveshape generator ----------------
  4980. (define waveshape? polyshape?)
  4981. (define waveshape polyshape)
  4982. (define* (make-waveshape (frequency *clm-default-frequency*)
  4983. (partials '(1 1))
  4984. wave
  4985. (size *clm-table-size*)) ; size arg is for backwards compatibility
  4986. (make-polyshape frequency (if wave
  4987. (values :coeffs wave)
  4988. (values :partials partials))))
  4989. (define* (partials->waveshape partials (size *clm-table-size*))
  4990. (partials->polynomial partials))
  4991. ;;; ---------------- tanh(sin(x)) ----------------
  4992. (defgenerator (tanhsin
  4993. :make-wrapper (lambda (g)
  4994. (set! (g 'osc) (make-oscil (g 'frequency) (g 'initial-phase)))
  4995. (set! (g 'frequency) (hz->radians (g 'frequency))) ; so that mus-frequency works at least read side
  4996. g))
  4997. (frequency *clm-default-frequency*) (r 1.0) (initial-phase 0.0)
  4998. (osc #f) fm)
  4999. (define tanhsin
  5000. (let ((documentation "(make-tanhsin (frequency 0.0) (r 1.0) (initial-phase 0.0) returns a tanhsin
  5001. generator. (tanhsin gen (fm 0.0)) produces tanh(r*sin) which approaches a square wave as r increases."))
  5002. (lambda* (gen (fm 0.0))
  5003. (let-set! gen 'fm fm)
  5004. (with-let gen
  5005. (tanh (* r (oscil osc fm)))))))
  5006. ;;; ---------------- moving-fft ----------------
  5007. (define last-moving-fft-window #f)
  5008. (define moving-fft-methods
  5009. (list
  5010. (cons 'mus-data (lambda (g) (g 'data)))
  5011. (cons 'mus-xcoeffs (lambda (g) (g 'rl)))
  5012. (cons 'mus-ycoeffs (lambda (g) (g 'im)))
  5013. (cons 'mus-run (lambda (g arg1 arg2) (moving-fft g)))))
  5014. (defgenerator (moving-fft
  5015. :make-wrapper (lambda (g)
  5016. (let ((n (g 'n)))
  5017. (set! (g 'rl) (make-float-vector n))
  5018. (set! (g 'im) (make-float-vector n))
  5019. (set! (g 'data) (make-float-vector n))
  5020. (set! (g 'window)
  5021. (if (and last-moving-fft-window
  5022. (= n (length last-moving-fft-window)))
  5023. last-moving-fft-window
  5024. (set! last-moving-fft-window (make-fft-window hamming-window n))))
  5025. (float-vector-scale! (g 'window) (/ 2.0 (* 0.54 n)))
  5026. (set! (g 'outctr) (+ n 1)) ; first time fill flag
  5027. g))
  5028. :methods moving-fft-methods)
  5029. (input #f) (n 512) (hop 128) (outctr 0)
  5030. (rl #f) (im #f) (data #f)
  5031. (window #f))
  5032. (define moving-fft
  5033. (let ((documentation "(make-moving-fft reader (size 512) (hop 128)) returns a moving-fft generator. (moving-fft gen)
  5034. produces an FFT (polar form) of 'size' samples every 'hop' samples, taking input from the readin generator 'reader'.
  5035. The magnitudes are available as mus-xcoeffs, the phases as mus-ycoeffs, and the current input data as mus-data."))
  5036. (lambda (gen)
  5037. (with-let gen
  5038. (let ((new-data #f))
  5039. (if (>= outctr hop)
  5040. (let ((fft-window window))
  5041. (if (> outctr n) ; must be first time through -- fill data array
  5042. (do ((i 0 (+ i 1)))
  5043. ((= i n))
  5044. (float-vector-set! data i (readin input)))
  5045. (let ((mid (- n hop)))
  5046. (float-vector-move! data 0 hop)
  5047. (do ((i mid (+ i 1)))
  5048. ((= i n))
  5049. (float-vector-set! data i (readin input)))))
  5050. (set! outctr 0)
  5051. (set! new-data #t)
  5052. (fill! im 0.0)
  5053. (float-vector-subseq data 0 n rl)
  5054. (float-vector-multiply! rl fft-window)
  5055. (mus-fft rl im n 1)
  5056. (rectangular->polar rl im)))
  5057. (set! outctr (+ outctr 1))
  5058. new-data)))))
  5059. #|
  5060. (let* ((snd (new-sound))
  5061. (rd (make-readin "oboe.snd"))
  5062. (ft (make-moving-fft rd))
  5063. (data (make-float-vector 256)))
  5064. (set! (lisp-graph?) #t)
  5065. (do ((i 0 (+ i 1)))
  5066. ((= i 10000))
  5067. (if (moving-fft ft)
  5068. (begin
  5069. (float-vector-subseq (mus-xcoeffs ft) 0 255 data)
  5070. (graph data "fft" 0.0 11025.0 0.0 0.1 snd 0 #t))))
  5071. (close-sound snd))
  5072. |#
  5073. ;;; ---------------- moving spectrum ----------------
  5074. (defgenerator (moving-spectrum
  5075. :make-wrapper (lambda (g)
  5076. (let ((n (g 'n)))
  5077. (set! (g 'amps) (make-float-vector n))
  5078. (set! (g 'phases) (make-float-vector n))
  5079. (set! (g 'amp-incs) (make-float-vector n))
  5080. (set! (g 'freqs) (make-float-vector n))
  5081. (set! (g 'freq-incs) (make-float-vector n))
  5082. (set! (g 'new-freq-incs) (make-float-vector n))
  5083. (set! (g 'data) (make-float-vector n))
  5084. (set! (g 'fft-window) (make-fft-window hamming-window n))
  5085. (float-vector-scale! (g 'fft-window) (/ 2.0 (* 0.54 n)))
  5086. (set! (g 'outctr) (+ n 1)) ; first time fill flag
  5087. g)))
  5088. (input #f) (n 512) (hop 128)
  5089. (outctr 0)
  5090. (amps #f) (phases #f)
  5091. (amp-incs #f) (freqs #f) (freq-incs #f) (new-freq-incs #f)
  5092. (fft-window #f)
  5093. (data #f) (dataloc 0))
  5094. (define (moving-spectrum gen)
  5095. (with-let gen
  5096. (when (>= outctr hop)
  5097. (if (> outctr n) ; must be first time through -- fill data array
  5098. (do ((i 0 (+ i 1)))
  5099. ((= i n))
  5100. (float-vector-set! data i (readin input)))
  5101. (begin
  5102. (float-vector-move! data 0 hop)
  5103. (do ((i (- n hop) (+ i 1)))
  5104. ((= i n))
  5105. (float-vector-set! data i (readin input)))))
  5106. (set! outctr 0) ; -1??
  5107. (set! dataloc (modulo dataloc n))
  5108. (fill! new-freq-incs 0.0)
  5109. (do ((i 0 (+ i 1))
  5110. (j dataloc (+ j 1)))
  5111. ((= j n))
  5112. (float-vector-set! amp-incs j (* (float-vector-ref fft-window i) (float-vector-ref data i))))
  5113. (if (> dataloc 0)
  5114. (do ((i (- n dataloc) (+ i 1))
  5115. (j 0 (+ j 1)))
  5116. ((= j dataloc))
  5117. (float-vector-set! amp-incs j (* (float-vector-ref fft-window i) (float-vector-ref data i)))))
  5118. (set! dataloc (+ dataloc hop))
  5119. (mus-fft amp-incs new-freq-incs n 1)
  5120. (rectangular->polar amp-incs new-freq-incs)
  5121. (let ((scl (/ 1.0 hop))
  5122. (kscl (/ two-pi n)))
  5123. (float-vector-subtract! amp-incs amps)
  5124. (float-vector-scale! amp-incs scl)
  5125. (do ((n2 (/ n 2))
  5126. (i 0 (+ i 1))
  5127. (ks 0.0 (+ ks kscl)))
  5128. ((= i n2))
  5129. (let ((diff (modulo (- (new-freq-incs i) (freq-incs i)) two-pi)))
  5130. (set! (freq-incs i) (new-freq-incs i))
  5131. (if (> diff pi) (set! diff (- diff (* 2 pi))))
  5132. (if (< diff (- pi)) (set! diff (+ diff (* 2 pi))))
  5133. (set! (new-freq-incs i) (+ (* diff scl) ks))))
  5134. (float-vector-subtract! new-freq-incs freqs)
  5135. (float-vector-scale! new-freq-incs scl)))
  5136. (set! outctr (+ outctr 1))
  5137. (float-vector-add! amps amp-incs)
  5138. (float-vector-add! freqs new-freq-incs)
  5139. (float-vector-add! phases freqs)))
  5140. (define (test-sv)
  5141. ;; sv-amps = pv-amps (but len is diff)
  5142. ;; sv-phases = pv-phases
  5143. ;; sv-freqs = pv-phase-increments
  5144. (let ((pv (make-phase-vocoder (make-readin "oboe.snd") ))
  5145. (sv (make-moving-spectrum (make-readin "oboe.snd"))))
  5146. (let ((pv-amps (phase-vocoder-amps pv))
  5147. (pv-incrs (phase-vocoder-phase-increments pv))
  5148. (sv-amps (sv 'amps))
  5149. (sv-freqs (sv 'freqs)))
  5150. (call-with-exit
  5151. (lambda (quit)
  5152. (do ((k 0 (+ k 1)))
  5153. ((= k 20))
  5154. (do ((i 0 (+ i 1)))
  5155. ((= i 2000))
  5156. (phase-vocoder pv))
  5157. (do ((i 0 (+ i 1)))
  5158. ((= i 2000))
  5159. (moving-spectrum sv))
  5160. (do ((i 0 (+ i 1)))
  5161. ((= i 256))
  5162. (if (fneq (sv-amps i) (pv-amps i))
  5163. (begin
  5164. (format *stderr* ";test-sv (generators) ~D amps: ~A ~A" i (sv-amps i) (pv-amps i))
  5165. (quit)))
  5166. (if (> (abs (- (sv-freqs i) (pv-incrs i))) .25)
  5167. (begin
  5168. (format *stderr* ";test-sv (generators) ~D freqs: ~A ~A" i (sv-freqs i) (pv-incrs i))
  5169. (quit))))))))))
  5170. #|
  5171. (define* (sine-bank amps phases size)
  5172. (let ((len (or size (length amps)))
  5173. (sum 0.0))
  5174. (do ((i 0 (+ i 1)))
  5175. ((= i len))
  5176. (set! sum (+ sum (* (amps i)
  5177. (sin (phases i))))))
  5178. sum))
  5179. (with-sound (:channels 2)
  5180. (let* ((gen (make-moving-spectrum (make-readin "oboe.snd")))
  5181. (pv (make-phase-vocoder (make-readin "oboe.snd")))
  5182. (samps (framples "oboe.snd")))
  5183. (do ((i 0 (+ i 1)))
  5184. ((= i samps))
  5185. (moving-spectrum gen)
  5186. (outa i (sine-bank (gen 'amps) (gen 'phases) 256)) ; size = n/2 as in pv
  5187. (outb i (phase-vocoder pv)))))
  5188. ; :(channel-distance 0 0 0 1)
  5189. ; 7.902601100022e-9
  5190. |#
  5191. ;;; moving spectrum returns freqs in radians, and does not try to find the interpolated peak,
  5192. ;;; so we need another version that returns current freq/amp pairs that can be used directly in oscil
  5193. ;;; This is the main portion of the "pins" instrument (also find-pitch in examp.scm)
  5194. ;;; ---------------- moving scentroid ----------------
  5195. (defgenerator (moving-scentroid
  5196. :make-wrapper (lambda (g)
  5197. (let ((n (g 'size)))
  5198. (set! (g 'rl) (make-float-vector n))
  5199. (set! (g 'im) (make-float-vector n))
  5200. (set! (g 'dly) (make-delay n))
  5201. (set! (g 'rms) (make-moving-rms n))
  5202. (set! (g 'hop) (floor (/ *clm-srate* (g 'rfreq))))
  5203. (set! (g 'binwidth) (/ *clm-srate* n))
  5204. g)))
  5205. (dbfloor -40.0) (rfreq 100.0)
  5206. (size 4096) (hop 1024) (outctr 0)
  5207. (curval 0.0) (binwidth 1.0)
  5208. (rl #f) (im #f)
  5209. (dly #f) (rms #f) x)
  5210. (define* (moving-scentroid gen (x 0.0))
  5211. (let-set! gen 'x x)
  5212. (with-let gen
  5213. (let ((rms (moving-rms rms x)))
  5214. (if (>= outctr hop)
  5215. (begin
  5216. (set! outctr 0)
  5217. (if (< (linear->db rms) dbfloor)
  5218. (set! curval 0.0)
  5219. (let* ((data (mus-data dly))
  5220. (fft2 (/ size 2)))
  5221. (fill! im 0.0)
  5222. (float-vector-subseq data 0 (- size 1) rl)
  5223. (mus-fft rl im size 1) ; we can use the delay line contents un-reordered because phases are ignored here
  5224. (rectangular->magnitudes rl im)
  5225. (do ((numsum 0.0)
  5226. (densum 0.0)
  5227. (k 0 (+ k 1)))
  5228. ((= k fft2)
  5229. (set! curval (/ (* binwidth numsum) densum)))
  5230. (set! numsum (+ numsum (* k (rl k))))
  5231. (set! densum (+ densum (rl k)))))))))
  5232. (delay dly x) ; our "sliding window" on the input data
  5233. (set! outctr (+ outctr 1))
  5234. curval))
  5235. #|
  5236. (let* ((snd (open-sound "oboe.snd"))
  5237. (cur-srate (srate snd))
  5238. (old-srate *clm-srate*))
  5239. (set! *clm-srate* cur-srate)
  5240. (let ((scn (make-moving-scentroid -40.0 100.0 128))
  5241. (vals (scentroid "oboe.snd" 0.0 1.1 -40.0 100.0 128))
  5242. (k 0))
  5243. (let ((data (channel->float-vector 0 22050 snd 0)))
  5244. (close-sound snd)
  5245. (do ((i 0 (+ i 1)))
  5246. ((= i (scn 'size)))
  5247. (moving-scentroid scn (data i)))
  5248. (set! (scn 'outctr) (scn 'hop))
  5249. (do ((i (scn 'size) (+ i 1))
  5250. (j 0 (+ j 1)))
  5251. ((= i 22050))
  5252. (let ((val (moving-scentroid scn (data i))))
  5253. (if (= (modulo j (scn 'hop)) 0)
  5254. (begin
  5255. (format () "[~A ~A]~%" val (vals k))
  5256. (set! k (+ k 1)))))))
  5257. (set! *clm-srate* old-srate)))
  5258. |#
  5259. ;;; ---------------- moving-autocorrelation ----------------
  5260. (define moving-autocorrelation-methods
  5261. (list
  5262. (cons 'mus-run (lambda (g arg1 arg2) (moving-autocorrelation g)))
  5263. (cons 'mus-data (lambda (g) (g 'rl)))))
  5264. (defgenerator (moving-autocorrelation
  5265. :make-wrapper (lambda (g)
  5266. (let ((n (g 'n)))
  5267. (set! (g 'rl) (make-float-vector n))
  5268. (set! (g 'im) (make-float-vector n))
  5269. (set! (g 'data) (make-float-vector n))
  5270. (set! (g 'outctr) (+ n 1)) ; first time fill flag
  5271. g))
  5272. :methods moving-autocorrelation-methods)
  5273. (input #f) (n 512) (hop 128) (outctr 0)
  5274. (rl #f) (im #f) (data #f))
  5275. (define moving-autocorrelation
  5276. (let ((documentation "(make-moving-autocorrelation reader (size 512) (hop 128)) returns a moving-autocorrelation
  5277. generator. (moving-autocorrelation gen) produces the autocorrelation of 'size' samples every 'hop' samples, taking
  5278. input from the readin generator 'reader'. The output data is available via mus-data."))
  5279. (lambda (gen)
  5280. (with-let gen
  5281. (let ((new-data #f))
  5282. (if (>= outctr hop)
  5283. (begin
  5284. (if (> outctr n) ; must be first time through -- fill data array
  5285. (do ((i 0 (+ i 1)))
  5286. ((= i n))
  5287. (float-vector-set! data i (readin input)))
  5288. (begin
  5289. (float-vector-move! data 0 hop)
  5290. (do ((i (- n hop) (+ i 1)))
  5291. ((= i n))
  5292. (float-vector-set! data i (readin input)))))
  5293. (set! outctr 0)
  5294. (set! new-data #t)
  5295. (fill! im 0.0)
  5296. (float-vector-subseq data 0 (- n 1) rl)
  5297. (autocorrelate rl)))
  5298. (set! outctr (+ outctr 1))
  5299. new-data)))))
  5300. ;;; ---------------- moving-pitch ----------------
  5301. (define moving-pitch-methods
  5302. (list
  5303. (cons 'mus-run (lambda (g arg1 arg2) (moving-pitch g)))))
  5304. (defgenerator (moving-pitch
  5305. :make-wrapper (lambda (g)
  5306. (set! (g 'ac) (make-moving-autocorrelation
  5307. (g 'input)
  5308. (g 'n)
  5309. (g 'hop)))
  5310. g)
  5311. :methods moving-pitch-methods)
  5312. (input #f) (n 512) (hop 128)
  5313. (ac #f) (val 0.0))
  5314. (define (moving-pitch gen)
  5315. (with-let gen
  5316. (when (moving-autocorrelation ac)
  5317. (let ((data (mus-data ac)))
  5318. (let ((peak 0.0)
  5319. (peak-loc 0)
  5320. (len (length data)))
  5321. (do ((i 8 (+ i 1))) ; assume we're not in the top few octaves
  5322. ((= i len))
  5323. (let ((apk (abs (data i))))
  5324. (if (> apk peak)
  5325. (begin
  5326. (set! peak apk)
  5327. (set! peak-loc i)))))
  5328. (if (or (= peak 0.0)
  5329. (= peak-loc 0))
  5330. (set! val 0.0)
  5331. (let ((la (data (- peak-loc 1)))
  5332. (ra (data (+ peak-loc 1))))
  5333. (let ((logla (log (/ (max la .0000001) peak) 10)) ; (positive la)?
  5334. (logra (log (/ (max ra .0000001) peak) 10)))
  5335. (set! val
  5336. (/ *clm-srate*
  5337. (+ peak-loc (/ (* 0.5 (- logla logra))
  5338. (+ logla logra)))))))))))
  5339. val))
  5340. #|
  5341. (let* ((rd (make-readin "oboe.snd"))
  5342. (cur-srate (srate "oboe.snd"))
  5343. (old-srate *clm-srate*))
  5344. (set! *clm-srate* cur-srate)
  5345. (let* ((scn (make-moving-pitch rd))
  5346. (last-pitch 0.0)
  5347. (pitch 0.0))
  5348. (do ((i 0 (+ i 1)))
  5349. ((= i 22050))
  5350. (set! last-pitch pitch)
  5351. (set! pitch (moving-pitch scn))
  5352. (if (not (= last-pitch pitch))
  5353. (format () "~A: ~A~%" (* 1.0 (/ i cur-srate)) pitch))))
  5354. (set! *clm-srate* old-srate))
  5355. |#
  5356. #|
  5357. (define (abel k)
  5358. ;; sum i from 1 to k (-1)^(i + 1) * (sin i) / i
  5359. (with-sound (:clipped #f :statistics #t)
  5360. (let ((harmonics (make-float-vector (* 2 k))))
  5361. (do ((i 1 (+ i 1))
  5362. (j 0 (+ j 2))
  5363. (n -1 (- n)))
  5364. ((= i k))
  5365. (set! (harmonics j) i)
  5366. (set! (harmonics (+ j 1)) (/ n i)))
  5367. (let ((gen (make-polywave 100.0 :partials (normalize-partials harmonics))))
  5368. (do ((i 0 (+ i 1)))
  5369. ((= i 100000))
  5370. (outa i (polywave gen)))))))
  5371. (define* (adds num freq e amp v (type mus-chebyshev-first-kind))
  5372. (with-sound (:clipped #f :statistics #t :play #t)
  5373. (let ((harmonics (make-float-vector (* 2 num)))
  5374. (freqe (make-env e :length num)))
  5375. (do ((i 1 (+ i 1))
  5376. (j 0 (+ j 2)))
  5377. ((= i num))
  5378. (set! (harmonics j) i)
  5379. (set! (harmonics (+ j 1)) (env freqe)))
  5380. (let ((gen (make-polywave freq :partials (normalize-partials harmonics) :type type))
  5381. (vib (make-oscil 5)))
  5382. (do ((i 0 (+ i 1)))
  5383. ((= i 100000))
  5384. (outa i (* amp (polywave gen (* (hz->radians v) (oscil vib))))))))))
  5385. ;(adds 200 20 '(0 0 10 1 12 0 20 0 24 .2 35 0 46 0 57 .1 68 0) .5 2)
  5386. ;(adds 300 15 '(0 0 10 1 12 0 20 0 24 .2 35 0 46 0 57 .1 68 0) .5 3)
  5387. |#
  5388. #|
  5389. (defgenerator (circler
  5390. :make-wrapper (lambda (g)
  5391. (set! (g 'frequency) (hz->radians (g 'frequency)))
  5392. g))
  5393. (frequency *clm-default-frequency*) (angle 0.0) fm)
  5394. (define circler
  5395. (let ((documentation "(make-circler (frequency 0.0) returns a circler generator. (circler gen (fm 0.0)) produces a waveform made up of half circles"))
  5396. (lambda* (gen (fm 0.0))
  5397. (let-set! gen 'fm fm)
  5398. (with-let gen
  5399. (let* ((x (modulo angle (* 2 pi)))
  5400. (xx (/ (* 4 x) (* 2 pi)))
  5401. (y (if (< xx 2)
  5402. (sqrt (- 1 (* (- 1 xx) (- 1 xx))))
  5403. (- (sqrt (- 1 (* (- 3 xx) (- 3 xx))))))))
  5404. (set! angle (+ x fm frequency))
  5405. y)))))
  5406. (with-sound (:clipped #f :statistics #t)
  5407. (let ((gen (make-circler 10.0)))
  5408. (do ((i 0 (+ i 1)))
  5409. ((= i 20000))
  5410. (outa i (circler gen)))))
  5411. ;;; odd harmonics: 1, .18 .081 .048 .033 .024, .019
  5412. |#
  5413. #|
  5414. ;; "extremal trigonometric polynomials"
  5415. (define (extremal-trig N freq)
  5416. (with-sound ()
  5417. (let ((tan-scl (tan (/ pi (* 2 (+ N 1)))))
  5418. (incr (hz->radians freq)))
  5419. (do ((k 1 (+ k 1)))
  5420. ((= k N))
  5421. (let ((cos-coeff (* tan-scl (sin (/ (* k pi) (+ N 1)))))
  5422. (kincr (* k incr)))
  5423. (do ((i 0 (+ i 1))
  5424. (x 0.0 (+ x kincr)))
  5425. ((= i 40000))
  5426. (outa i (* cos-coeff (cos x)))))))))
  5427. |#
  5428. ;;; ---------------- flocsig (flanged locsig) ----------------
  5429. (defgenerator (flocsig
  5430. ;; assume stereo out/rev
  5431. :make-wrapper (lambda (g)
  5432. (set! (g 'maxd) (ceiling (g 'amplitude))) ; was amplitude?
  5433. (set! (g 'out1) (make-float-vector (g 'maxd)))
  5434. (set! (g 'out2) (make-float-vector (g 'maxd)))
  5435. (set! (g 'ri) (make-rand-interp
  5436. :frequency (g 'frequency)
  5437. :amplitude (- (g 'amplitude) 1.0)))
  5438. (if (not (g 'offset))
  5439. (set! (g 'offset) (mus-random (* 0.3 (g 'amplitude)))))
  5440. g))
  5441. (reverb-amount 0.0) (frequency 1.0) (amplitude 2.0) offset
  5442. (maxd 0)
  5443. (out1 #f) (out2 #f) (outloc 0)
  5444. (ri #f) samp input)
  5445. (define 1/sqrt2 (/ 1.0 (sqrt 2.0)))
  5446. (define (flocsig gen samp input)
  5447. ;; signal position and per-channel-delay depends on rand-interp
  5448. (let-set! gen 'samp samp)
  5449. (let-set! gen 'input input)
  5450. (with-let gen
  5451. (let ((pos (min (max (+ (rand-interp ri) offset)
  5452. (- amplitude))
  5453. amplitude))
  5454. (loc outloc))
  5455. (let ((dly1 (abs (min 0.0 pos)))
  5456. (dly2 (max 0.0 pos)))
  5457. (let ((amp1 (if (<= pos -1.0) 1.0
  5458. (if (>= pos 1.0) 0.0
  5459. (* (sqrt (- 1.0 pos)) 1/sqrt2))))
  5460. (amp2 (if (<= pos -1.0) 0.0
  5461. (if (>= pos 1.0) 1.0
  5462. (* (sqrt (+ 1.0 pos)) 1/sqrt2))))
  5463. (frac1 (- dly1 (floor dly1)))
  5464. (frac2 (- dly2 (floor dly2))))
  5465. (let ((loc10 (modulo (+ loc (floor dly1)) maxd)))
  5466. (set! (out1 loc10) (+ (out1 loc10) (* amp1 input (- 1.0 frac1)))))
  5467. (let ((loc11 (modulo (+ loc 1 (floor dly1)) maxd)))
  5468. (set! (out1 loc11) (+ (out1 loc11) (* amp1 input frac1))))
  5469. (let ((loc20 (modulo (+ loc (floor dly2)) maxd)))
  5470. (set! (out2 loc20) (+ (out2 loc20) (* amp2 input (- 1.0 frac2)))))
  5471. (let ((loc21 (modulo (+ loc 1 (floor dly2)) maxd)))
  5472. (set! (out2 loc21) (+ (out2 loc21) (* amp2 input frac2))))))
  5473. (let ((val1 (out1 loc))
  5474. (val2 (out2 loc)))
  5475. (set! (out1 loc) 0.0)
  5476. (set! (out2 loc) 0.0)
  5477. (set! loc (+ loc 1))
  5478. (if (= loc maxd) (set! loc 0))
  5479. (outa samp val1)
  5480. (outb samp val2)
  5481. (if (> reverb-amount 0.0)
  5482. (begin
  5483. (outa samp (* reverb-amount val1) *reverb*)
  5484. (outb samp (* reverb-amount val2) *reverb*)))
  5485. (set! outloc loc)))))
  5486. ;;; --------------------------------------------------------------------------------
  5487. ;;; old version of one-pole-all-pass
  5488. #|
  5489. (defgenerator one-pole-allpass coeff input x1 y1)
  5490. (define (one-pole-allpass gen input)
  5491. (let-set! gen 'input input)
  5492. (with-let gen
  5493. (set! y1 (+ x1 (* coeff (- input y1))))
  5494. (set! x1 input)
  5495. y1))
  5496. (defgenerator one-pole-allpass-bank coeff input x1 y1 x2 y2 x3 y3 x4 y4 x5 y5 x6 y6 x7 y7 x8 y8)
  5497. (define (one-pole-allpass-bank gen input)
  5498. (let-set! gen 'input input)
  5499. (with-let gen
  5500. (set! y1 (+ x1 (* coeff (- input y1))))
  5501. (set! x1 input)
  5502. (set! y2 (+ x2 (* coeff (- y1 y2))))
  5503. (set! x2 y1)
  5504. (set! y3 (+ x3 (* coeff (- y2 y3))))
  5505. (set! x3 y2)
  5506. (set! y4 (+ x4 (* coeff (- y3 y4))))
  5507. (set! x4 y3)
  5508. (set! y5 (+ x5 (* coeff (- y4 y5))))
  5509. (set! x5 y4)
  5510. (set! y6 (+ x6 (* coeff (- y5 y6))))
  5511. (set! x6 y5)
  5512. (set! y7 (+ x7 (* coeff (- y6 y7))))
  5513. (set! x7 y6)
  5514. (set! y8 (+ x8 (* coeff (- y7 y8))))
  5515. (set! x8 y7)
  5516. y8))
  5517. (defgenerator expseg currentValue targetValue r)
  5518. (define (expseg gen r)
  5519. (let-set! gen 'r r)
  5520. (with-let gen
  5521. (set! currentValue (+ (* r targetValue) (* (- 1.0 r) currentValue)))))
  5522. ;(set! currentValue (+ currentValue (* r (- targetValue currentValue))))))
  5523. ;; (bil) this is slightly different (getting clicks)
  5524. (define (make-one-pole-swept)
  5525. (vector 0.0))
  5526. (define (one-pole-swept gen input coef)
  5527. ;; signal controlled one-pole lowpass filter
  5528. (set! (gen 0) (- (* (+ 1.0 coef) input) (* coef (gen 0)))))
  5529. (define (make-pnoise)
  5530. (vector 16383))
  5531. (define (pnoise gen x)
  5532. ;; very special noise generator
  5533. (set! (gen 0) (logand (floor (+ (* (gen 0) 1103515245) 12345)) #xffffffff))
  5534. ;; (bil) added the logand -- otherwise we get an overflow somewhere
  5535. (* x (- (* (modulo (floor (/ (gen 0) 65536.0)) 65536) 0.0000305185) 1.0)))
  5536. ;; this looks nutty to me -- was it originally running in 32 bits?
  5537. (define pn-gen 16383)
  5538. (define (pnoise x)
  5539. ;; very special noise generator
  5540. (set! pn-gen (logand (+ (* pn-gen 1103515245) 12345) #xffffffff))
  5541. ;; (bil) added the logand -- otherwise we get an overflow somewhere, also removed floor
  5542. (* x (- (* pn-gen 4.6566128730774e-10) 1.0)))
  5543. |#
  5544. ;;; --------------------------------------------------------------------------------
  5545. (define (calling-all-generators)
  5546. ;; for snd-test
  5547. (with-sound (:play #f)
  5548. (lutish 0 1 440 .1)
  5549. (oboish 1 1 300 .1 '(0 0 1 1 2 0))
  5550. (nkssber 2 1 1000 100 5 5 0.5)
  5551. (stringy 3 1 1000 .5)
  5552. (ercoser 4 1 100 .5 0.1)
  5553. (bouncy 5 2 300 .5 5 10)
  5554. (pianoy 6 3 100 .5)
  5555. (pianoy1 7 4 200 .5 1 .1)
  5556. (pianoy2 8 1 100 .5)
  5557. (glassy 9 .1 1000 .5)
  5558. (machine1 10 .3 100 540 0.5 3.0 0.0)
  5559. (organish 11 .4 100 .5 1.0 #f)
  5560. (brassy 12 4 50 .5 '(0 0 1 1 10 1 11 0) '(0 1 1 0) 1000)))