summaryrefslogtreecommitdiff
path: root/runtime/stk.lsp
blob: 6ba7e55efbaa7551aed62fa3a4ed94404882871e (plain)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
;; stk.lsp -- STK-based instruments
;;
;; currently clarinet and saxophony are implemented

(defun instr-parameter (parm)
  ;; coerce parameter into a *sound-srate* signal
  (cond ((numberp parm)
         (stretch 30 (control-srate-abs *sound-srate* (const (float parm)))))
        (t
         (force-srate *sound-srate* parm))))


(defun clarinet (step breath-env)
  (snd-clarinet (step-to-hz step) (force-srate *sound-srate* breath-env) *sound-srate*))


(defun clarinet-freq (step breath-env freq-env)
  ;; note that the parameters are in a different order -- I defined 
  ;; clarinet-freq this way so that the first two parameters are always
  ;; step and breath. I didn't redo snd-clarinet-freq.
  (snd-clarinet_freq (step-to-hz step) 
                (instr-parameter breath-env)
                (instr-parameter freq-env)
                *sound-srate*))



(defun clarinet-all (step breath-env freq-env vibrato-freq vibrato-gain reed-stiffness noise)
  ;; note that the parameters are not in the same order as snd-clarinet-all
  (setf breath-env (instr-parameter breath-env))
  (setf freq-env (instr-parameter freq-env))
  (setf reed-stiffness (instr-parameter reed-stiffness))
  (setf noise (instr-parameter noise))
  (snd-clarinet_all (step-to-hz step)
                    breath-env freq-env 
                    ;; STK scales 1.0 to 12Hz. Scale here so vibrato-freq is in Hz
                    (/ vibrato-freq 12.0) vibrato-gain
                    reed-stiffness noise 
                    *sound-srate*))


(defun sax (step breath-env)
  (snd-sax (step-to-hz step) (force-srate *sound-srate* breath-env) *sound-srate*))

(defun sax-freq (step breath-env freq-env)
  (snd-sax_freq (step-to-hz step)
          (instr-parameter breath-env)
          (instr-parameter freq-env)
          *sound-srate*))

(defun sax-all (step breath-env freq-env vibrato-freq vibrato-gain reed-stiffness noise blow-pos reed-table-offset)
  (snd-sax_all (step-to-hz step)
	       (instr-parameter freq-env)
               (instr-parameter breath-env)
               (instr-parameter (/ vibrato-freq 12.0))
               (instr-parameter vibrato-gain)
               (instr-parameter reed-stiffness)
               (instr-parameter noise)
               (instr-parameter blow-pos)
               (instr-parameter reed-table-offset)
               *sound-srate*)
)

; instr-parameter already defined in stk.lsp

(defun flute (step breath-env)
  (snd-flute (step-to-hz step) (force-srate *sound-srate* breath-env) *sound-srate*))
 
(defun flute-freq (step breath-env freq-env)
  (snd-flute_freq (step-to-hz step) 
		  (instr-parameter breath-env)
		  (instr-parameter freq-env)
		  *sound-srate*))

(defun flute-all (step breath-env freq-env vibrato-freq vibrato-gain jet-delay noise)
  ;; note that the parameters are not in the same order as snd-clarinet-all
  (setf breath-env (instr-parameter breath-env))
  (setf freq-env (instr-parameter freq-env))
  (setf jet-delay (instr-parameter jet-delay))
  (setf noise (instr-parameter noise))
  (snd-flute_all (step-to-hz step)
                    breath-env freq-env 
                    ;; STK scales 1.0 to 12Hz. Scale here so vibrato-freq is in Hz
                    (/ vibrato-freq 12.0) vibrato-gain
                    jet-delay noise 
                    *sound-srate*))


(defun bowed (step bowpress-env)
  (snd-bowed (step-to-hz step) (force-srate *sound-srate* bowpress-env) *sound-srate*))

(defun bowed-freq (step bowpress-env freq-env)
  (snd-bowed_freq (step-to-hz step)
		  (instr-parameter bowpress-env)
		  (instr-parameter freq-env)
		  *sound-srate*))

(defun mandolin (step dur &optional (detune 4.0))
  (let ((d (get-duration dur)))
    (snd-mandolin *rslt* (step-to-hz step) d 1.0 detune *sound-srate*)))

(defun wg-uniform-bar (step bowpress-env)
  (snd-bandedwg (step-to-hz step) (force-srate *sound-srate* bowpress-env) 0 *sound-srate*))

(defun wg-tuned-bar (step bowpress-env)
  (snd-bandedwg (step-to-hz step) (force-srate *sound-srate* bowpress-env) 1 *sound-srate*))

(defun wg-glass-harm (step bowpress-env)
  (snd-bandedwg (step-to-hz step) (force-srate *sound-srate* bowpress-env) 2 *sound-srate*))

(defun wg-tibetan-bowl (step bowpress-env)
  (snd-bandedwg (step-to-hz step) (force-srate *sound-srate* bowpress-env) 3 *sound-srate*))
 
(defun modalbar (preset step duration)
   (let ((preset (case preset
			(MARIMBA 0)
			(VIBRAPHONE 1)
			(AGOGO 2)
			(WOOD1 3)
			(RESO 4)
			(WOOD2 5)
			(BEATS 6)
			(TWO-FIXED 7)
			(CLUMP 8)
			(t (error (format nil "Unknown preset for modalbar %A" preset)))))
	 (d (get-duration duration)))
     (snd-modalbar *rslt* (step-to-hz step) preset d *sound-srate*)))

(defun sitar (step dur)
  (let ((d (get-duration dur)))
    (snd-sitar *rslt* (step-to-hz step) d *sound-srate*)))

(defun nyq:nrev (snd rev-time mix)
  (snd-stkrev 0 snd rev-time mix *sound-srate*))

(defun nyq:jcrev (snd rev-time mix)
  (snd-stkrev 1 snd rev-time mix *sound-srate*))

(defun nyq:prcrev (snd rev-time mix)
  (snd-stkrev 2 snd rev-time mix *sound-srate*))

(defun nrev (snd rev-time mix)
  (multichan-expand #'nyq:nrev snd rev-time mix))

(defun jcrev (snd rev-time mix)
  (multichan-expand #'nyq:jcrev snd rev-time mix))

(defun prcrev (snd rev-time mix)
  (multichan-expand #'nyq:prcrev snd rev-time mix))

(defun nyq:chorus (snd depth freq mix &optional (base-delay 6000))
  (snd-stkchorus snd base-delay depth freq mix *sound-srate*))

(defun stkchorus (snd depth freq mix &optional (base-delay 6000))
  (multichan-expand #'nyq:chorus snd depth freq mix base-delay))

(defun nyq:pitshift (snd shift mix)
  (snd-stkpitshift snd shift mix *sound-srate*))

(defun pitshift (snd shift mix)
  (multichan-expand #'nyq:pitshift snd shift mix))



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; HELPER FUNCTIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; pass in rates of increase/decrease in begin/end... this is like noteOn and noteOff
;
; STK uses setRate but the actual ramp time is also a function of the sample rate.
; I will assume the clarinet was run at 44100Hz and fix things so that the envelope
; is sample-rate independent.
;
; STK seemed to always give a very fast release, so I changed the numbers so that
; note-off values from 0.01 to 1 give an interesting range of articulations.
;
; IMPORTANT: the returned envelope is 0.1s longer than dur. There is 0.1s of silence
; at the end so that the clarinet can "ring" after the driving force is removed.
;
(defun stk-breath-env (dur note-on note-off)
  (let* ((target (+ 0.55 (* 0.3 note-on)))
         (on-time (/ (* target 0.0045) note-on))
         (off-time (/ (* target 0.02) note-off)))
    ;(display "clarinet-breath-env" target on-time off-time)
    (pwl on-time target
         (- dur off-time) target
         dur 0 (+ dur 0.1))))