annotate base/generics.lisp @ 118:d574d015f5af

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