m@24
|
1 (cl:in-package #:amuse)
|
m@24
|
2
|
m@81
|
3 ;;; diatonic pitch
|
m@81
|
4
|
m@86
|
5 (defmethod octave ((dp diatonic-pitch))
|
m@86
|
6 (%diatonic-pitch-octave dp))
|
m@86
|
7
|
m@86
|
8 (defmethod diatonic-pitch-accidental ((dp diatonic-pitch))
|
m@86
|
9 (%diatonic-pitch-accidental dp))
|
m@86
|
10
|
m@83
|
11 (defmethod pitch= ((p1 diatonic-pitch) (p2 diatonic-pitch))
|
m@83
|
12 (let ((n1 (%diatonic-pitch-name p1))
|
m@83
|
13 (a1 (%diatonic-pitch-accidental p1))
|
m@83
|
14 (o1 (%diatonic-pitch-accidental p1))
|
m@83
|
15 (n2 (%diatonic-pitch-name p2))
|
m@83
|
16 (a2 (%diatonic-pitch-accidental p2))
|
m@83
|
17 (o2 (%diatonic-pitch-accidental p2)))
|
m@83
|
18 (and n1 n2 (= n1 n2)
|
m@83
|
19 a1 a2 (= a1 a2)
|
m@83
|
20 o1 o2 (= o1 o2))))
|
m@83
|
21
|
m@81
|
22 (defmethod middle-c ((dp diatonic-pitch))
|
m@81
|
23 (make-diatonic-pitch 2 0 4))
|
m@81
|
24
|
m@81
|
25 (defmethod diatonic-pitch ((dp diatonic-pitch))
|
m@81
|
26 dp)
|
m@81
|
27
|
m@81
|
28 (defmethod diatonic-pitch-name ((dp diatonic-pitch))
|
m@81
|
29 (elt "ABCDEFG" (%diatonic-pitch-name dp)))
|
m@81
|
30
|
m@81
|
31 (defmethod asa-pitch-string ((dp diatonic-pitch))
|
m@81
|
32 (concatenate 'string
|
m@81
|
33 (diatonic-pitch-name dp)
|
m@81
|
34 (let ((a (%diatonic-pitch-accidental dp)))
|
m@81
|
35 (cond ((plusp a)
|
m@81
|
36 (make-sequence 'string a :initial-element "s"))
|
m@81
|
37 ((minusp a)
|
m@81
|
38 (make-sequence 'string (abs a) :initial-element "f"))
|
m@81
|
39 (t "n")))
|
m@81
|
40 (%diatonic-pitch-octave dp)))
|
m@81
|
41
|
m@81
|
42 (defmethod mips-pitch ((dp diatonic-pitch))
|
m@81
|
43 (let ((mips-pitch (mips:pn-p (asa-pitch-string dp))))
|
m@81
|
44 (make-mips-pitch (first mips-pitch) (second mips-pitch))))
|
m@81
|
45 (defmethod midi-pitch-number ((dp diatonic-pitch))
|
m@81
|
46 (midi-pitch-number (mips-pitch dp)))
|
m@81
|
47 (defmethod chromatic-pitch ((dp diatonic-pitch))
|
m@81
|
48 (make-chromatic-pitch (midi-pitch-number dp)))
|
m@81
|
49 (defmethod meredith-chromatic-pitch-number ((dp diatonic-pitch))
|
m@81
|
50 (meredith-chromatic-pitch-number (mips-pitch dp)))
|
m@81
|
51 (defmethod meredith-morphetic-pitch-number ((dp diatonic-pitch))
|
m@81
|
52 (meredith-morphetic-pitch-number (mips-pitch dp)))
|
m@81
|
53
|
m@81
|
54 ;;; MIPS pitch
|
m@81
|
55
|
m@86
|
56 (defmethod octave ((mp mips-pitch))
|
m@86
|
57 (octave (diatonic-pitch mp)))
|
m@86
|
58
|
m@86
|
59 (defmethod diatonic-pitch-accidental ((mp mips-pitch))
|
m@86
|
60 (diatonic-pitch-accidental (diatonic-pitch mp)))
|
m@86
|
61
|
m@83
|
62 (defmethod pitch= ((p1 mips-pitch) (p2 mips-pitch))
|
m@83
|
63 (let ((c1 (meredith-chromatic-pitch-number p1))
|
m@83
|
64 (m1 (meredith-morphetic-pitch-number p1))
|
m@83
|
65 (c2 (meredith-chromatic-pitch-number p2))
|
m@83
|
66 (m2 (meredith-morphetic-pitch-number p2)))
|
m@83
|
67 (and c1 c2 (= c1 c2)
|
m@83
|
68 m1 m2 (= m1 m2))))
|
m@83
|
69
|
m@81
|
70 (defmethod middle-c ((mp mips-pitch))
|
m@81
|
71 (make-mips-pitch 39 23))
|
m@81
|
72
|
m@81
|
73 (defmethod mips-pitch ((mp mips-pitch))
|
m@81
|
74 mp)
|
m@81
|
75
|
m@81
|
76 (defmethod diatonic-pitch ((mp mips-pitch))
|
m@81
|
77 (let ((asa-pitch (mips:p-pn (list (%p-pc mp) (%p-pm mp))))
|
m@81
|
78 (accidental-count nil))
|
m@81
|
79 (make-diatonic-pitch
|
m@81
|
80 (position (elt asa-pitch 0) "ABCDEFG")
|
m@81
|
81 (ecase (elt asa-pitch 1)
|
m@81
|
82 (#\n 0)
|
m@81
|
83 (#\s
|
m@81
|
84 (let ((c (count #\s asa-pitch)))
|
m@81
|
85 (setf accidental-count c)
|
m@81
|
86 c))
|
m@81
|
87 (#\f
|
m@81
|
88 (let ((c (count #\f asa-pitch)))
|
m@81
|
89 (setf accidental-count c)
|
m@81
|
90 (- c))))
|
m@81
|
91 (parse-integer
|
m@81
|
92 asa-pitch :start (if accidental-count (1+ accidental-count) 2)))))
|
m@81
|
93
|
m@81
|
94 (defmethod meredith-chromatic-pitch-number ((mp mips-pitch))
|
m@81
|
95 (%p-pc mp))
|
m@81
|
96 (defmethod meredith-morphetic-pitch-number ((mp mips-pitch))
|
m@81
|
97 (%p-pm mp))
|
m@81
|
98 (defmethod midi-pitch-number ((mp mips-pitch))
|
m@81
|
99 (+ (meredith-chromatic-pitch-number mp) 21))
|
m@81
|
100 (defmethod chromatic-pitch ((mp mips-pitch))
|
m@81
|
101 (make-chromatic-pitch (midi-pitch-number mp)))
|
m@81
|
102 (defmethod asa-pitch-string ((mp mips-pitch))
|
m@81
|
103 (mips:p-pn (list (meredith-chromatic-pitch-number mp)
|
m@81
|
104 (meredith-morphetic-pitch-number mp))))
|
m@81
|
105 (defmethod diatonic-pitch-name ((mp mips-pitch))
|
m@81
|
106 (elt (asa-pitch-string mp) 0))
|
m@81
|
107
|
m@81
|
108 ;;; Chromatic pitch
|
m@81
|
109
|
m@86
|
110 (defmethod octave ((cp chromatic-pitch))
|
m@86
|
111 (1- (/ (%chromatic-pitch-number cp) 12)))
|
m@86
|
112
|
m@81
|
113 (defmethod middle-c ((cp chromatic-pitch))
|
m@81
|
114 (make-chromatic-pitch 60))
|
m@81
|
115
|
m@24
|
116 (defmethod chromatic-pitch ((pitch-designator chromatic-pitch))
|
m@24
|
117 pitch-designator)
|
m@24
|
118
|
m@24
|
119 (defmethod midi-pitch-number ((pitch-designator chromatic-pitch))
|
m@24
|
120 (%chromatic-pitch-number pitch-designator))
|
m@24
|
121
|
m@24
|
122 (defmethod midi-pitch-number ((pitch-designator pitch))
|
m@24
|
123 (%chromatic-pitch-number (chromatic-pitch pitch-designator)))
|
m@24
|
124
|
m@24
|
125 (defmethod span ((pitch-interval-designator pitch-interval))
|
m@24
|
126 (%pitch-interval-span pitch-interval-designator))
|
m@24
|
127
|
m@24
|
128 (defmethod duration ((period-designator period))
|
m@24
|
129 (%period-interval period-designator))
|
m@24
|
130
|
d@33
|
131 (defmethod (setf duration) ((value real) (period-designator period))
|
d@33
|
132 (setf (%period-interval period-designator) value))
|
d@33
|
133
|
m@24
|
134 (defmethod timepoint ((moment-designator moment))
|
m@24
|
135 (%moment-time moment-designator))
|
m@24
|
136
|
d@33
|
137 (defmethod (setf timepoint) ((value real) (moment-designator moment))
|
d@33
|
138 (setf (%moment-time moment-designator) value))
|
d@33
|
139
|
d@73
|
140 (defmethod cut-off ((anchored-period-designator anchored-period))
|
d@73
|
141 (make-instance 'moment
|
d@73
|
142 :time (+ (%moment-time anchored-period-designator)
|
d@73
|
143 (%period-interval anchored-period-designator))))
|
d@73
|
144
|
m@24
|
145 (defmethod beat-units-per-bar ((time-signature basic-time-signature))
|
m@24
|
146 (%basic-time-signature-numerator time-signature))
|
m@24
|
147
|
m@24
|
148 (defmethod beat-units ((time-signature basic-time-signature))
|
m@24
|
149 (%basic-time-signature-denominator time-signature))
|
m@24
|
150
|
m@67
|
151 (defmethod time-signature-equal ((ts1 basic-time-signature)
|
m@67
|
152 (ts2 basic-time-signature))
|
m@67
|
153 (let ((n1 (time-signature-numerator ts1))
|
m@67
|
154 (n2 (time-signature-numerator ts2))
|
m@67
|
155 (d1 (time-signature-denominator ts1))
|
m@67
|
156 (d2 (time-signature-denominator ts2)))
|
m@67
|
157 (and n1 n2 (= n1 n2)
|
m@67
|
158 d1 d2 (= d1 d2))))
|
m@67
|
159
|
m@24
|
160 (defmethod key-signature-sharps ((key-signature basic-key-signature))
|
m@24
|
161 (%basic-key-signature-sharp-count key-signature))
|
m@24
|
162
|
m@45
|
163 (defmethod key-signature-mode ((ks midi-key-signature))
|
m@45
|
164 (%midi-key-signature-mode ks))
|
m@45
|
165
|
m@67
|
166 (defmethod key-signature-equal ((ks1 basic-key-signature)
|
m@67
|
167 (ks2 basic-key-signature))
|
m@67
|
168 (let ((s1 (key-signature-sharps ks1))
|
m@67
|
169 (s2 (key-signature-sharps ks2)))
|
m@67
|
170 (and s1 s2 (= s1 s2))))
|
m@67
|
171
|
m@67
|
172 (defmethod key-signature-equal ((ks1 midi-key-signature)
|
m@67
|
173 (ks2 midi-key-signature))
|
m@67
|
174 (let ((s1 (key-signature-sharps ks1))
|
m@67
|
175 (s2 (key-signature-sharps ks2))
|
m@67
|
176 (m1 (key-signature-mode ks1))
|
m@67
|
177 (m2 (key-signature-mode ks2)))
|
m@67
|
178 (and s1 s2 (= s1 s2)
|
m@67
|
179 m1 m2 (= m1 m2))))
|
m@67
|
180
|
m@24
|
181 (defmethod bpm ((tempo tempo))
|
m@24
|
182 (%tempo-bpm tempo))
|
m@24
|
183
|
m@67
|
184 (defmethod tempo-equal ((t1 tempo) (t2 tempo))
|
m@67
|
185 (and (bpm t1) (bpm t2) (= t1 t2)))
|
m@67
|
186
|
m@67
|
187
|
m@24
|
188 ;; Time protocol
|
m@24
|
189
|
m@24
|
190 (defmethod time+ ((object1 moment) (object2 period))
|
m@24
|
191 (make-moment (+ (timepoint object1) (duration object2))))
|
m@24
|
192
|
m@24
|
193 (defmethod time+ ((object1 period) (object2 moment)) ;?
|
m@24
|
194 (time+ object2 object1))
|
m@24
|
195
|
m@24
|
196 (defmethod time+ ((object1 period) (object2 period))
|
m@24
|
197 (make-floating-period (+ (duration object1)
|
m@24
|
198 (duration object2))))
|
m@24
|
199
|
m@24
|
200 (defmethod time+ ((object1 moment) (object2 moment))
|
m@24
|
201 (error 'undefined-action :operation 'time+ :datatype (list (class-of object1) (class-of object2))))
|
m@24
|
202
|
m@24
|
203 (defmethod time- ((object1 moment) (object2 moment))
|
m@24
|
204 (make-anchored-period (timepoint object2)
|
m@24
|
205 (- (timepoint object1)
|
m@24
|
206 (timepoint object2))))
|
m@24
|
207
|
m@24
|
208 (defmethod time- ((object1 moment) (object2 period))
|
m@24
|
209 (make-moment (- (timepoint object1) (duration object2))))
|
m@24
|
210
|
m@24
|
211 (defmethod time- ((object1 period) (object2 moment)) ;?
|
m@24
|
212 (error 'undefined-action
|
m@24
|
213 :operation 'time-
|
m@24
|
214 :datatype (list (class-of object1) (class-of object2))))
|
m@24
|
215
|
m@24
|
216 (defmethod time- ((object1 period) (object2 period))
|
m@24
|
217 (make-floating-period (- (duration object2)
|
m@24
|
218 (duration object1))))
|
m@24
|
219
|
m@24
|
220 ;; these ones are less certain. I've just put them in, but think I
|
m@24
|
221 ;; should remove them and force the user to specify what they mean
|
m@24
|
222 ;; when they give objects that are both moments *and* periods to these
|
m@24
|
223 ;; functions.
|
m@24
|
224
|
m@24
|
225 (defmethod time- ((object1 anchored-period) (object2 anchored-period)) ;?
|
m@24
|
226 (time- (moment object1) (moment object2)))
|
m@24
|
227
|
m@24
|
228 (defmethod time- (object1 (object2 anchored-period)) ;?
|
m@24
|
229 (time- object1 (moment object2)))
|
m@24
|
230
|
m@24
|
231 (defmethod time- ((object1 anchored-period) object2) ;?
|
m@24
|
232 (time- (moment object1) object2))
|
m@24
|
233
|
m@24
|
234 (defmethod time> ((object1 moment) (object2 moment))
|
m@24
|
235 (> (timepoint object1) (timepoint object2)))
|
m@24
|
236
|
d@73
|
237 (defmethod time< ((object1 moment) (object2 moment))
|
d@73
|
238 (< (timepoint object1) (timepoint object2)))
|
d@73
|
239
|
m@24
|
240 (defmethod time= ((object1 moment) (object2 moment))
|
m@24
|
241 (= (timepoint object1) (timepoint object2)))
|
m@24
|
242
|
m@24
|
243 (defmethod duration> ((object1 period) (object2 period))
|
m@24
|
244 (> (duration object1) (duration object2)))
|
m@24
|
245
|
m@24
|
246 (defmethod duration= ((object1 period) (object2 period))
|
m@24
|
247 (= (duration object1) (duration object2)))
|
m@24
|
248
|
m@24
|
249 (defmethod duration* ((object1 period) (object2 number))
|
m@24
|
250 (make-floating-period (* (duration object1) object2)))
|
m@24
|
251
|
m@24
|
252 (defmethod duration* ((object1 number) (object2 period))
|
m@24
|
253 (duration* object2 object1))
|
m@24
|
254
|
m@24
|
255 (defmethod duration/ ((object1 period) (object2 number))
|
m@24
|
256 (make-floating-period (/ (duration object1) object2)))
|
m@24
|
257
|
m@24
|
258 ;; Pitch protocol
|
m@24
|
259
|
m@24
|
260 (defmethod pitch+ ((object1 pitch-designator)
|
m@24
|
261 (object2 pitch-designator))
|
m@24
|
262 (error 'undefined-action :operation 'pitch+
|
m@24
|
263 :datatype (list (class-of object1) (class-of object2))))
|
m@24
|
264
|
m@24
|
265 (defmethod pitch+ ((object1 pitch-designator)
|
m@24
|
266 (object2 pitch-interval)) ; or should I check the
|
m@24
|
267 ; pitch/interval types?
|
d@34
|
268 (make-chromatic-pitch (+ (midi-pitch-number object1)
|
m@24
|
269 (span object2))))
|
m@24
|
270
|
m@24
|
271 (defmethod pitch+ ((object1 pitch-interval)
|
m@24
|
272 (object2 pitch-designator)) ;?
|
m@24
|
273 (pitch+ object2 object1))
|
m@24
|
274
|
m@24
|
275 (defmethod pitch+ ((object1 pitch-interval)
|
m@24
|
276 (object2 pitch-interval))
|
m@24
|
277 (make-pitch-interval (+ (span object1)
|
m@24
|
278 (span object2))))
|
m@24
|
279
|
m@24
|
280 (defmethod pitch- ((object1 pitch-designator)
|
m@24
|
281 (object2 pitch-designator))
|
d@34
|
282 (make-pitch-interval (- (midi-pitch-number object1)
|
d@34
|
283 (midi-pitch-number object2))))
|
m@24
|
284
|
m@24
|
285 (defmethod pitch- ((object1 pitch-designator)
|
m@24
|
286 (object2 pitch-interval))
|
d@34
|
287 (make-chromatic-pitch (- (midi-pitch-number object1)
|
m@24
|
288 (span object2))))
|
m@24
|
289
|
m@24
|
290 (defmethod pitch- ((object1 pitch-interval)
|
m@24
|
291 (object2 pitch-interval))
|
m@24
|
292 (make-pitch-interval (- (span object1)
|
m@24
|
293 (span object2))))
|
m@24
|
294
|
m@24
|
295 (defmethod pitch- ((object1 pitch-interval)
|
m@24
|
296 (object2 pitch-designator))
|
m@24
|
297 (error 'undefined-action :operation 'pitch-
|
m@24
|
298 :datatype (list (class-of object1) (class-of object2))))
|
m@24
|
299
|
m@24
|
300 (defmethod pitch> ((object1 pitch-designator)
|
m@24
|
301 (object2 pitch-designator))
|
d@34
|
302 (> (midi-pitch-number object1)
|
d@34
|
303 (midi-pitch-number object2)))
|
m@24
|
304
|
m@24
|
305 (defmethod pitch= ((object1 pitch-designator)
|
m@24
|
306 (object2 pitch-designator))
|
d@34
|
307 (= (midi-pitch-number object1)
|
d@34
|
308 (midi-pitch-number object2)))
|
m@24
|
309
|
m@24
|
310 (defmethod interval> ((object1 pitch-interval)
|
m@24
|
311 (object2 pitch-interval))
|
m@24
|
312 (> (span object1)
|
m@24
|
313 (span object2)))
|
m@24
|
314
|
m@24
|
315 (defmethod interval= ((object1 pitch-interval)
|
m@24
|
316 (object2 pitch-interval))
|
m@24
|
317 (= (span object1)
|
m@24
|
318 (span object2)))
|
m@24
|
319
|
m@24
|
320
|
m@24
|
321
|
m@24
|
322 ;; Allen
|
m@24
|
323
|
m@24
|
324 (defmethod meets ((object1 anchored-period)
|
m@24
|
325 (object2 anchored-period))
|
m@24
|
326 (or (time= (cut-off object1) object2)
|
m@24
|
327 (time= (cut-off object2) object1)))
|
m@24
|
328
|
m@24
|
329 (defmethod before ((object1 anchored-period)
|
m@24
|
330 (object2 anchored-period))
|
m@24
|
331 (time> object2 (cut-off object1)))
|
m@24
|
332
|
m@24
|
333 (defmethod overlaps ((object1 anchored-period)
|
m@24
|
334 (object2 anchored-period))
|
m@24
|
335 ;; FIXME: Is there a tidier method?
|
m@24
|
336 (or (and (time> object2 object1) ; object1 starts before object2
|
m@24
|
337 (time> (cut-off object1) object2) ; object1 ends after object2 starts
|
m@24
|
338 (time> (cut-off object2) (cut-off object1))) ; object1 ends before object2 does
|
m@24
|
339 (and (time> object1 object2) ; object1 starts after object2
|
m@24
|
340 (time> (cut-off object2) object1) ; object1 starts before object2 ends
|
m@24
|
341 (time> (cut-off object1) (cut-off object2))))) ; object1 ends after object2 does
|
m@24
|
342
|
m@24
|
343 (defmethod during ((object1 anchored-period)
|
m@24
|
344 (object2 anchored-period))
|
m@24
|
345 (and (time> object1 object2)
|
m@24
|
346 (time< (cut-off object2) (cut-off object2))))
|
m@24
|
347
|
m@24
|
348 (defmethod starts ((object1 anchored-period)
|
m@24
|
349 (object2 anchored-period))
|
m@24
|
350 (time= object1 object2))
|
m@24
|
351
|
m@24
|
352 (defmethod ends ((object1 anchored-period)
|
m@24
|
353 (object2 anchored-period))
|
m@24
|
354 (time= (cut-off object1) (cut-off object2)))
|
m@24
|
355
|
m@24
|
356 ;; ...and
|
m@24
|
357
|
d@33
|
358 (defmethod period= ((object1 anchored-period)
|
d@33
|
359 (object2 anchored-period))
|
d@33
|
360 (and (time= object1 object2)
|
d@33
|
361 (duration= object1 object2)))
|
d@33
|
362 (defmethod period= ((object1 floating-period)
|
d@33
|
363 (object2 floating-period))
|
d@33
|
364 (duration= object1 object2))
|
d@33
|
365
|
m@24
|
366 (defmethod period-intersection ((object1 anchored-period)
|
m@24
|
367 (object2 anchored-period))
|
m@24
|
368 (cond
|
m@24
|
369 ((disjoint object1 object2)
|
m@24
|
370 ;; if they don't overlap, return nil, not a negative-valued
|
m@24
|
371 ;; period
|
m@24
|
372 nil)
|
m@24
|
373 ((let* ((start (if (time> (onset object2) (onset object1))
|
m@24
|
374 (onset object2)
|
m@24
|
375 (onset object1)))
|
m@24
|
376 (duration (duration (time- (if (time> (cut-off object2) (cut-off object1))
|
m@24
|
377 (cut-off object1)
|
m@24
|
378 (cut-off object2))
|
m@24
|
379 start))))
|
m@24
|
380 (make-anchored-period (timepoint start) duration)))))
|
m@24
|
381
|
m@24
|
382
|