annotate implementations/geerdes/constructors.lisp @ 217:d8f650e3796e

Rationalise base and geerdes classes, constructors and methods. Ignore-this: d9d4d88566a6d110844d91d4c70513cd Towards a more standardised interface. Some of these changes (generalised constructors and reader functions) are necessary for amuse-database-admin functionality and some other CHARM-like things. darcs-hash:20090716154406-16a00-8a9b4fb1fc1f5ba75af66a1bbd87e1bb68e02493.gz committer: Jamie Forth <j.forth@gold.ac.uk>
author j.forth <j.forth@gold.ac.uk>
date Thu, 24 Feb 2011 11:23:18 +0000
parents 619194befdd4
children 7afb8cfdcdcf
rev   line source
d@88 1 (cl:in-package #:amuse-geerdes)
d@88 2
j@217 3 ;; Identifiers
j@217 4 ;; FIXME: use standard constructor names?
j@217 5 ;; FIXME: use standard composition-identifier?
j@217 6 (defun g-id (cat-id)
j@217 7 "Make a geerdes-identifier based on a catalogue id"
j@217 8 (make-instance 'geerdes-identifier-cat-id
j@217 9 :cat-id cat-id))
j@217 10
j@217 11 (defun g-id-file-id (file-id)
j@217 12 "Make a geerdes-identifier based on the file id. This is used as
j@217 13 the standard composition-id."
j@217 14 (make-instance 'geerdes-identifier-file-id
j@217 15 :file-id file-id))
j@217 16
j@217 17 (defun make-geerdes-event-identifier (event-id)
j@217 18 (make-instance 'geerdes-event-identifier
j@217 19 :event-id event-id))
j@217 20
j@217 21 ;; Events
j@217 22
d@88 23 (defgeneric %initialise-notes (composition))
d@88 24 (defmethod %initialise-notes ((composition geerdes-composition))
d@88 25 (let ((notes) (l 0) (last-time 0) (monody-notes)
d@88 26 (monody (make-instance 'geerdes-monody :file-id (file-id composition)))
j@212 27 (timebase (midi-timebase composition)))
d@88 28 (dolist (row (%midi-events composition))
d@88 29 (let* ((note (if (pitched-row-p row)
d@136 30 (make-geerdes-pitched-event (%fast-pitch row)
d@136 31 (%fast-velocity row)
d@136 32 (%fast-patch row)
d@136 33 (%fast-channel row)
d@136 34 (%fast-track row)
d@136 35 (%fast-onset row timebase)
d@136 36 (%fast-duration row timebase)
d@136 37 (%fast-id row))
d@136 38 (make-geerdes-percussive-event (%fast-pitch row)
d@136 39 (%fast-velocity row)
d@136 40 (%fast-patch row)
d@136 41 (%fast-channel row)
d@136 42 (%fast-track row)
d@136 43 (%fast-onset row timebase)
d@136 44 (%fast-duration row timebase)
d@136 45 (%fast-id row)))))
d@88 46 (when (%fast-monodyp row)
d@133 47 (let ((monody-note (copy-event note)))
d@133 48 (setf (duration monody-note) (%fast-monody-duration row timebase))
d@133 49 (push monody-note monody-notes)))
d@88 50 (when (> (timepoint (cut-off note)) last-time)
d@88 51 (setf last-time (timepoint (cut-off note))))
d@88 52 (push note notes)
d@88 53 (incf l)))
d@88 54 (sequence:adjust-sequence composition l :initial-contents (reverse notes))
d@88 55 (setf (duration composition) last-time
d@88 56 (timepoint composition) 0)
d@88 57 (when monody-notes
d@88 58 (setf (%monody composition) (sequence:adjust-sequence monody (length monody-notes)
d@88 59 :initial-contents (reverse monody-notes))
d@88 60 (timepoint (%monody composition)) (timepoint (elt monody 0))
d@88 61 (duration (%monody composition)) (- (timepoint (cut-off (car monody-notes)))
d@88 62 (timepoint (elt monody 0)))))
d@88 63 composition))
d@88 64
d@88 65 (defgeneric %initialise-constituents (composition))
d@88 66 (defmethod %initialise-constituents ((composition geerdes-composition))
d@88 67 ;; FIXME: Should the duration of composition be affected by this? On
d@88 68 ;; the one hand, it makes no difference to the musical content, but
d@88 69 ;; on the other, it seems illogical to reach outside the period.
j@212 70 (let ((timebase (midi-timebase composition))
d@88 71 (time-sigs)
d@88 72 (tempi)
d@88 73 (mystery 0))
d@88 74 (dolist (row (%midi-constituents composition))
d@88 75 (cond
d@88 76 ((%fast-tempo row)
d@136 77 (push (make-standard-tempo-period
d@88 78 (microsecond-per-crotchet-to-bpm
d@88 79 (%fast-tempo row))
d@88 80 (%fast-onset row timebase)
d@88 81 (%fast-duration row timebase))
d@88 82 tempi))
d@88 83 ((%fast-numerator row)
d@136 84 (push (make-standard-time-signature-period
d@88 85 (%fast-numerator row)
d@88 86 (%fast-denominator row)
d@88 87 (%fast-onset row timebase)
d@88 88 (%fast-duration row timebase))
d@88 89 time-sigs))
d@88 90 (t (incf mystery))))
d@88 91 (setf (time-signatures composition) (reverse time-sigs)
d@88 92 (tempi composition) (reverse tempi))
d@88 93 (when (%monody composition)
d@88 94 (setf (time-signatures (%monody composition)) (time-signatures composition)
d@88 95 (tempi (%monody composition)) (tempi composition)))
d@88 96 (format t "There are ~D constituents not processed~%" mystery)
d@88 97 composition))
d@88 98
d@88 99 (defun %fast-track (row)
d@88 100 (first row))
d@88 101 (defun %fast-channel (row)
d@88 102 (second row))
d@88 103 (defun %fast-onset (row timebase)
d@88 104 (/ (third row) timebase))
d@88 105 (defun %fast-duration (row timebase)
d@88 106 (/ (fourth row) timebase))
d@88 107 (defun %fast-patch (event-row)
d@88 108 (fifth event-row))
d@88 109 (defun %fast-pitch (event-row)
d@88 110 (sixth event-row))
d@88 111 (defun %fast-velocity (event-row)
d@88 112 (seventh event-row))
d@88 113 (defun %fast-id (event-row)
d@88 114 (eighth event-row))
d@88 115 (defun %fast-monodyp (event-row)
d@88 116 (ninth event-row))
d@133 117 (defun %fast-monody-duration (event-row timebase)
d@133 118 (/ (tenth event-row) timebase))
d@88 119
d@88 120 (defun %fast-tempo (tp-row)
d@88 121 (eighth tp-row))
d@88 122 (defun %fast-numerator (ts-row)
d@88 123 (ninth ts-row))
d@88 124 (defun %fast-denominator (ts-row)
d@88 125 (tenth ts-row))
d@88 126
d@88 127 (defun pitched-row-p (event-row)
d@88 128 (and (not (= (%fast-channel event-row) 10))
d@88 129 (< (%fast-patch event-row) 112)))
d@88 130
j@217 131 (defun make-geerdes-pitched-event (pitch-number velocity patch channel
j@217 132 track onset duration event-id)
d@88 133 (make-instance 'geerdes-pitched-event
d@88 134 :number pitch-number
d@88 135 :velocity velocity
d@88 136 :patch patch
d@88 137 :channel channel
d@88 138 :track track
d@88 139 :time onset
d@88 140 :interval duration
j@217 141 :identifier (make-geerdes-event-identifier
j@217 142 event-id)))
d@88 143
d@88 144 (defun make-geerdes-percussive-event (pitch-number velocity patch
j@217 145 channel track onset duration
j@217 146 event-id)
d@88 147 (make-instance 'geerdes-percussive-event
d@88 148 :sound pitch-number
d@88 149 :velocity velocity
d@88 150 :patch patch
d@88 151 :channel channel
d@88 152 :track track
d@88 153 :time onset
d@88 154 :interval duration
j@217 155 :identifier (make-geerdes-event-identifier
j@217 156 event-id)))
d@88 157
d@88 158 (defmethod copy-event ((event geerdes-pitched-event))
d@88 159 (with-slots ((channel amuse-midi::channel)
d@88 160 (track amuse-midi::track)
d@88 161 (number amuse::number)
d@88 162 (time amuse::time)
d@88 163 (interval amuse::interval)
d@88 164 (velocity amuse-midi::velocity)
j@217 165 (patch amuse-midi::patch)
j@217 166 identifier)
d@88 167 event
d@88 168 (make-instance 'geerdes-pitched-event
d@88 169 :channel channel
d@88 170 :track track
d@88 171 :number number
d@88 172 :time time
d@88 173 :interval interval
d@88 174 :velocity velocity
d@88 175 :patch patch
j@217 176 :identifier identifier)))
j@217 177
d@133 178 (defmethod copy-event ((event geerdes-percussive-event))
d@88 179 (with-slots ((channel amuse-midi::channel)
d@88 180 (track amuse-midi::track)
d@88 181 (time amuse::time)
d@88 182 (interval amuse::interval)
d@88 183 (velocity amuse-midi::velocity)
d@88 184 (patch amuse-midi::patch)
j@217 185 (sound amuse-midi::sound)
j@217 186 identifier)
d@88 187 event
d@88 188 (make-instance 'geerdes-percussive-event
d@133 189 :channel channel
d@88 190 :track track
d@88 191 :time time
d@88 192 :interval interval
d@88 193 :velocity velocity
d@88 194 :patch patch
d@88 195 :sound sound
j@217 196 :identifier identifier)))
d@88 197
d@88 198 ;; We want any function that generates a sequence from a geerdes
d@88 199 ;; composition to preserve all slot values:
d@154 200 #+nil
d@88 201 (defmethod sequence:make-sequence-like :around ((o geerdes-composition)
d@88 202 length
d@88 203 &key (initial-element nil iep)
d@88 204 (initial-contents nil icp))
d@88 205 (declare (ignore iep icp length initial-element initial-contents))
d@88 206 (let ((result (call-next-method)))
d@88 207 (setf (%db-entry result) (%db-entry o))
d@88 208 result))