annotate base/generics.lisp @ 134:5e362d998f29

More documentation darcs-hash:20070828101524-f76cc-6add2c3c254befc3cf767ac69706865b7830bc6a.gz
author David Lewis <d.lewis@gold.ac.uk>
date Tue, 28 Aug 2007 11:15:24 +0100
parents f57ab0e109fb
children fd85f52d9f9d
rev   line source
m@24 1 (cl:in-package #:amuse)
m@24 2
m@24 3 ;;; Pulling compositions from the database
m@24 4
d@123 5 (defgeneric get-composition (identifier)
d@123 6 (:documentation "Returns a composition of type dependant on
d@123 7 identifier"))
m@24 8
m@89 9 (defgeneric monody (object)
m@89 10 (:documentation "Returns a monody."))
m@89 11 (defgeneric ensure-monody (object)
m@89 12 (:documentation "Returns a generalised boolean."))
m@89 13
d@33 14 ;;; Getting constituents from compositions
d@33 15 ;; IS this the mechanism we want to use
d@72 16 (defgeneric time-signatures (composition)
d@72 17 (:documentation "Returns all time-signatures in a composition
d@72 18 Probably shouldn't be exported - can be replaced
d@72 19 by (get-applicable-time-signature commposition composition)"))
d@72 20 (defgeneric (setf time-signatures) (sequence composition)
d@72 21 (:documentation "Sets all time-signatures in a composition.
d@72 22 Is this wanted here?"))
d@72 23 (defgeneric tempi (composition)
d@72 24 (:documentation "Returns all tempi in a composition Probably
d@72 25 shouldn't be exported - can be replaced
d@72 26 by (get-applicable-tempi commposition composition)"))
d@72 27 (defgeneric (setf tempi) (sequence composition)
d@72 28 (:documentation "Sets all tempi in a composition.
d@72 29 Is this wanted here?"))
d@72 30 (defgeneric key-signatures (composition)
d@72 31 (:documentation "Returns all key-signatures in a composition
d@72 32 Probably shouldn't be exported - can be replaced
d@72 33 by (get-applicable-key-signature commposition composition)"))
d@72 34 (defgeneric (setf key-signatures) (sequence composition)
d@72 35 (:documentation "Sets all key sigs in a composition.
d@72 36 Is this wanted here?"))
d@33 37
m@24 38 ;;; Simple Accessors
m@24 39
m@24 40 ;; pitch-based
m@24 41
m@24 42 (defgeneric pitch (object &key kind)) ; ? Maybe this returns the pitch
m@24 43 ; in its ur form?
c@106 44 (defgeneric chromatic-pitch (pitch-designator))
c@106 45 (defgeneric diatonic-pitch (pitch-designator))
m@24 46 (defgeneric frequency (object)) ;?
m@81 47
m@86 48 (defgeneric octave (pitch-designator)
m@86 49 (:documentation "Return an integer representing the octave of
m@86 50 pitch-designator where middle c is defined to be the lowest pitch in
m@86 51 octave 4."))
m@86 52
c@106 53 (defgeneric diatonic-pitch-octave (pitch-designator)
c@106 54 (:documentation "Return an integer representing the diatonic octave
c@106 55 of PITCH-DESIGNATOR."))
c@106 56
m@86 57 (defgeneric diatonic-pitch-accidental (pitch-designator)
m@86 58 (:documentation "Return an integer representing the inflection of a
m@86 59 diatonic pitch where where negative values indicate numbers of flats,
m@86 60 0 indicates natural and positive values indicate numbers of sharps."))
m@86 61
c@108 62 (defgeneric diatonic-pitch-mp (pitch-designator)
c@108 63 (:documentation "Return an integer representing the morphetic pitch
c@108 64 \(in MIPS terms) of a diatonic pitch."))
c@108 65 (defgeneric diatonic-pitch-cp (pitch-designator)
c@108 66 (:documentation "Return an integer representing the chromatic pitch
c@108 67 \(in MIPS terms) of a diatonic pitch."))
c@108 68
m@81 69 (defgeneric middle-c (pitch-designator)
m@81 70 (:documentation "Returns the value of middle C in the particular
m@81 71 representation of pitch used by PITCH-DESIGNATOR."))
d@72 72 (defgeneric midi-pitch-number (pitch-designator)
d@72 73 (:documentation "Takes a pitch-designator (usually a pitched
d@72 74 event) and returns an integer between 0 and 127 representing
d@72 75 the chromatic pitch designated (60=middle C, 48 the C below
d@72 76 that, etc.)"))
m@81 77 (defgeneric asa-pitch-string (pitch-designator)
m@81 78 (:documentation "Returns a string representing the designated ASA
m@81 79 pitch name which has three parts: a letter name in the set
m@81 80 {A,B,C,D,E,F,G}, an inflection in the set {n,f,s,ff,ss,fff,sss,...}
m@81 81 and an octave number. E.g., Cn4 = Middle C."))
c@112 82 (defgeneric asa-interval-string (pitch-designator)
c@112 83 (:documentation "Returns a string representing the designated ASA
c@112 84 interval name which has two or three parts: a direction in the set
c@112 85 {r,f} (absent for unisons/primes), a type in the set
c@112 86 {p,ma,mi,a,d,aa,dd,aaa,ddd,...}, and a size number. E.g. rma2 =
c@112 87 rising major second."))
m@81 88 (defgeneric diatonic-pitch-name (pitch-designator)
m@81 89 (:documentation "Returns a char in the set
m@81 90 {#\A,#\B,#\C,#\D,#\E,#\F,#\G}, representing the pitch name of
m@81 91 PITCH-DESIGNATOR."))
m@24 92 (defgeneric pitch-class (pitch-designator)
d@72 93 (:documentation "Takes a pitch-designator (usually a pitched
d@72 94 event) and returns an integer between 0 and 12 representing
d@72 95 the octave-independant pitch, with c=0, c#=1, etc.")
m@24 96 (:method (p) (mod (midi-pitch-number p) 12)))
m@24 97 (defgeneric span (pitch-interval-designator))
m@24 98
m@24 99 ;; time
m@24 100
d@123 101 (defgeneric duration (period-designator)
d@123 102 (:documentation "Returns a value. Probably should only apply do
d@123 103 periods (rather than designators?)"))
d@123 104 (defgeneric (setf duration) (value period-designator)
d@123 105 (:documentation "As with duration, should probably work only
d@123 106 with periods"))
d@123 107 (defgeneric timepoint (moment-designator)
d@123 108 (:documentation "Returns a value for a moment. Does this make
d@123 109 any sense on a designator?"))
d@123 110 (defgeneric (setf timepoint) (value moment-designator)
d@123 111 (:documentation "Sets timepoint. What does this mean for a
d@123 112 designator?"))
m@24 113 (defgeneric cut-off (anchored-period-designator) ; name?
d@72 114 (:documentation "Returns a <moment> representing the point at
d@121 115 which the anchored period has ended. By default, is calculated
d@121 116 as the result of running time+ on the onset and period of the
d@121 117 object.")
m@24 118 (:method (apd) (time+ (moment apd) (floating-period apd))))
m@95 119 (defgeneric crotchet (object)
m@95 120 (:documentation "Returns a period, the duration of which represents
m@95 121 a crotchet in the time representation used by object."))
m@24 122
m@24 123 ;; others
m@24 124
m@24 125 ;; I've given the time-sig accessors general names because it allows
m@24 126 ;; for symbols in time-signatures as well as numbers - numerator is an
m@24 127 ;; odd accessor if the time sig is C (even in common practice) but
d@100 128 ;; its meaning is clear. beat-units-per-bar is clearer, though, I
m@24 129 ;; think.
m@24 130
d@123 131 (defgeneric beat-units-per-bar (time-signature)
d@123 132 (:documentation "In a standard, fraction-like time-signature or
d@123 133 a symbolic equivalent, this is the numerator."))
m@24 134 (defgeneric time-signature-numerator (time-signature)
d@123 135 (:method (ts) (beat-units-per-bar ts))
d@123 136 (:documentation "Not obviously meaningful for non fraction-like
d@123 137 time signatures"))
d@123 138 (defgeneric beat-units (time-signature)
d@123 139 (:documentation "In a standard, fraction-like time-signature or
d@134 140 a symbolic equivalent, this is the denominator (n.b. the
d@134 141 difference between this and @code{tactus-duration} is only
d@134 142 visible for compound time, where this returns the lower portion
d@134 143 of the time signature, but @code{tactus-duration} returns the
d@134 144 higher-level unit)."))
m@24 145 (defgeneric time-signature-denominator (time-signature)
d@123 146 (:method (ts) (beat-units ts))
d@123 147 (:documentation "Not obviously meaningful for non fraction-like
d@123 148 time signatures"))
d@33 149 (defgeneric tactus-duration (time-signature)
d@33 150 ;; basic, but should do?
d@33 151 (:method (ts)
d@33 152 (cond
d@33 153 ((and (not (= (beat-units-per-bar ts) 3))
d@33 154 (= (rem (beat-units-per-bar ts) 3) 0))
d@33 155 ;; compound time
d@33 156 (* (/ 4 (beat-units ts))
d@33 157 3))
d@123 158 (t (/ 4 (beat-units ts)))))
d@123 159 (:documentation "Returns a number of crotchets to represent the
d@123 160 tactus, based on some idea of time signature patterns. Should,
d@123 161 in future, return a duration rather than a number."))
m@24 162
d@123 163 (defgeneric key-signature-sharps (key-signature)
d@123 164 (:documentation "Simple query for normal key-signatures."))
d@123 165 (defgeneric key-signature-mode (ks)
d@123 166 (:documentation "Query that only makes sense for midi-like key
d@123 167 signatures"))
m@24 168
d@123 169 (defgeneric bpm (tempo)
d@123 170 (:documentation "Basic tempo query")) ;; in bpm
m@24 171 (defgeneric microseconds-per-crotchet (tempo)
m@24 172 ;; As used (when rounded) in MIDI
d@123 173 (:method (tp) (/ 60000000 (bpm tp)))
d@123 174 (:documentation "Basic tempo query for MIDI. N.B. This will be
d@123 175 a fraction and must be rounded before being used for output."))
m@24 176
m@24 177 ;;; Coerce-type accessors
m@24 178
m@24 179 ;; Should I be including these default methods? Should the accessors
m@24 180 ;; be direct slot accessors or the generics I'm using? Should we
m@24 181 ;; return the object itself if it already is in the target class?
m@24 182
m@24 183 (defgeneric anchored-period (anchored-period-designator)
d@123 184 (:method (apd) (make-anchored-period (onset apd) (duration apd)))
d@123 185 (:documentation "Coerce any anchored period to a plain anchored
d@123 186 period"))
m@24 187
m@24 188 (defgeneric floating-period (period-designator)
d@123 189 (:method (pd) (make-floating-period (duration pd)))
d@123 190 (:documentation "Coerce any period to a floating period"))
m@24 191
m@24 192 (defgeneric moment (moment-designator)
d@123 193 (:method (md) (make-moment (timepoint md)))
d@123 194 (:documentation "Coerce any moment(-designator?), including an
d@123 195 anchored-period to a moment"))
m@24 196
m@24 197 (defgeneric onset (anchored-period-designator)
d@123 198 (:method (apd) (moment apd))
d@123 199 (:documentation "Return a moment for the start of an anchored period"))
m@24 200 (defgeneric (setf onset) (value anchored-period-designator))
m@24 201
m@24 202 ;;; Time Protocol (or moments?)
m@24 203
m@24 204 ;; negative times/durations -> ERROR?
m@24 205
m@24 206 ;; time+: <time> <duration> -> <time>
m@24 207 ;; <duration> <time> -> <time> (same as previous?)
m@24 208 ;; <duration> <duration> -> <duration> (or a distinct duration+?)
m@24 209 ;; <time> <time> -> ERROR?
m@24 210 ;;
m@24 211 ;; time-: <time> <time> -> <duration>
m@24 212 ;; <time> <duration> -> <time>
m@24 213 ;; <duration> <duration> -> <duration> (or a distinct duration-?)
m@24 214 ;; <duration> <time> -> ERROR?
m@24 215 ;; <anchored> <anchored> -> (time- (moment o1) (moment o2)) ? or error?
m@24 216
d@102 217 (defgeneric time+ (object1 object2)
d@102 218 (:documentation "Addition for time designators"))
d@102 219 (defgeneric time- (object1 object2)
d@102 220 (:documentation "Subtraction for time designators"))
m@24 221
d@102 222 (defgeneric time> (object1 object2)
d@118 223 (:documentation "> operator for moment designators"))
m@24 224 (defgeneric time< (object1 object2)
d@118 225 (:documentation "< operator for moment designators")
m@24 226 (:method (o1 o2) (time> o2 o1)))
d@102 227 (defgeneric time= (object1 object2)
d@118 228 (:documentation "= operator for moment designators"))
m@24 229 (defgeneric time>= (object1 object2)
d@118 230 (:documentation ">= operator for moment designators")
m@24 231 (:method (o1 o2) (or (time> o1 o2) (time= o1 o2))))
m@24 232 (defgeneric time<= (object1 object2)
d@118 233 (:documentation "<= operator for moment designators")
m@24 234 (:method (o1 o2) (or (time< o1 o2) (time= o1 o2))))
m@24 235 (defgeneric time/= (object1 object2)
d@118 236 (:documentation "not = operator for moment designators")
m@24 237 (:method (o1 o2) (not (time= o1 o2))))
m@24 238
m@24 239 ;;; Duration protocol
m@24 240
d@118 241 (defgeneric duration> (object1 object2)
d@118 242 (:documentation "> operator for period designators"))
m@24 243 (defgeneric duration< (object1 object2)
d@118 244 (:documentation "< operator for period designators")
m@24 245 (:method (o1 o2) (duration> o2 o1)))
d@118 246 (defgeneric duration= (object1 object2)
d@118 247 (:documentation "= operator for period designators"))
m@24 248 (defgeneric duration>= (object1 object2)
d@118 249 (:documentation ">= operator for period designators")
m@24 250 (:method (o1 o2) (or (duration> o1 o2) (duration= o1 o2))))
m@24 251 (defgeneric duration<= (object1 object2)
d@118 252 (:documentation "<= operator for period designators")
m@24 253 (:method (o1 o2) (or (duration< o1 o2) (duration= o1 o2))))
m@24 254 (defgeneric duration/= (object1 object2)
d@118 255 (:documentation "not = operator for period designators")
m@24 256 (:method (o1 o2) (not (duration= o1 o2))))
m@24 257
m@24 258 ;; for linear scaling:
d@118 259 (defgeneric duration* (object1 object2)
d@118 260 (:documentation "Multiplication operator for period
d@118 261 designators. Intuitively, this makes sense, but it may cause us
d@118 262 trouble with some implementations in the future."))
d@118 263 (defgeneric duration/ (object1 number)
d@118 264 (:documentation "Division operator for period designators. This
d@118 265 may turn out not to mean much. Division is probably useful, but
d@118 266 we may need to define what we mean with care."))
m@24 267
m@24 268 ;;; Pitch protocol
m@24 269
m@24 270 ;; pitch+: <pitch> <pitch> -> ERROR
m@24 271 ;; <pitch> <interval> -> <pitch>
m@24 272 ;; <interval> <pitch> -> <pitch> (same as previous?)
m@24 273 ;; <interval> <interval> -> <interval> (or a distinct interval+?)
m@24 274 ;;
m@24 275 ;; pitch-: <pitch> <pitch> -> <interval>
m@24 276 ;; <pitch> <interval> -> <pitch>
m@24 277 ;; <interval> <interval> -> <interval>
m@24 278 ;; <interval> <pitch> -> ERROR
m@24 279
m@24 280 (defgeneric pitch+ (object1 object2))
m@24 281 (defgeneric pitch- (object1 object2))
m@24 282
m@24 283 (defgeneric pitch> (object1 object2))
m@24 284 (defgeneric pitch< (object1 object2)
m@24 285 (:method (o1 o2) (pitch> o2 o1)))
m@24 286 (defgeneric pitch= (object1 object2))
m@24 287 (defgeneric pitch>= (object1 object2)
m@24 288 (:method (o1 o2) (or (pitch> o1 o2) (pitch= o1 o2))))
m@24 289 (defgeneric pitch<= (object1 object2)
m@24 290 (:method (o1 o2) (or (pitch< o1 o2) (pitch= o1 o2))))
m@24 291 (defgeneric pitch/= (object1 object2)
m@24 292 (:method (o1 o2) (not (pitch= o1 o2))))
m@24 293
m@24 294 ;;; Interval protocol (emphasise _pitch_ not _time_ interval?)
m@24 295
m@24 296 (defgeneric interval> (object1 object2))
m@24 297 (defgeneric interval< (object1 object2)
m@24 298 (:method (o1 o2) (interval> o2 o1)))
m@24 299 (defgeneric interval= (object1 object2))
m@24 300 (defgeneric interval>= (object1 object2)
m@24 301 (:method (o1 o2) (or (interval> o1 o2) (interval= o1 o2))))
m@24 302 (defgeneric interval<= (object1 object2)
m@24 303 (:method (o1 o2) (or (interval< o1 o2) (interval= o1 o2))))
m@24 304 (defgeneric interval/= (object1 object2)
m@24 305 (:method (o1 o2) (not (interval= o1 o2))))
m@24 306
m@24 307 ;;; Allen's (1984) interval relations
m@24 308 ;;; . equals already defined as INTERVAL= above
m@24 309 ;;; . inverses ommitted for now (just use CL:NOT)
m@24 310 ;;; . can all be defined in terms of MEETS (apparently)
m@24 311
m@24 312 (defgeneric meets (object1 object2))
m@24 313 (defgeneric before (object1 object2))
m@24 314 (defgeneric overlaps (object1 object2))
m@24 315 (defgeneric during (object1 object2))
m@24 316 (defgeneric starts (object1 object2))
m@24 317 (defgeneric ends (object1 object2))
m@24 318
m@24 319 ;;; and extensions thereof ...
m@24 320
m@24 321 (defgeneric subinterval (object1 object2)
m@24 322 (:method (o1 o2) (or (starts o1 o2) (during o1 o2) (ends o1 o2))))
m@24 323
m@24 324 (defgeneric disjoint (object1 object2)
m@24 325 (:method (o1 o2)
m@24 326 (or (before o1 o2) (meets o1 o2) (meets o2 o1) (before o2 o1))))
m@24 327
m@24 328 ;;; More time-based functions
d@33 329
d@33 330 (defgeneric period= (object1 object2)
d@33 331 (:method (x y) nil))
d@33 332
d@33 333 (defgeneric find-overlapping (anchored-period sequence)
d@33 334 ;; Returns all members of a sequence of period signifiers that overlap
d@33 335 ;; with the supplied period
d@33 336 (:method (ap s) (remove-if #'(lambda (x) (amuse:disjoint ap x)) s)))
d@33 337
m@24 338 ;; Return the anchored-period representing the intersection of two
m@24 339 ;; anchored-period-specifiers.
m@24 340 (defgeneric period-intersection (anchored-period-specifier1
m@24 341 anchored-period-specifier2))
m@24 342
m@24 343 (defgeneric inter-onset-interval (moment-designator1 moment-designator2)
m@24 344 (:method (md1 md2) (time- (moment md2) (moment md1))))
m@24 345
m@24 346
m@24 347 ;;; Time Signature
m@24 348
d@33 349 (defgeneric get-applicable-time-signatures (anchored-period composition)
d@123 350 (:method (ap c) (find-overlapping ap (time-signatures c)))
d@123 351 (:documentation "Return a list of time-signatures that are
d@123 352 relevant to <anchored-period>. The period may contain
d@123 353 information such as staff position and voicing, and the method
d@123 354 may use this to filter its response"))
m@24 355
d@123 356 (defgeneric time-signature-equal (ts1 ts2)
d@123 357 (:documentation "Comparison operator. The definition of
d@123 358 equality is left open for implementers"))
m@67 359
m@24 360 ;;; Tempo
m@24 361
d@33 362 (defgeneric get-applicable-tempi (anchored-period composition)
d@123 363 (:method (ap c) (find-overlapping ap (tempi c)))
d@123 364 (:documentation "Return a list of tempi that are relevant to
d@123 365 <anchored-period>. The period may contain information such as
d@123 366 staff position and voicing, and the method may use this to
d@123 367 filter its response"))
m@24 368
d@123 369 (defgeneric tempo-equal (t1 t2)
d@123 370 (:documentation "Comparison operator. The definition of
d@123 371 equality is left open for implementers"))
m@67 372
m@24 373 ;;; Tonality (Key Signature / Mode)
m@24 374
d@123 375 (defgeneric get-applicable-key-signatures (object1 object2)
d@123 376 (:documentation "Return a list of key-signatures that are
d@123 377 relevant to <anchored-period>. The period may contain
d@123 378 information such as staff position and voicing, and the method
d@123 379 may use this to filter its response"))
m@24 380
d@123 381 (defgeneric key-signature-equal (ks1 ks2)
d@123 382 (:documentation "Comparison operator. The definition of
d@123 383 equality is left open to implementers"))
m@67 384
m@24 385 ;;; Dynamics
m@24 386 ;;; Voice
m@81 387 ;;; Boundary Strength (phrasing)