annotate implementations/geerdes/methods.lisp @ 212:619194befdd4

add identifier and timebase slots to midifile composition class Ignore-this: 4e72a0860344399452bea196c3739bbf darcs-hash:20090524150506-16a00-bce845ccf20a9289a4015fb58287f25ebfa178ad.gz committer: Jamie Forth <j.forth@gold.ac.uk>
author j.forth <j.forth@gold.ac.uk>
date Thu, 24 Feb 2011 11:23:17 +0000
parents e2839225f6fb
children d8f650e3796e
rev   line source
d@88 1 (cl:in-package #:amuse-geerdes)
d@88 2
d@88 3 ;;; Compositions
d@88 4
d@88 5 ;; identifiers
d@88 6 (defun g-id (cat-id)
d@100 7 "Make a geerdes-identifier based on a catalogue id"
d@88 8 (make-instance 'geerdes-identifier-cat-id :cat-id cat-id))
d@88 9 (defun g-id-file-id (file-id)
d@100 10 "Make a geerdes-identifier based on a catalogue id"
d@88 11 (make-instance 'geerdes-identifier-file-id :file-id file-id))
d@88 12
d@100 13 (defgeneric cat-id (object)
d@134 14 (:documentation "Return a database catalogue id for object (for
d@134 15 Geerdes data, this is the company's own ID"))
d@100 16 (defgeneric file-id (object)
d@134 17 (:documentation "Return a database file id for object (for
d@134 18 Geerdes data, this is a unique integer identifier)"))
d@88 19 (defgeneric (setf cat-id) (value object))
d@88 20 (defgeneric (setf file-id) (value object))
d@88 21
d@88 22 (defmethod cat-id ((object geerdes-composition))
d@88 23 (%db-cat-id object))
d@88 24 (defmethod cat-id ((object geerdes-identifier-cat-id))
d@88 25 (slot-value object 'cat-id))
d@88 26 (defmethod file-id ((object geerdes-composition))
d@88 27 (%db-file-id object))
d@88 28 (defmethod file-id ((object geerdes-identifier-file-id))
d@88 29 (slot-value object 'file-id))
d@88 30 (defmethod (setf cat-id) (value (object geerdes-composition))
d@88 31 (setf (%db-cat-id object) value))
d@88 32 (defmethod (setf cat-id) (value (object geerdes-identifier-cat-id))
d@88 33 (setf (slot-value object 'cat-id) value))
d@88 34 (defmethod (setf file-id) (value (object geerdes-composition))
d@88 35 (setf (%db-file-id object) value))
d@88 36 (defmethod (setf file-id) (value (object geerdes-identifier-file-id))
d@88 37 (setf (slot-value object 'file-id) value))
d@88 38
j@211 39 ;; Specialised constructors
j@211 40
j@211 41 (defmethod make-composition-identifier ((package (eql *package*))
j@211 42 composition-id)
j@211 43 (g-id-file-id composition-id))
j@211 44
d@88 45 ;; Composition
d@88 46
d@88 47 (defmethod get-composition ((identifier geerdes-identifier))
d@88 48 (let* ((composition (get-geerdes-composition identifier)))
d@88 49 (%initialise-notes composition)
d@88 50 (%initialise-constituents composition)))
d@88 51
d@88 52 (defgeneric get-geerdes-composition (identifier))
d@88 53 (defmethod get-geerdes-composition ((identifier geerdes-identifier-cat-id))
d@88 54 #.(clsql:locally-enable-sql-reader-syntax)
d@88 55 (let* ((cat-id (cat-id identifier))
d@88 56 (file-info (car (clsql:select [id] [timebase]
d@88 57 :from [midi_file]
d@88 58 :where [= [cat_id] cat-id]
d@88 59 :flatp t
j@211 60 :result-types :auto
j@211 61 :database *amuse-database*)))
d@88 62 (timebase (second file-info))
d@88 63 (file-id (first file-info))
d@88 64 (composition (make-instance 'geerdes-composition
j@212 65 :identifier identifier
d@88 66 :file-id file-id
d@88 67 :cat-id cat-id
d@88 68 :midi-timebase timebase)))
d@88 69 (setf (%midi-events composition) (get-db-events file-id)
d@88 70 (%midi-constituents composition) (get-db-constituents file-id))
d@88 71 #.(clsql:restore-sql-reader-syntax-state)
d@88 72 composition))
j@211 73
d@88 74 (defmethod get-geerdes-composition ((identifier geerdes-identifier-file-id))
d@88 75 #.(clsql:locally-enable-sql-reader-syntax)
d@88 76 (let* ((file-id (file-id identifier))
d@88 77 (file-info (car (clsql:select [cat_id] [timebase]
d@88 78 :from [midi_file]
d@88 79 :where [= [id] file-id]
d@88 80 :flatp t
j@211 81 :result-types :auto
j@211 82 :database *amuse-database*)))
d@88 83 (timebase (second file-info))
d@88 84 (cat-id (first file-info))
d@88 85 (composition (make-instance 'geerdes-composition
j@212 86 :identifier identifier
d@88 87 :cat-id cat-id
d@88 88 :file-id file-id
d@88 89 :midi-timebase timebase)))
d@88 90 (setf (%midi-events composition) (get-db-events file-id)
d@88 91 (%midi-constituents composition) (get-db-constituents file-id))
d@88 92 #.(clsql:restore-sql-reader-syntax-state)
d@88 93 composition))
d@88 94
d@88 95 (defun get-db-events (file-id)
d@88 96 (clsql:query
d@88 97 (concatenate 'string "
d@133 98 SELECT track, channel, start, duration, patch, pitch, velocity, id, event_id, mel_duration
d@88 99 FROM midi_event LEFT JOIN derived_midi_monody ON (id=event_id)
d@88 100 WHERE file_id=" (princ-to-string file-id)
j@211 101 " ORDER BY start")
j@211 102 :database *amuse-database*))
j@211 103
d@88 104 (defun get-db-constituents (file-id)
d@88 105 (clsql:query (concatenate 'string "
d@88 106 SELECT track, channel, start, duration,
d@88 107 param.num, param.value, pb.value, tp.value, ts.num, ts.denom
d@88 108 FROM midi_constituent c
d@88 109 LEFT JOIN midi_pb pb ON (id=pb.constituent_id)
d@88 110 LEFT JOIN midi_tempo tp ON (id=tp.constituent_id)
d@88 111 LEFT JOIN midi_timesig ts ON (id=ts.constituent_id)
d@88 112 LEFT JOIN midi_param param ON (id=param.constituent_id)
d@88 113 WHERE c.file_id=" (princ-to-string file-id)
j@211 114 " ORDER BY start")
j@211 115 :database *amuse-database*))
d@101 116
d@101 117 (defmethod monody ((composition geerdes-composition))
d@101 118 (unless (amuse-geerdes::%monody composition)
d@101 119 (setf (amuse-geerdes::%monody composition)
d@101 120 (get-monody composition)))
d@101 121 (amuse-geerdes::%monody composition))
d@101 122
d@101 123 (defgeneric get-monody (composition))
d@101 124 (defmethod get-monody ((composition geerdes-composition))
d@101 125 ;;; FIXME: FIXED-[THIS IS DANGEROUS - IT EDITS NOTE LENGTH]
d@101 126 ;; FIXME: As a result of this fix, notes no longer eq their monody
d@101 127 ;; versions
d@101 128 ;;; FIXME: This is a serious issue. Needs to be addressed by
d@101 129 ;; a proper implementation of constituent with annotations
d@101 130 ;;; From DTM: - Select notes
d@101 131 ;; on channel 4
d@101 132 (let ((vocal-line (loop for event being the elements of (lead-vocal-part composition)
d@101 133 collect (copy-event event))))
d@101 134 (when vocal-line
d@101 135 (let* ((comp (make-instance 'geerdes-composition
d@101 136 :file-id (file-id composition)
d@101 137 :time (timepoint composition)
d@101 138 :tempi (tempi composition)
d@101 139 :time-signatures (time-signatures composition)
d@101 140 :interval (duration composition)))
d@101 141 (vocal-composition (sequence:adjust-sequence comp
d@101 142 (length vocal-line)
d@101 143 :initial-contents vocal-line))
d@101 144 (monody (make-instance 'geerdes-monody
d@101 145 :time (timepoint composition)
d@101 146 :file-id (file-id composition)
d@101 147 :tempi (tempi composition)
d@101 148 :time-signatures (time-signatures composition)
d@101 149 :interval (duration composition))) ;; Overly inclusive?
d@101 150 (monody-events (monodificate vocal-composition)))
d@101 151 (sequence:adjust-sequence monody (length monody-events)
d@101 152 :initial-contents monody-events)))))
d@101 153
d@101 154 (defgeneric lead-vocal-part (time-ordered-constituent)
d@101 155 (:method (toc) (remove-if-not #'lead-vocalp toc)))
d@101 156
d@101 157 (defgeneric lead-vocalp (event)
d@101 158 (:method (e) (declare (ignore e)) nil))
m@103 159 (defmethod lead-vocalp ((event geerdes-pitched-event))
d@101 160 (= (midi-channel event) 4))
d@114 161
d@130 162 (defmethod crotchet ((object geerdes-object))
d@139 163 (make-standard-period 1))