annotate base/methods.lisp @ 104:67f96832cfb0

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