m@24
|
1 (cl:in-package #:amuse)
|
m@24
|
2
|
m@89
|
3 ;;; monody
|
m@89
|
4
|
m@89
|
5 (defmethod ensure-monody ((m monody))
|
m@89
|
6 (let ((result t))
|
m@89
|
7 (dotimes (i (1- (length m)) result)
|
m@89
|
8 ;; assumes the events are time ordered which (since monody is a
|
m@89
|
9 ;; subclass of time-ordered-constituent) they ought to be.
|
m@89
|
10 (let ((e1 (elt m i))
|
m@89
|
11 (e2 (elt m (1+ i))))
|
m@89
|
12 (unless (or (before e1 e2) (meets e1 e2))
|
m@89
|
13 (setf result nil))))))
|
m@89
|
14
|
c@109
|
15 ;;; diatonic pitch (represented using MIPS)
|
m@81
|
16
|
c@109
|
17 (defmethod asa-pitch-string ((mp diatonic-pitch))
|
c@106
|
18 (mips:p-pn (list (%p-pc mp) (%p-pm mp))))
|
c@106
|
19
|
c@109
|
20 (defmethod diatonic-pitch-octave ((mp diatonic-pitch))
|
c@106
|
21 (let* ((asa-string (asa-pitch-string mp))
|
c@106
|
22 (start (position-if #'digit-char-p asa-string)))
|
c@106
|
23 (values (parse-integer asa-string :start start))))
|
m@86
|
24
|
c@109
|
25 (defmethod diatonic-pitch-accidental ((mp diatonic-pitch))
|
c@106
|
26 (let* ((asa-string (asa-pitch-string mp))
|
c@106
|
27 (start 1)
|
c@106
|
28 (end (position-if #'digit-char-p asa-string))
|
c@106
|
29 (malist '((#\n . 0) (#\s . +1) (#\f . -1)))
|
c@106
|
30 (multiplier (cdr (assoc (char asa-string 1) malist))))
|
c@106
|
31 (* multiplier (- end start))))
|
c@106
|
32
|
c@109
|
33 (defmethod diatonic-pitch-name ((mp diatonic-pitch))
|
c@106
|
34 (elt (asa-pitch-string mp) 0))
|
m@86
|
35
|
c@109
|
36 (defmethod middle-c ((mp diatonic-pitch))
|
c@109
|
37 (make-diatonic-pitch 39 23))
|
m@81
|
38
|
c@109
|
39 (defmethod midi-pitch-number ((mp diatonic-pitch))
|
c@106
|
40 (+ (%p-pc mp) 21))
|
c@106
|
41
|
c@109
|
42 (defmethod octave ((mp diatonic-pitch))
|
c@106
|
43 (1- (floor (midi-pitch-number mp) 12)))
|
c@106
|
44
|
c@109
|
45 (defmethod diatonic-pitch ((mp diatonic-pitch))
|
m@81
|
46 mp)
|
m@81
|
47
|
c@109
|
48 (defmethod print-object ((o diatonic-pitch) stream)
|
c@106
|
49 (print-unreadable-object (o stream :type t)
|
c@106
|
50 (let ((asa-string (asa-pitch-string o)))
|
c@106
|
51 (write asa-string :stream stream))))
|
m@81
|
52
|
c@111
|
53 (defmethod asa-interval-string ((mpi diatonic-pitch-interval))
|
c@111
|
54 (mips:pi-pin (%diatonic-pitch-interval-span mpi)))
|
c@111
|
55
|
c@111
|
56 (defmethod print-object ((o diatonic-pitch-interval) stream)
|
c@111
|
57 (print-unreadable-object (o stream :type t)
|
c@111
|
58 (let ((asa-string (asa-interval-string o)))
|
c@111
|
59 (write asa-string :stream stream))))
|
c@111
|
60
|
m@81
|
61 ;;; Chromatic pitch
|
m@81
|
62
|
m@86
|
63 (defmethod octave ((cp chromatic-pitch))
|
c@106
|
64 (1- (floor (%chromatic-pitch-number cp) 12)))
|
m@86
|
65
|
m@81
|
66 (defmethod middle-c ((cp chromatic-pitch))
|
m@81
|
67 (make-chromatic-pitch 60))
|
m@81
|
68
|
m@24
|
69 (defmethod chromatic-pitch ((pitch-designator chromatic-pitch))
|
m@24
|
70 pitch-designator)
|
m@24
|
71
|
m@24
|
72 (defmethod midi-pitch-number ((pitch-designator chromatic-pitch))
|
m@24
|
73 (%chromatic-pitch-number pitch-designator))
|
m@24
|
74
|
m@24
|
75 (defmethod midi-pitch-number ((pitch-designator pitch))
|
m@24
|
76 (%chromatic-pitch-number (chromatic-pitch pitch-designator)))
|
m@24
|
77
|
m@113
|
78 (defmethod print-object ((o chromatic-pitch) stream)
|
m@113
|
79 (print-unreadable-object (o stream :type t)
|
m@113
|
80 (write (midi-pitch-number o) :stream stream)))
|
m@113
|
81
|
m@113
|
82 (defmethod print-object ((o chromatic-pitch-interval) stream)
|
m@113
|
83 (print-unreadable-object (o stream :type t)
|
m@113
|
84 (write (span o) :stream stream)))
|
m@113
|
85
|
m@113
|
86
|
c@111
|
87 (defmethod span ((pitch-interval-designator chromatic-pitch-interval))
|
c@111
|
88 (%chromatic-pitch-interval-span pitch-interval-designator))
|
m@24
|
89
|
m@24
|
90 (defmethod duration ((period-designator period))
|
m@24
|
91 (%period-interval period-designator))
|
m@24
|
92
|
d@33
|
93 (defmethod (setf duration) ((value real) (period-designator period))
|
d@33
|
94 (setf (%period-interval period-designator) value))
|
d@33
|
95
|
m@24
|
96 (defmethod timepoint ((moment-designator moment))
|
m@24
|
97 (%moment-time moment-designator))
|
m@24
|
98
|
d@33
|
99 (defmethod (setf timepoint) ((value real) (moment-designator moment))
|
d@33
|
100 (setf (%moment-time moment-designator) value))
|
d@33
|
101
|
d@73
|
102 (defmethod cut-off ((anchored-period-designator anchored-period))
|
d@73
|
103 (make-instance 'moment
|
d@73
|
104 :time (+ (%moment-time anchored-period-designator)
|
d@73
|
105 (%period-interval anchored-period-designator))))
|
d@73
|
106
|
m@113
|
107 (defmethod print-object ((o moment) stream)
|
m@113
|
108 (print-unreadable-object (o stream :type t)
|
m@113
|
109 (write (timepoint o) :stream stream)))
|
m@113
|
110
|
m@126
|
111 (defmethod print-object ((o period) stream)
|
m@113
|
112 (print-unreadable-object (o stream :type t)
|
m@113
|
113 (write (duration o) :stream stream)))
|
m@113
|
114
|
m@126
|
115 (defmethod print-object ((o anchored-period) stream)
|
m@126
|
116 (print-unreadable-object (o stream :type t)
|
m@126
|
117 (format stream "~A ~A" (timepoint o) (duration o))))
|
m@113
|
118
|
m@24
|
119 (defmethod beat-units-per-bar ((time-signature basic-time-signature))
|
m@24
|
120 (%basic-time-signature-numerator time-signature))
|
m@24
|
121
|
m@24
|
122 (defmethod beat-units ((time-signature basic-time-signature))
|
m@24
|
123 (%basic-time-signature-denominator time-signature))
|
m@24
|
124
|
m@67
|
125 (defmethod time-signature-equal ((ts1 basic-time-signature)
|
m@67
|
126 (ts2 basic-time-signature))
|
m@67
|
127 (let ((n1 (time-signature-numerator ts1))
|
m@67
|
128 (n2 (time-signature-numerator ts2))
|
m@67
|
129 (d1 (time-signature-denominator ts1))
|
m@67
|
130 (d2 (time-signature-denominator ts2)))
|
m@67
|
131 (and n1 n2 (= n1 n2)
|
m@67
|
132 d1 d2 (= d1 d2))))
|
m@67
|
133
|
m@113
|
134 (defmethod print-object ((bts basic-time-signature) stream)
|
m@113
|
135 (print-unreadable-object (bts stream :type t)
|
m@113
|
136 (format stream "~A/~A" (beat-units-per-bar bts) (beat-units bts))))
|
m@113
|
137
|
m@24
|
138 (defmethod key-signature-sharps ((key-signature basic-key-signature))
|
m@24
|
139 (%basic-key-signature-sharp-count key-signature))
|
m@24
|
140
|
m@45
|
141 (defmethod key-signature-mode ((ks midi-key-signature))
|
m@45
|
142 (%midi-key-signature-mode ks))
|
m@45
|
143
|
m@113
|
144 (defmethod print-object ((mks midi-key-signature) stream)
|
m@113
|
145 (print-unreadable-object (mks stream :type t)
|
m@113
|
146 (format stream "~A ~A"
|
m@113
|
147 (%basic-key-signature-sharp-count mks)
|
m@113
|
148 (%midi-key-signature-mode mks))))
|
m@113
|
149
|
m@67
|
150 (defmethod key-signature-equal ((ks1 basic-key-signature)
|
m@67
|
151 (ks2 basic-key-signature))
|
m@67
|
152 (let ((s1 (key-signature-sharps ks1))
|
m@67
|
153 (s2 (key-signature-sharps ks2)))
|
m@67
|
154 (and s1 s2 (= s1 s2))))
|
m@67
|
155
|
m@67
|
156 (defmethod key-signature-equal ((ks1 midi-key-signature)
|
m@67
|
157 (ks2 midi-key-signature))
|
m@67
|
158 (let ((s1 (key-signature-sharps ks1))
|
m@67
|
159 (s2 (key-signature-sharps ks2))
|
m@67
|
160 (m1 (key-signature-mode ks1))
|
m@67
|
161 (m2 (key-signature-mode ks2)))
|
m@67
|
162 (and s1 s2 (= s1 s2)
|
m@67
|
163 m1 m2 (= m1 m2))))
|
m@67
|
164
|
m@24
|
165 (defmethod bpm ((tempo tempo))
|
m@24
|
166 (%tempo-bpm tempo))
|
m@24
|
167
|
m@113
|
168 (defmethod print-object ((tempo tempo) stream)
|
m@113
|
169 (print-unreadable-object (tempo stream :type t)
|
m@113
|
170 (write (bpm tempo) :stream stream)))
|
m@113
|
171
|
m@67
|
172 (defmethod tempo-equal ((t1 tempo) (t2 tempo))
|
m@67
|
173 (and (bpm t1) (bpm t2) (= t1 t2)))
|
m@67
|
174
|
m@67
|
175
|
m@24
|
176 ;; Time protocol
|
m@24
|
177
|
m@24
|
178 (defmethod time+ ((object1 moment) (object2 period))
|
d@121
|
179 "Returns a <moment>. Implemented as a straightforward
|
d@121
|
180 summation."
|
m@24
|
181 (make-moment (+ (timepoint object1) (duration object2))))
|
m@24
|
182
|
m@24
|
183 (defmethod time+ ((object1 period) (object2 moment)) ;?
|
d@121
|
184 "Returns a <moment>. Implemented as a straightforward summation
|
d@121
|
185 and defined by default as (time+ <moment> <period>)."
|
m@24
|
186 (time+ object2 object1))
|
m@24
|
187
|
m@24
|
188 (defmethod time+ ((object1 period) (object2 period))
|
d@121
|
189 "Returns a <period>. Implemented as a straightforward
|
d@121
|
190 summation."
|
m@24
|
191 (make-floating-period (+ (duration object1)
|
m@24
|
192 (duration object2))))
|
m@24
|
193
|
m@24
|
194 (defmethod time+ ((object1 moment) (object2 moment))
|
d@121
|
195 "Returns <condition:undefined-action>. The question makes no
|
d@121
|
196 sense."
|
m@24
|
197 (error 'undefined-action :operation 'time+ :datatype (list (class-of object1) (class-of object2))))
|
m@24
|
198
|
m@24
|
199 (defmethod time- ((object1 moment) (object2 moment))
|
d@121
|
200 "Returns <anchored-period> with an onset at object2 and
|
d@121
|
201 extending to object1"
|
m@24
|
202 (make-anchored-period (timepoint object2)
|
m@24
|
203 (- (timepoint object1)
|
m@24
|
204 (timepoint object2))))
|
m@24
|
205
|
m@24
|
206 (defmethod time- ((object1 moment) (object2 period))
|
d@121
|
207 "Simple subtraction - Returns a <moment>"
|
m@24
|
208 (make-moment (- (timepoint object1) (duration object2))))
|
m@24
|
209
|
m@24
|
210 (defmethod time- ((object1 period) (object2 moment)) ;?
|
d@121
|
211 "Returns <condition:undefined-action>. The question makes no
|
d@121
|
212 sense"
|
m@24
|
213 (error 'undefined-action
|
m@24
|
214 :operation 'time-
|
m@24
|
215 :datatype (list (class-of object1) (class-of object2))))
|
m@24
|
216
|
m@24
|
217 (defmethod time- ((object1 period) (object2 period))
|
d@121
|
218 "Returns <floating-period> spanning the difference of the
|
d@121
|
219 periods"
|
m@24
|
220 (make-floating-period (- (duration object2)
|
m@24
|
221 (duration object1))))
|
m@24
|
222
|
m@24
|
223 ;; these ones are less certain. I've just put them in, but think I
|
m@24
|
224 ;; should remove them and force the user to specify what they mean
|
m@24
|
225 ;; when they give objects that are both moments *and* periods to these
|
m@24
|
226 ;; functions.
|
m@24
|
227
|
m@24
|
228 (defmethod time- ((object1 anchored-period) (object2 anchored-period)) ;?
|
m@24
|
229 (time- (moment object1) (moment object2)))
|
m@24
|
230
|
m@24
|
231 (defmethod time- (object1 (object2 anchored-period)) ;?
|
m@24
|
232 (time- object1 (moment object2)))
|
m@24
|
233
|
m@24
|
234 (defmethod time- ((object1 anchored-period) object2) ;?
|
m@24
|
235 (time- (moment object1) object2))
|
m@24
|
236
|
m@24
|
237 (defmethod time> ((object1 moment) (object2 moment))
|
m@24
|
238 (> (timepoint object1) (timepoint object2)))
|
m@24
|
239
|
d@73
|
240 (defmethod time< ((object1 moment) (object2 moment))
|
d@73
|
241 (< (timepoint object1) (timepoint object2)))
|
d@73
|
242
|
m@24
|
243 (defmethod time= ((object1 moment) (object2 moment))
|
m@24
|
244 (= (timepoint object1) (timepoint 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 period))
|
m@24
|
250 (= (duration object1) (duration object2)))
|
m@24
|
251
|
m@24
|
252 (defmethod duration* ((object1 period) (object2 number))
|
m@24
|
253 (make-floating-period (* (duration object1) object2)))
|
m@24
|
254
|
m@24
|
255 (defmethod duration* ((object1 number) (object2 period))
|
m@24
|
256 (duration* object2 object1))
|
m@24
|
257
|
m@24
|
258 (defmethod duration/ ((object1 period) (object2 number))
|
m@24
|
259 (make-floating-period (/ (duration object1) object2)))
|
m@24
|
260
|
c@111
|
261 ;;;; Pitch protocol
|
m@24
|
262
|
c@111
|
263 ;;; Some catch-all methods for undefined operations and cases where we
|
c@111
|
264 ;;; don't have enough information:
|
c@111
|
265 (macrolet ((def (name class1 class2)
|
c@111
|
266 `(defmethod ,name ((object1 ,class1) (object2 ,class2))
|
c@111
|
267 (error 'undefined-action :operation ',name
|
c@111
|
268 :datatype (list (class-of object1) (class-of object2))))))
|
c@111
|
269 (def pitch+ pitch-designator pitch-designator)
|
c@111
|
270 (def pitch- pitch-interval-designator pitch-designator))
|
m@24
|
271
|
c@111
|
272 (macrolet ((def (name class1 class2)
|
c@111
|
273 `(defmethod ,name ((object1 ,class1) (object2 ,class2))
|
c@111
|
274 (error 'insufficient-information :operation ',name
|
c@111
|
275 :datatype (list (class-of object1) (class-of object2))))))
|
c@111
|
276 (def pitch+ pitch-designator pitch-interval-designator)
|
c@111
|
277 (def pitch+ pitch-interval-designator pitch-designator)
|
c@111
|
278 (def pitch+ pitch-interval-designator pitch-interval-designator)
|
c@111
|
279 (def pitch- pitch-designator pitch-designator)
|
c@111
|
280 (def pitch- pitch-designator pitch-interval-designator)
|
c@111
|
281 (def pitch- pitch-interval-designator pitch-interval-designator))
|
m@24
|
282
|
c@111
|
283 ;;; chromatic pitch intervals
|
m@24
|
284
|
c@111
|
285 (defmethod pitch+ ((object1 chromatic-pitch)
|
c@111
|
286 (object2 chromatic-pitch-interval))
|
c@111
|
287 (make-chromatic-pitch (+ (midi-pitch-number object1) (span object2))))
|
c@111
|
288
|
c@111
|
289 (defmethod pitch+ ((object1 chromatic-pitch-interval)
|
c@111
|
290 (object2 chromatic-pitch))
|
c@111
|
291 (make-chromatic-pitch (+ (span object1) (midi-pitch-number object2))))
|
c@111
|
292
|
c@111
|
293 (defmethod pitch+ ((object1 chromatic-pitch-interval)
|
c@111
|
294 (object2 chromatic-pitch-interval))
|
c@105
|
295 (make-chromatic-pitch-interval (+ (span object1) (span object2))))
|
m@24
|
296
|
c@111
|
297 (defmethod pitch- ((object1 chromatic-pitch)
|
c@111
|
298 (object2 chromatic-pitch))
|
c@111
|
299 (make-chromatic-pitch-interval
|
c@105
|
300 (- (midi-pitch-number object1) (midi-pitch-number object2))))
|
m@24
|
301
|
c@111
|
302 (defmethod pitch- ((object1 chromatic-pitch)
|
c@111
|
303 (object2 chromatic-pitch-interval))
|
c@105
|
304 (make-chromatic-pitch (- (midi-pitch-number object1) (span object2))))
|
m@24
|
305
|
c@111
|
306 (defmethod pitch- ((object1 chromatic-pitch-interval)
|
c@111
|
307 (object2 chromatic-pitch-interval))
|
c@105
|
308 (make-chromatic-pitch-interval (- (span object1) (span object2))))
|
m@24
|
309
|
c@111
|
310 (defmethod pitch> ((object1 chromatic-pitch)
|
c@111
|
311 (object2 chromatic-pitch))
|
c@111
|
312 (> (midi-pitch-number object1) (midi-pitch-number object2)))
|
m@24
|
313
|
c@111
|
314 (defmethod pitch= ((object1 chromatic-pitch)
|
c@111
|
315 (object2 chromatic-pitch))
|
c@111
|
316 (= (midi-pitch-number object1) (midi-pitch-number object2)))
|
m@24
|
317
|
c@111
|
318 (defmethod interval> ((object1 chromatic-pitch-interval)
|
c@111
|
319 (object2 chromatic-pitch-interval))
|
c@111
|
320 (> (span object1) (span object2)))
|
m@24
|
321
|
c@111
|
322 (defmethod interval= ((object1 chromatic-pitch-interval)
|
c@111
|
323 (object2 chromatic-pitch-interval))
|
c@111
|
324 (= (span object1) (span object2)))
|
m@24
|
325
|
c@111
|
326 ;;; diatonic pitch intervals
|
m@24
|
327
|
c@111
|
328 (defmethod pitch+ ((object1 diatonic-pitch) (object2 diatonic-pitch-interval))
|
c@111
|
329 (let* ((cp (%p-pc object1))
|
c@111
|
330 (mp (%p-pm object1))
|
c@111
|
331 (span (span object2))
|
c@111
|
332 (cps (first span))
|
c@111
|
333 (mps (second span)))
|
c@111
|
334 (make-mips-pitch (+ cp cps) (+ mp mps))))
|
c@111
|
335
|
c@111
|
336 (defmethod pitch+ ((object1 diatonic-pitch-interval) (object2 diatonic-pitch))
|
c@111
|
337 (let* ((cp (%p-pc object2))
|
c@111
|
338 (mp (%p-pm object2))
|
c@111
|
339 (span (span object1))
|
c@111
|
340 (cps (first span))
|
c@111
|
341 (mps (second span)))
|
c@111
|
342 (make-mips-pitch (+ cp cps) (+ mp mps))))
|
c@111
|
343
|
c@111
|
344 (defmethod pitch+ ((object1 diatonic-pitch-interval)
|
c@111
|
345 (object2 diatonic-pitch-interval))
|
c@111
|
346 (let* ((span1 (span object1))
|
c@111
|
347 (span2 (span object2)))
|
c@111
|
348 (make-mips-pitch-interval (+ (first span1) (first span2))
|
c@111
|
349 (+ (second span1) (second span2)))))
|
c@111
|
350
|
c@111
|
351 (defmethod pitch- ((object1 diatonic-pitch) (object2 diatonic-pitch))
|
c@111
|
352 (let ((cp1 (%p-pc object1))
|
c@111
|
353 (mp1 (%p-pm object1))
|
c@111
|
354 (cp2 (%p-pc object2))
|
c@111
|
355 (mp2 (%p-pm object2)))
|
c@111
|
356 (make-mips-pitch-interval (- cp1 cp2) (- mp1 mp2))))
|
c@111
|
357
|
c@111
|
358 (defmethod pitch- ((object1 diatonic-pitch) (object2 diatonic-pitch-interval))
|
c@111
|
359 (let* ((cp (%p-pc object1))
|
c@111
|
360 (mp (%p-pm object1))
|
c@111
|
361 (span (span object2))
|
c@111
|
362 (cps (first span))
|
c@111
|
363 (mps (second span)))
|
c@111
|
364 (make-mips-pitch (- cp cps) (- mp mps))))
|
c@111
|
365
|
c@111
|
366 (defmethod pitch- ((object1 diatonic-pitch-interval)
|
c@111
|
367 (object2 diatonic-pitch-interval))
|
c@111
|
368 (let ((span1 (span object1))
|
c@111
|
369 (span2 (span object2)))
|
c@111
|
370 (make-mips-pitch-interval (- (first span1) (first span2))
|
c@111
|
371 (- (second span1) (second span2)))))
|
c@111
|
372
|
c@111
|
373 (defmethod pitch> ((p1 diatonic-pitch) (p2 diatonic-pitch))
|
c@111
|
374 (error 'undefined-action :operation 'pitch>
|
c@111
|
375 :datatype (list (class-of p1) (class-of p2))))
|
c@111
|
376
|
c@111
|
377 (defmethod pitch= ((p1 diatonic-pitch) (p2 diatonic-pitch))
|
c@111
|
378 (let ((c1 (%p-pc p1)) (m1 (%p-pm p1))
|
c@111
|
379 (c2 (%p-pc p2)) (m2 (%p-pm p2)))
|
c@111
|
380 (and c1 c2 (= c1 c2)
|
c@111
|
381 m1 m2 (= m1 m2))))
|
m@24
|
382
|
m@24
|
383
|
m@24
|
384 ;; Allen
|
m@24
|
385
|
m@24
|
386 (defmethod meets ((object1 anchored-period)
|
m@24
|
387 (object2 anchored-period))
|
m@24
|
388 (or (time= (cut-off object1) object2)
|
m@24
|
389 (time= (cut-off object2) object1)))
|
m@24
|
390
|
m@24
|
391 (defmethod before ((object1 anchored-period)
|
m@24
|
392 (object2 anchored-period))
|
m@24
|
393 (time> object2 (cut-off object1)))
|
m@24
|
394
|
m@24
|
395 (defmethod overlaps ((object1 anchored-period)
|
m@24
|
396 (object2 anchored-period))
|
m@24
|
397 ;; FIXME: Is there a tidier method?
|
m@24
|
398 (or (and (time> object2 object1) ; object1 starts before object2
|
m@24
|
399 (time> (cut-off object1) object2) ; object1 ends after object2 starts
|
m@24
|
400 (time> (cut-off object2) (cut-off object1))) ; object1 ends before object2 does
|
m@24
|
401 (and (time> object1 object2) ; object1 starts after object2
|
m@24
|
402 (time> (cut-off object2) object1) ; object1 starts before object2 ends
|
m@24
|
403 (time> (cut-off object1) (cut-off object2))))) ; object1 ends after object2 does
|
m@24
|
404
|
m@24
|
405 (defmethod during ((object1 anchored-period)
|
m@24
|
406 (object2 anchored-period))
|
m@24
|
407 (and (time> object1 object2)
|
m@24
|
408 (time< (cut-off object2) (cut-off object2))))
|
m@24
|
409
|
m@24
|
410 (defmethod starts ((object1 anchored-period)
|
m@24
|
411 (object2 anchored-period))
|
m@24
|
412 (time= object1 object2))
|
m@24
|
413
|
m@24
|
414 (defmethod ends ((object1 anchored-period)
|
m@24
|
415 (object2 anchored-period))
|
m@24
|
416 (time= (cut-off object1) (cut-off object2)))
|
m@24
|
417
|
m@24
|
418 ;; ...and
|
m@24
|
419
|
d@33
|
420 (defmethod period= ((object1 anchored-period)
|
c@105
|
421 (object2 anchored-period))
|
d@33
|
422 (and (time= object1 object2)
|
d@33
|
423 (duration= object1 object2)))
|
d@33
|
424 (defmethod period= ((object1 floating-period)
|
d@33
|
425 (object2 floating-period))
|
d@33
|
426 (duration= object1 object2))
|
d@33
|
427
|
m@24
|
428 (defmethod period-intersection ((object1 anchored-period)
|
m@24
|
429 (object2 anchored-period))
|
m@24
|
430 (cond
|
m@24
|
431 ((disjoint object1 object2)
|
m@24
|
432 ;; if they don't overlap, return nil, not a negative-valued
|
m@24
|
433 ;; period
|
m@24
|
434 nil)
|
m@24
|
435 ((let* ((start (if (time> (onset object2) (onset object1))
|
m@24
|
436 (onset object2)
|
m@24
|
437 (onset object1)))
|
m@24
|
438 (duration (duration (time- (if (time> (cut-off object2) (cut-off object1))
|
m@24
|
439 (cut-off object1)
|
m@24
|
440 (cut-off object2))
|
m@24
|
441 start))))
|
m@24
|
442 (make-anchored-period (timepoint start) duration)))))
|
m@24
|
443
|
m@24
|
444
|