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@53
|
7 (defgeneric get-dataset (identifer))
|
m@53
|
8
|
m@53
|
9 (defmethod get-dataset ((identifier mtp-dataset-identifier))
|
m@53
|
10 (let* ((dataset-id (dataset-id identifier))
|
m@53
|
11 (where-clause [= [dataset-id] dataset-id])
|
m@53
|
12 (data (clsql:select [*] :from [mtp-dataset] :where where-clause))
|
m@53
|
13 (dataset (make-mtp-dataset :dataset-id (first data)
|
m@53
|
14 :description (second data)
|
m@53
|
15 :timebase (third data)
|
m@53
|
16 :midc (fourth data)))
|
m@53
|
17 (compositions nil)
|
m@53
|
18 (composition-count
|
m@53
|
19 (1+
|
m@53
|
20 (car
|
m@53
|
21 (clsql:select [max [composition-id]] :from [mtp-composition]
|
m@53
|
22 :where where-clause :flatp t :field-names nil)))))
|
m@53
|
23 (dotimes (composition-id composition-count)
|
m@53
|
24 (push (get-composition
|
m@53
|
25 (make-mtp-composition-identifier dataset-id composition-id))
|
m@53
|
26 compositions))
|
m@53
|
27 (sequence:adjust-sequence dataset (length compositions)
|
m@53
|
28 :initial-contents (nreverse compositions))
|
m@53
|
29 dataset))
|
m@53
|
30
|
m@82
|
31
|
m@82
|
32
|
m@46
|
33 (defmethod get-composition ((identifier mtp-composition-identifier))
|
m@46
|
34 (let* ((dataset-id (dataset-id identifier))
|
m@46
|
35 (composition-id (composition-id identifier))
|
m@46
|
36 (where-clause [and [= [dataset-id] dataset-id]
|
m@46
|
37 [= [composition-id] composition-id]])
|
m@46
|
38 (description
|
m@51
|
39 (car (clsql:select [description] :from [mtp-composition]
|
m@46
|
40 :where where-clause :flatp t :field-names nil)))
|
m@46
|
41 (event-count
|
m@46
|
42 (1+
|
m@46
|
43 (car
|
m@51
|
44 (clsql:select [max [event-id]] :from [mtp-event]
|
m@46
|
45 :where where-clause :flatp t :field-names nil))))
|
m@46
|
46 (events nil))
|
m@46
|
47 (dotimes (event-id event-count)
|
m@46
|
48 (push (get-event dataset-id composition-id event-id) events))
|
m@46
|
49 (let* ((interval (+ (timepoint (car events)) (duration (car events))))
|
m@46
|
50 (composition
|
m@46
|
51 (make-mtp-composition :dataset-id dataset-id
|
m@46
|
52 :composition-id composition-id
|
m@46
|
53 :description description
|
m@46
|
54 :time 0
|
m@46
|
55 :interval interval)))
|
m@46
|
56 (sequence:adjust-sequence composition (length events)
|
m@46
|
57 :initial-contents (nreverse events))
|
m@46
|
58 composition)))
|
m@46
|
59
|
m@46
|
60 (defun get-event (dataset-id composition-id event-id)
|
m@46
|
61 (let* ((attributes
|
m@46
|
62 (list (list 'amuse::time [onset])
|
m@46
|
63 (list 'amuse::interval [dur])
|
m@46
|
64 (list 'deltast [deltast])
|
m@46
|
65 (list 'cpitch [cpitch])
|
m@46
|
66 (list 'mpitch [mpitch])
|
m@46
|
67 (list 'accidental [accidental])
|
m@46
|
68 (list 'keysig [keysig])
|
m@46
|
69 (list 'mode [mode])
|
m@46
|
70 (list 'barlength [barlength])
|
m@46
|
71 (list 'pulses [pulses])
|
m@46
|
72 (list 'phrase [phrase])
|
m@46
|
73 (list 'tempo [tempo])
|
m@46
|
74 (list 'dyn [dyn])
|
m@46
|
75 (list 'voice [voice])))
|
m@46
|
76 (mtp-event
|
m@46
|
77 (make-mtp-event :dataset-id dataset-id
|
m@46
|
78 :composition-id composition-id
|
m@46
|
79 :event-id event-id)))
|
m@46
|
80 (dolist (a attributes mtp-event)
|
m@46
|
81 (let ((value
|
m@51
|
82 (clsql:select (cadr a) :from [mtp-event]
|
m@46
|
83 :where [and [= [dataset-id] dataset-id]
|
m@46
|
84 [= [composition-id] composition-id]
|
m@46
|
85 [= [event-id] event-id]]
|
m@46
|
86 :flatp t
|
m@46
|
87 :field-names nil)))
|
m@46
|
88 (setf (slot-value mtp-event (car a)) (car value))))))
|
m@46
|
89
|
m@46
|
90 #.(clsql:restore-sql-reader-syntax-state)
|
m@46
|
91
|
m@46
|
92
|
m@46
|
93 ;;; Constituents from compositions: time-signatures
|
m@46
|
94
|
m@46
|
95 #.(clsql:locally-enable-sql-reader-syntax)
|
m@46
|
96 (defun timebase-for-event (event)
|
m@51
|
97 (car (clsql:select [timebase] :from [mtp-dataset]
|
m@46
|
98 :where [= [dataset-id]
|
m@46
|
99 (dataset-id event)]
|
m@46
|
100 :flatp t
|
m@46
|
101 :field-names nil)))
|
m@46
|
102 #.(clsql:restore-sql-reader-syntax-state)
|
m@46
|
103
|
m@69
|
104 (defmethod get-applicable-time-signatures ((e mtp-event) c)
|
m@69
|
105 (declare (ignore c))
|
m@69
|
106 (let ((pulses (%mtp-pulses e))
|
m@69
|
107 (barlength (%mtp-barlength e))
|
m@69
|
108 (timebase (timebase-for-event e)))
|
m@69
|
109 (list
|
m@69
|
110 (amuse:make-basic-time-signature pulses
|
m@69
|
111 (/ timebase (/ barlength pulses))
|
m@69
|
112 (timepoint e)
|
m@69
|
113 (duration e)))))
|
m@69
|
114
|
m@46
|
115 (defmethod time-signatures ((c mtp-composition))
|
m@46
|
116 (let ((results nil)
|
m@46
|
117 (interval 0)
|
m@46
|
118 (current nil))
|
m@46
|
119 (sequence:dosequence (event c)
|
m@70
|
120 (let ((ts (car (get-applicable-time-signatures event c))))
|
m@46
|
121 (when (and (%mtp-barlength event)
|
m@46
|
122 (%mtp-pulses event)
|
m@46
|
123 (or (null current)
|
m@46
|
124 (not (time-signature-equal ts current))))
|
m@46
|
125 (unless (null current)
|
m@46
|
126 (setf (duration current) interval)
|
m@46
|
127 (push current results))
|
m@46
|
128 (setf interval 0
|
m@46
|
129 current ts)))
|
m@46
|
130 (incf interval (%mtp-deltast event))
|
m@46
|
131 (incf interval (duration event)))
|
m@46
|
132 (when current
|
m@46
|
133 (setf (duration current) interval)
|
m@46
|
134 (push current results))
|
m@46
|
135 (nreverse results)))
|
m@46
|
136
|
m@46
|
137 ;;; Constituents from compositions: key-signatures
|
m@46
|
138
|
m@69
|
139 (defmethod get-applicable-key-signatures ((e mtp-event) c)
|
m@69
|
140 (declare (ignore c))
|
m@69
|
141 (let* ((sharps (%mtp-keysig e))
|
m@68
|
142 (mode (%mtp-mode e))
|
m@69
|
143 (midi-mode (and mode (if (= mode 0) 0 1))))
|
m@69
|
144 (list (amuse:make-midi-key-signature sharps midi-mode
|
m@69
|
145 (timepoint e)
|
m@69
|
146 (duration e)))))
|
m@46
|
147
|
m@68
|
148 (defmethod key-signatures ((c mtp-composition))
|
m@46
|
149 (let ((results nil)
|
m@46
|
150 (interval 0)
|
m@46
|
151 (current nil))
|
m@46
|
152 (sequence:dosequence (event c)
|
m@69
|
153 (let ((ks (car (get-applicable-key-signatures event c))))
|
m@46
|
154 (when (and (%mtp-keysig event)
|
m@46
|
155 (%mtp-mode event)
|
m@46
|
156 (or (null current)
|
m@46
|
157 (not (key-signature-equal ks current))))
|
m@46
|
158 (unless (null current)
|
m@46
|
159 (setf (duration current) interval)
|
m@46
|
160 (push current results))
|
m@46
|
161 (setf interval 0
|
m@46
|
162 current ks)))
|
m@46
|
163 (incf interval (%mtp-deltast event))
|
m@46
|
164 (incf interval (duration event)))
|
m@46
|
165 (when current
|
m@46
|
166 (setf (duration current) interval)
|
m@46
|
167 (push current results))
|
m@46
|
168 (nreverse results)))
|
m@46
|
169
|
m@46
|
170 ;;; Constituents from compositions: tempi
|
m@46
|
171
|
m@69
|
172 (defmethod get-applicable-tempi ((e mtp-event) c)
|
m@69
|
173 (declare (ignore c))
|
m@71
|
174 (list (amuse:make-tempo (%mtp-tempo e)
|
m@71
|
175 (timepoint e)
|
m@71
|
176 (duration e))))
|
m@69
|
177
|
m@46
|
178 (defmethod tempi ((c mtp-composition))
|
m@46
|
179 (let ((results nil)
|
m@46
|
180 (interval 0)
|
m@46
|
181 (current nil))
|
m@46
|
182 (sequence:dosequence (event c)
|
m@46
|
183 (when (and (%mtp-tempo event)
|
m@46
|
184 (or (null current)
|
m@46
|
185 (not (= (bpm current) (%mtp-tempo event)))))
|
m@46
|
186 (unless (null current)
|
m@46
|
187 (setf (duration current) interval)
|
m@46
|
188 (push current results))
|
m@69
|
189 (let ((new (car (get-applicable-tempi event c))))
|
m@46
|
190 (setf interval 0
|
m@46
|
191 current new)))
|
m@46
|
192 (incf interval (%mtp-deltast event))
|
m@46
|
193 (incf interval (duration event)))
|
m@46
|
194 (when current
|
m@46
|
195 (setf (duration current) interval)
|
m@46
|
196 (push current results))
|
m@46
|
197 (nreverse results)))
|
m@46
|
198
|
m@46
|
199
|
m@46
|
200 ;;; Events: Pitch
|
m@46
|
201
|
m@46
|
202 (defmethod chromatic-pitch ((e mtp-event))
|
m@46
|
203 (make-chromatic-pitch (%mtp-cpitch e)))
|
m@46
|
204
|
m@46
|
205 (defmethod midi-pitch-number ((e mtp-event))
|
m@46
|
206 (%mtp-cpitch e))
|
m@46
|
207
|
m@82
|
208 (defmethod meredith-morphetic-pitch-number ((e mtp-event))
|
m@82
|
209 ;; MIPS morphetic pitch is relative to An0 while mpitch is relative to Cn2
|
m@82
|
210 (- (%mtp-mpitch e) 12))
|
m@82
|
211
|
m@82
|
212 (defmethod mips-pitch ((e mtp-event))
|
m@82
|
213 (make-mips-pitch (meredith-chromatic-pitch-number e)
|
m@82
|
214 (meredith-morphetic-pitch-number e)))
|
m@82
|
215
|
m@46
|
216 (defmethod diatonic-pitch ((e mtp-event))
|
m@82
|
217 (diatonic-pitch (mips-pitch e)))
|
m@82
|
218
|
m@82
|
219 #.(clsql:locally-enable-sql-reader-syntax)
|
m@82
|
220 (defmethod middle-c ((e mtp-event))
|
m@82
|
221 (let ((cpitch (car (clsql:select [midc] :from [dataset]
|
m@82
|
222 :where [= [dataset-id] (dataset-id e)]
|
m@82
|
223 :flatp t :field-names nil))))
|
m@82
|
224 (make-mtp-event :cpitch cpitch :mpitch (* (/ cpitch 12) 7))))
|
m@82
|
225 #.(clsql:restore-sql-reader-syntax-state)
|
m@79
|
226
|
m@79
|
227 ;;; Phrase boundaries
|
m@79
|
228
|
m@79
|
229 (defmethod boundary-strength ((s mtp-before-segmenter) (e mtp-event) c)
|
m@79
|
230 (declare (ignore s c))
|
m@79
|
231 (let ((phrase (%mtp-phrase e)))
|
m@79
|
232 (case phrase
|
m@79
|
233 (-1 1)
|
m@79
|
234 (t 0))))
|
m@79
|
235
|
m@79
|
236 (defmethod boundary-strength ((s mtp-after-segmenter) (e mtp-event) c)
|
m@79
|
237 (declare (ignore s c))
|
m@79
|
238 (let ((phrase (%mtp-phrase e)))
|
m@79
|
239 (case phrase
|
m@79
|
240 (1 1)
|
m@79
|
241 (t 0))))
|