annotate implementations/mtp/methods.lisp @ 292:80c227c1c0da

The MTP implementation of AMUSE:MONODY now uses the voice of the first event in the piece. darcs-hash:20090723085710-c0ce4-0324442e9897c7a903fa20cfd16d18f880718439.gz
author Marcus Pearce <m.pearce@gold.ac.uk>
date Thu, 23 Jul 2009 09:57:10 +0100
parents 2d2bc910c364
children 2284dbc7d51a 984e0b4dfaab 5271a0aa06d6
rev   line source
m@46 1 (cl:in-package #:amuse-mtp)
m@46 2
m@46 3 ;;; Compositions
m@46 4
m@46 5 #.(clsql:locally-enable-sql-reader-syntax)
m@46 6
m@87 7 (defvar *event-attributes*
m@87 8 (list [dataset-id] [composition-id] [event-id]
m@87 9 [onset] [dur] [deltast] [cpitch] [mpitch] [accidental] [keysig] [mode]
m@87 10 [barlength] [pulses] [phrase] [tempo] [dyn] [voice]))
m@87 11
m@53 12 (defgeneric get-dataset (identifer))
m@53 13
m@53 14 (defmethod get-dataset ((identifier mtp-dataset-identifier))
m@53 15 (let* ((dataset-id (dataset-id identifier))
m@53 16 (where-clause [= [dataset-id] dataset-id])
m@149 17 (db-dataset (car (clsql:select [*] :from [mtp-dataset] :where where-clause)))
m@87 18 (db-compositions (clsql:select [composition-id][description]
m@87 19 :from [mtp-composition]
m@87 20 :order-by '(([composition-id] :asc))
m@87 21 :where where-clause))
m@87 22 (db-events (apply #'clsql:select
m@87 23 (append *event-attributes*
m@87 24 (list :from [mtp-event]
m@87 25 :order-by '(([composition-id] :asc)
m@87 26 ([event-id] :asc))
m@87 27 :where where-clause))))
m@87 28 (dataset (make-mtp-dataset :dataset-id (first db-dataset)
m@87 29 :description (second db-dataset)
m@87 30 :timebase (third db-dataset)
m@87 31 :midc (fourth db-dataset)))
m@53 32 (compositions nil)
m@87 33 (events nil))
m@87 34 ;; for each db-composition
m@87 35 (dolist (dbc db-compositions)
m@149 36 (let ((composition-id (car dbc))
m@149 37 (description (car dbc)))
m@87 38 ;; for each db-event
m@87 39 (do* ((dbes db-events (cdr dbes))
m@87 40 (dbe (car dbes) (car dbes))
m@87 41 (cid (second dbe) (second dbe)))
m@87 42 ((or (null dbes) (not (= cid composition-id)))
m@87 43 (setf db-events dbes))
m@87 44 (when dbe
m@87 45 (push (db-event->mtp-event dbe) events)))
m@149 46 (when events
m@149 47 (let* ((interval (+ (timepoint (car events)) (duration (car events))))
m@149 48 (composition
m@149 49 (make-mtp-composition :dataset-id dataset-id
m@149 50 :composition-id composition-id
m@149 51 :description description
m@149 52 :time 0
m@149 53 :interval interval)))
m@149 54 (sequence:adjust-sequence composition (length events)
m@149 55 :initial-contents (nreverse events))
m@149 56 (setf events nil)
m@149 57 (push composition compositions)))))
m@53 58 (sequence:adjust-sequence dataset (length compositions)
m@53 59 :initial-contents (nreverse compositions))
m@53 60 dataset))
m@53 61
m@46 62 (defmethod get-composition ((identifier mtp-composition-identifier))
m@46 63 (let* ((dataset-id (dataset-id identifier))
m@46 64 (composition-id (composition-id identifier))
m@46 65 (where-clause [and [= [dataset-id] dataset-id]
m@46 66 [= [composition-id] composition-id]])
m@46 67 (description
m@51 68 (car (clsql:select [description] :from [mtp-composition]
m@46 69 :where where-clause :flatp t :field-names nil)))
m@87 70 (db-events (apply #'clsql:select
m@87 71 (append *event-attributes*
m@87 72 (list :from [mtp-event]
m@87 73 :order-by '(([event-id] :asc))
m@87 74 :where where-clause))))
m@46 75 (events nil))
m@87 76 (dolist (e db-events)
m@87 77 (push (db-event->mtp-event e) events))
m@46 78 (let* ((interval (+ (timepoint (car events)) (duration (car events))))
m@46 79 (composition
m@46 80 (make-mtp-composition :dataset-id dataset-id
m@46 81 :composition-id composition-id
m@46 82 :description description
m@46 83 :time 0
m@46 84 :interval interval)))
m@46 85 (sequence:adjust-sequence composition (length events)
m@46 86 :initial-contents (nreverse events))
m@46 87 composition)))
m@46 88
m@90 89 #.(clsql:restore-sql-reader-syntax-state)
m@90 90
m@87 91 (defun db-event->mtp-event (db-event)
m@87 92 (let* ((slots ; the order must match *event-attributes*
m@87 93 '(amuse::time amuse::interval deltast cpitch mpitch accidental
m@186 94 keysig mode barlength pulses phrase tempo dyn voice bioi))
m@46 95 (mtp-event
m@87 96 (make-mtp-event :dataset-id (first db-event)
m@87 97 :composition-id (second db-event)
m@87 98 :event-id (third db-event))))
m@87 99 (do* ((slts slots (cdr slts))
m@87 100 (db-atts (nthcdr 3 db-event) (cdr db-atts)))
m@87 101 ((null slts) mtp-event)
m@87 102 (setf (slot-value mtp-event (car slts)) (car db-atts)))))
m@90 103
m@90 104 ;;; Monodies
m@90 105
m@90 106 (defmethod monody ((identifier mtp-composition-identifier))
m@90 107 (monody (get-composition identifier)))
m@90 108
m@90 109 (defmethod monody ((c mtp-composition))
m@292 110 ;; using the voice of the first event in the piece
m@90 111 (let ((monody (make-instance 'mtp-monody
m@90 112 :dataset-id (dataset-id c)
m@90 113 :composition-id (composition-id c)
m@90 114 :description (description c)
m@90 115 :time 0
m@90 116 :interval (duration c)))
m@90 117 (events nil)
m@292 118 (monody-voice nil))
m@90 119 (sequence:dosequence (event c)
m@292 120 (when (null monody-voice)
m@292 121 (setf monody-voice (%mtp-voice event)))
m@90 122 (when (= (%mtp-voice event) monody-voice)
m@90 123 (push event events)))
m@90 124 (sequence:adjust-sequence
m@90 125 monody (length events)
m@90 126 :initial-contents (sort events #'< :key #'amuse:timepoint))
m@90 127 monody))
m@46 128
m@46 129 ;;; Constituents from compositions: time-signatures
m@46 130
m@96 131 (defmethod crotchet ((dataset mtp-dataset))
d@136 132 (amuse:make-standard-period
m@96 133 (/ (dataset-timebase dataset) 4)))
m@87 134
m@46 135 #.(clsql:locally-enable-sql-reader-syntax)
m@96 136 (defmethod crotchet ((composition mtp-composition))
m@96 137 (let ((timebase
m@96 138 (car (clsql:select [timebase] :from [mtp-dataset]
m@96 139 :where [= [dataset-id]
m@96 140 (dataset-id composition)]
m@96 141 :flatp t
m@96 142 :field-names nil))))
d@136 143 (amuse:make-standard-period (/ timebase 4))))
m@96 144 (defmethod crotchet ((event mtp-event))
m@96 145 (let ((timebase
m@96 146 (car (clsql:select [timebase] :from [mtp-dataset]
m@96 147 :where [= [dataset-id]
m@96 148 (dataset-id event)]
m@96 149 :flatp t
m@96 150 :field-names nil))))
d@136 151 (amuse:make-standard-period (/ timebase 4))))
m@46 152 #.(clsql:restore-sql-reader-syntax-state)
m@46 153
m@69 154 (defmethod get-applicable-time-signatures ((e mtp-event) c)
m@69 155 (declare (ignore c))
m@291 156 ;(format t "~&GATS ~A ~A ~A: pulses = ~A; barlength = ~A.~%" (dataset-id e) (composition-id e) (event-id e) (%mtp-pulses e) (%mtp-barlength e))
m@291 157 (let* ((pulses (%mtp-pulses e))
m@291 158 (barlength (%mtp-barlength e))
m@291 159 (timebase (* 4 (duration (crotchet e))))
m@291 160 (numerator (if (null pulses) 0 pulses))
m@291 161 (denominator (if (null barlength)
m@291 162 1
m@291 163 (/ timebase (/ barlength pulses)))))
m@291 164 (list
m@291 165 (amuse:make-standard-time-signature-period numerator
m@291 166 denominator
d@136 167 (timepoint e)
d@136 168 (duration e)))))
m@69 169
m@46 170 (defmethod time-signatures ((c mtp-composition))
m@46 171 (let ((results nil)
m@46 172 (interval 0)
m@46 173 (current nil))
m@46 174 (sequence:dosequence (event c)
m@70 175 (let ((ts (car (get-applicable-time-signatures event c))))
m@46 176 (when (and (%mtp-barlength event)
m@46 177 (%mtp-pulses event)
m@46 178 (or (null current)
m@46 179 (not (time-signature-equal ts current))))
m@46 180 (unless (null current)
m@46 181 (setf (duration current) interval)
m@46 182 (push current results))
m@46 183 (setf interval 0
m@46 184 current ts)))
m@46 185 (incf interval (%mtp-deltast event))
m@46 186 (incf interval (duration event)))
m@46 187 (when current
m@46 188 (setf (duration current) interval)
m@46 189 (push current results))
m@46 190 (nreverse results)))
m@46 191
m@46 192 ;;; Constituents from compositions: key-signatures
m@46 193
m@69 194 (defmethod get-applicable-key-signatures ((e mtp-event) c)
m@69 195 (declare (ignore c))
m@69 196 (let* ((sharps (%mtp-keysig e))
m@68 197 (mode (%mtp-mode e))
m@69 198 (midi-mode (and mode (if (= mode 0) 0 1))))
d@136 199 (list (amuse:make-midi-key-signature-period sharps midi-mode
d@136 200 (timepoint e)
d@136 201 (duration e)))))
m@46 202
m@68 203 (defmethod key-signatures ((c mtp-composition))
m@46 204 (let ((results nil)
m@46 205 (interval 0)
m@46 206 (current nil))
m@46 207 (sequence:dosequence (event c)
m@69 208 (let ((ks (car (get-applicable-key-signatures event c))))
m@46 209 (when (and (%mtp-keysig event)
m@46 210 (%mtp-mode event)
m@46 211 (or (null current)
m@46 212 (not (key-signature-equal ks current))))
m@46 213 (unless (null current)
m@46 214 (setf (duration current) interval)
m@46 215 (push current results))
m@46 216 (setf interval 0
m@46 217 current ks)))
m@46 218 (incf interval (%mtp-deltast event))
m@46 219 (incf interval (duration event)))
m@46 220 (when current
m@46 221 (setf (duration current) interval)
m@46 222 (push current results))
m@46 223 (nreverse results)))
m@46 224
m@46 225 ;;; Constituents from compositions: tempi
m@46 226
m@69 227 (defmethod get-applicable-tempi ((e mtp-event) c)
m@69 228 (declare (ignore c))
d@136 229 (list (amuse:make-standard-tempo-period (%mtp-tempo e)
d@136 230 (timepoint e)
d@136 231 (duration e))))
m@69 232
m@46 233 (defmethod tempi ((c mtp-composition))
m@46 234 (let ((results nil)
m@46 235 (interval 0)
m@46 236 (current nil))
m@46 237 (sequence:dosequence (event c)
m@46 238 (when (and (%mtp-tempo event)
m@46 239 (or (null current)
m@46 240 (not (= (bpm current) (%mtp-tempo event)))))
m@46 241 (unless (null current)
m@46 242 (setf (duration current) interval)
m@46 243 (push current results))
m@69 244 (let ((new (car (get-applicable-tempi event c))))
m@46 245 (setf interval 0
m@46 246 current new)))
m@46 247 (incf interval (%mtp-deltast event))
m@46 248 (incf interval (duration event)))
m@46 249 (when current
m@46 250 (setf (duration current) interval)
m@46 251 (push current results))
m@46 252 (nreverse results)))
m@46 253
m@46 254 ;;; Events: Pitch
m@46 255
m@46 256 (defmethod chromatic-pitch ((e mtp-event))
m@46 257 (make-chromatic-pitch (%mtp-cpitch e)))
m@46 258
m@46 259 (defmethod midi-pitch-number ((e mtp-event))
m@46 260 (%mtp-cpitch e))
m@46 261
m@110 262 (defmethod diatonic-pitch-cp ((e mtp-event))
m@110 263 ;; MIPS morphetic pitch is relative to An0 while cpitch is relative to Cn2
m@110 264 (- (%mtp-cpitch e) 21))
m@110 265
m@110 266 (defmethod diatonic-pitch-mp ((e mtp-event))
m@82 267 ;; MIPS morphetic pitch is relative to An0 while mpitch is relative to Cn2
m@82 268 (- (%mtp-mpitch e) 12))
m@82 269
m@46 270 (defmethod diatonic-pitch ((e mtp-event))
m@110 271 (make-mips-pitch (diatonic-pitch-cp e)
m@110 272 (diatonic-pitch-mp e)))
m@82 273
m@84 274 (defmethod asa-pitch-string ((e mtp-event))
m@110 275 (asa-pitch-string (diatonic-pitch e)))
m@84 276
m@82 277 #.(clsql:locally-enable-sql-reader-syntax)
m@82 278 (defmethod middle-c ((e mtp-event))
m@82 279 (let ((cpitch (car (clsql:select [midc] :from [dataset]
m@82 280 :where [= [dataset-id] (dataset-id e)]
m@82 281 :flatp t :field-names nil))))
m@82 282 (make-mtp-event :cpitch cpitch :mpitch (* (/ cpitch 12) 7))))
m@82 283 #.(clsql:restore-sql-reader-syntax-state)
m@79 284
m@79 285 ;;; Phrase boundaries
m@79 286
m@98 287 (defmethod ground-truth-segmenter-before ((c mtp-composition))
m@98 288 (declare (ignore c))
m@98 289 (make-instance 'mtp-before-segmenter))
m@98 290
m@98 291 (defmethod ground-truth-segmenter-after ((c mtp-composition))
m@98 292 (declare (ignore c))
m@99 293 (make-instance 'mtp-after-segmenter))
m@98 294
m@98 295 (defmethod ground-truth-segmenter-before ((e mtp-event))
m@98 296 (declare (ignore e))
m@98 297 (make-instance 'mtp-before-segmenter))
m@98 298
m@98 299 (defmethod ground-truth-segmenter-after ((e mtp-event))
m@98 300 (declare (ignore e))
m@99 301 (make-instance 'mtp-after-segmenter))
m@98 302
m@79 303 (defmethod boundary-strength ((s mtp-before-segmenter) (e mtp-event) c)
m@79 304 (declare (ignore s c))
m@79 305 (let ((phrase (%mtp-phrase e)))
m@79 306 (case phrase
m@79 307 (-1 1)
m@79 308 (t 0))))
m@79 309
m@79 310 (defmethod boundary-strength ((s mtp-after-segmenter) (e mtp-event) c)
m@79 311 (declare (ignore s c))
m@79 312 (let ((phrase (%mtp-phrase e)))
m@79 313 (case phrase
m@79 314 (1 1)
m@79 315 (t 0))))