-
Notifications
You must be signed in to change notification settings - Fork 0
/
maraca.ins
135 lines (131 loc) · 4.96 KB
/
maraca.ins
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
;;; Perry Cook's maraca from CMJ vol 21 no 3 (Fall 97) p 44
(definstrument maraca (beg dur &optional (amp .1)
(sound-decay 0.95)
(system-decay 0.999)
(probability .0625)
(shell-freq 3200.0)
(shell-reso 0.96))
(let* ((st (floor (* *srate* beg)))
(nd (+ st (floor (* *srate* dur))))
(temp 0.0)
(shake-energy 0.0)
(snd-level 0.0)
(input 0.0)
(output (make-double-array 2))
(coeffs (make-double-array 2))
(num-beans 64)
(j 0)
(sndamp (/ amp 16384.0))
(srate4 (floor *srate* 4))
(gain (/ (* (log num-beans 4) 40) num-beans)))
;; gourd resonance filter
(setf (aref coeffs 0) (double (* -2.0 shell-reso (cos (hz->radians shell-freq)))))
(setf (aref coeffs 1) (double (* shell-reso shell-reso)))
(run
(loop for i from st to nd do
(when (< temp two-pi)
;; shake over 50msec and add shake energy
(incf temp (hz->radians 20))
(incf shake-energy (- 1.0 (cos temp))))
(when (= j srate4) ;shake 4 times/sec
(setf temp 0.0)
(setf j 0))
(incf j)
(setf shake-energy (* shake-energy system-decay))
;; if collision, add energy
(if (< (random 1.0) probability) (incf snd-level (* gain shake-energy)))
;; actual sound is random
(setf input (* snd-level (centered-random 1.0)))
;; compute exponential sound decay
(setf snd-level (* snd-level sound-decay))
;; gourd resonance filter calc
(setf input (- input
(* (aref output 0) (aref coeffs 0))
(* (aref output 1) (aref coeffs 1))))
(setf (aref output 1) (double (aref output 0)))
(setf (aref output 0) (double input))
;; extra zero for spectral shape, also fixup amp since Perry is assuming maxamp 16384
(outa i (* sndamp (- (aref output 0) (aref output 1))))))))
;;; maraca: (with-sound () (maraca 0 5 .5))
;;; cabasa: (with-sound () (maraca 0 5 .5 0.95 0.997 0.5 3000.0 0.7))
(definstrument big-maraca (beg dur &optional (amp .1)
(sound-decay 0.95)
(system-decay 0.999)
(probability .0625)
(shell-freqs '(3200.0))
(shell-resos '(0.96))
(randiff .01)
(with-filters t))
;; like maraca, but takes a list of resonances and includes low-pass filter (or no filter)
(let* ((st (floor (* *srate* beg)))
(nd (+ st (floor (* *srate* dur))))
(temp 0.0)
(temp1 0.0)
(resn (length shell-freqs))
(shake-energy 0.0)
(snd-level 0.0)
(input 0.0)
(sum 0.0)
(last-sum 0.0)
(last-diff 0.0)
(diff 0.0)
(output (make-double-array (list resn 2)))
(coeffs (make-double-array (list resn 2)))
(basesf (make-double-array resn))
(num-beans 64)
(j 0)
(sndamp (/ amp (* 16384.0 resn)))
(srate4 (floor *srate* 4))
(gain (/ (* (log num-beans 4) 40) num-beans)))
;; gourd resonance filters
(loop for i from 0 below resn and shell-freq in shell-freqs and shell-reso in shell-resos do
(setf (aref coeffs i 0) (double (* -2.0 shell-reso (cos (hz->radians shell-freq)))))
(setf (aref basesf i) (double (aref coeffs i 0)))
(setf (aref coeffs i 1) (double (* shell-reso shell-reso))))
(run
(loop for k from st to nd do
(when (< temp two-pi)
;; shake over 50msec and add shake energy
(incf temp (hz->radians 20))
(incf shake-energy (- 1.0 (cos temp))))
(when (= j srate4) ;shake 4 times/sec
(setf temp 0.0)
(setf j 0))
(incf j)
(setf shake-energy (* shake-energy system-decay))
;; if collision, add energy
(when (< (random 1.0) probability)
(incf snd-level (* gain shake-energy))
;; randomize res freqs a bit
(do ((i 0 (1+ i)))
((= i resn))
(setf (aref coeffs i 0) (double (+ (aref basesf i) (centered-random randiff))))))
;; actual sound is random
(setf input (* snd-level (centered-random 1.0)))
;; compute exponential sound decay
(setf snd-level (* snd-level sound-decay))
;; gourd resonance filter calcs
(setf temp1 input)
(setf last-sum sum)
(setf sum 0.0)
(do ((i 0 (1+ i)))
((= i resn))
(setf input temp1)
(setf input (- input
(* (aref output i 0) (aref coeffs i 0))
(* (aref output i 1) (aref coeffs i 1))))
(setf (aref output i 1) (double (aref output i 0)))
(setf (aref output i 0) (double input))
(incf sum input))
(if with-filters
(progn
(setf last-diff diff)
(setf diff (- sum last-sum))
(setf temp1 (+ last-diff diff)))
(setf temp1 sum))
;; extra zero for spectral shape, also fixup amp since Perry is assuming maxamp 16384
(outa k (* sndamp temp1))))))
;;; tambourine: (with-sound () (big-maraca 0 1 .25 0.95 0.9985 .03125 '(2300 5600 8100) '(0.96 0.995 0.995) .01))
;;; sleighbells: (with-sound () (big-maraca 0 2 .5 0.97 0.9994 0.03125 '(2500 5300 6500 8300 9800) '(0.999 0.999 0.999 0.999 0.999)))
;;; sekere: (with-sound () (big-maraca 0 2 .5 0.96 0.999 .0625 '(5500) '(0.6)))
;;; windchimes: (with-sound () (big-maraca 0 2 .5 0.99995 0.95 .001 '(2200 2800 3400) '(0.995 0.995 0.995) .01 nil))