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@46
|
7 (defmethod get-composition ((identifier mtp-composition-identifier))
|
m@46
|
8 (let* ((dataset-id (dataset-id identifier))
|
m@46
|
9 (composition-id (composition-id identifier))
|
m@46
|
10 (where-clause [and [= [dataset-id] dataset-id]
|
m@46
|
11 [= [composition-id] composition-id]])
|
m@46
|
12 (description
|
m@46
|
13 (car (clsql:select [description] :from [composition]
|
m@46
|
14 :where where-clause :flatp t :field-names nil)))
|
m@46
|
15 (event-count
|
m@46
|
16 (1+
|
m@46
|
17 (car
|
m@46
|
18 (clsql:select [max [event-id]] :from [event]
|
m@46
|
19 :where where-clause :flatp t :field-names nil))))
|
m@46
|
20 (events nil))
|
m@46
|
21 (dotimes (event-id event-count)
|
m@46
|
22 (push (get-event dataset-id composition-id event-id) events))
|
m@46
|
23 (let* ((interval (+ (timepoint (car events)) (duration (car events))))
|
m@46
|
24 (composition
|
m@46
|
25 (make-mtp-composition :dataset-id dataset-id
|
m@46
|
26 :composition-id composition-id
|
m@46
|
27 :description description
|
m@46
|
28 :time 0
|
m@46
|
29 :interval interval)))
|
m@46
|
30 (sequence:adjust-sequence composition (length events)
|
m@46
|
31 :initial-contents (nreverse events))
|
m@46
|
32 composition)))
|
m@46
|
33
|
m@46
|
34 (defun get-event (dataset-id composition-id event-id)
|
m@46
|
35 (let* ((attributes
|
m@46
|
36 (list (list 'amuse::time [onset])
|
m@46
|
37 (list 'amuse::interval [dur])
|
m@46
|
38 (list 'deltast [deltast])
|
m@46
|
39 (list 'cpitch [cpitch])
|
m@46
|
40 (list 'mpitch [mpitch])
|
m@46
|
41 (list 'accidental [accidental])
|
m@46
|
42 (list 'keysig [keysig])
|
m@46
|
43 (list 'mode [mode])
|
m@46
|
44 (list 'barlength [barlength])
|
m@46
|
45 (list 'pulses [pulses])
|
m@46
|
46 (list 'phrase [phrase])
|
m@46
|
47 (list 'tempo [tempo])
|
m@46
|
48 (list 'dyn [dyn])
|
m@46
|
49 (list 'voice [voice])))
|
m@46
|
50 (mtp-event
|
m@46
|
51 (make-mtp-event :dataset-id dataset-id
|
m@46
|
52 :composition-id composition-id
|
m@46
|
53 :event-id event-id)))
|
m@46
|
54 (dolist (a attributes mtp-event)
|
m@46
|
55 (let ((value
|
m@46
|
56 (clsql:select (cadr a) :from [event]
|
m@46
|
57 :where [and [= [dataset-id] dataset-id]
|
m@46
|
58 [= [composition-id] composition-id]
|
m@46
|
59 [= [event-id] event-id]]
|
m@46
|
60 :flatp t
|
m@46
|
61 :field-names nil)))
|
m@46
|
62 (setf (slot-value mtp-event (car a)) (car value))))))
|
m@46
|
63
|
m@46
|
64 #.(clsql:restore-sql-reader-syntax-state)
|
m@46
|
65
|
m@46
|
66
|
m@46
|
67 ;;; Constituents from compositions: time-signatures
|
m@46
|
68
|
m@46
|
69 (defgeneric time-signature-equal (ts1 ts2))
|
m@46
|
70 (defmethod time-signature-equal ((ts1 basic-time-signature)
|
m@46
|
71 (ts2 basic-time-signature))
|
m@46
|
72 (let ((n1 (time-signature-numerator ts1))
|
m@46
|
73 (n2 (time-signature-numerator ts2))
|
m@46
|
74 (d1 (time-signature-denominator ts1))
|
m@46
|
75 (d2 (time-signature-denominator ts2)))
|
m@46
|
76 (and n1 n2 (= n1 n2)
|
m@46
|
77 d1 d2 (= d1 d2))))
|
m@46
|
78
|
m@46
|
79 (defgeneric time-signature (event))
|
m@46
|
80 (defmethod time-signature ((e mtp-event))
|
m@46
|
81 (let ((pulses (%mtp-pulses e))
|
m@46
|
82 (barlength (%mtp-barlength e))
|
m@46
|
83 (timebase (timebase-for-event e)))
|
m@46
|
84 (make-basic-time-signature pulses (/ timebase (/ barlength pulses))
|
m@46
|
85 (timepoint e) nil)))
|
m@46
|
86
|
m@46
|
87 #.(clsql:locally-enable-sql-reader-syntax)
|
m@46
|
88 (defun timebase-for-event (event)
|
m@46
|
89 (car (clsql:select [timebase] :from [dataset]
|
m@46
|
90 :where [= [dataset-id]
|
m@46
|
91 (dataset-id event)]
|
m@46
|
92 :flatp t
|
m@46
|
93 :field-names nil)))
|
m@46
|
94 #.(clsql:restore-sql-reader-syntax-state)
|
m@46
|
95
|
m@46
|
96 (defmethod time-signatures ((c mtp-composition))
|
m@46
|
97 (let ((results nil)
|
m@46
|
98 (interval 0)
|
m@46
|
99 (current nil))
|
m@46
|
100 (sequence:dosequence (event c)
|
m@46
|
101 (let ((ts (time-signature event)))
|
m@46
|
102 (when (and (%mtp-barlength event)
|
m@46
|
103 (%mtp-pulses event)
|
m@46
|
104 (or (null current)
|
m@46
|
105 (not (time-signature-equal ts current))))
|
m@46
|
106 (unless (null current)
|
m@46
|
107 (setf (duration current) interval)
|
m@46
|
108 (push current results))
|
m@46
|
109 (setf interval 0
|
m@46
|
110 current ts)))
|
m@46
|
111 (incf interval (%mtp-deltast event))
|
m@46
|
112 (incf interval (duration event)))
|
m@46
|
113 (when current
|
m@46
|
114 (setf (duration current) interval)
|
m@46
|
115 (push current results))
|
m@46
|
116 (nreverse results)))
|
m@46
|
117
|
m@46
|
118 ;;; Constituents from compositions: key-signatures
|
m@46
|
119
|
m@46
|
120 (defgeneric key-signature-equal (ks1 ks2))
|
m@46
|
121 (defmethod key-signature-equal ((ks1 midi-key-signature)
|
m@46
|
122 (ks2 midi-key-signature))
|
m@46
|
123 (let ((s1 (key-signature-sharps ks1))
|
m@46
|
124 (s2 (key-signature-sharps ks2))
|
m@46
|
125 (m1 (key-signature-mode ks1))
|
m@46
|
126 (m2 (key-signature-mode ks2)))
|
m@46
|
127 (and s1 s2 (= s1 s2)
|
m@46
|
128 m1 m2 (= m1 m2))))
|
m@46
|
129
|
m@46
|
130 (defgeneric key-signature (event))
|
m@46
|
131 (defmethod key-signature ((e mtp-event))
|
m@46
|
132 (let ((keysig (%mtp-keysig e))
|
m@46
|
133 (mode (%mtp-mode e))
|
m@46
|
134 (onset (timepoint e)))
|
m@46
|
135 (amuse:make-midi-key-signature keysig mode onset nil)))
|
m@46
|
136
|
m@46
|
137 (defmethod key-signatures ((c mtp-composition))
|
m@46
|
138 (let ((results nil)
|
m@46
|
139 (interval 0)
|
m@46
|
140 (current nil))
|
m@46
|
141 (sequence:dosequence (event c)
|
m@46
|
142 (let ((ks (key-signature event)))
|
m@46
|
143 (when (and (%mtp-keysig event)
|
m@46
|
144 (%mtp-mode event)
|
m@46
|
145 (or (null current)
|
m@46
|
146 (not (key-signature-equal ks current))))
|
m@46
|
147 (unless (null current)
|
m@46
|
148 (setf (duration current) interval)
|
m@46
|
149 (push current results))
|
m@46
|
150 (setf interval 0
|
m@46
|
151 current ks)))
|
m@46
|
152 (incf interval (%mtp-deltast event))
|
m@46
|
153 (incf interval (duration event)))
|
m@46
|
154 (when current
|
m@46
|
155 (setf (duration current) interval)
|
m@46
|
156 (push current results))
|
m@46
|
157 (nreverse results)))
|
m@46
|
158
|
m@46
|
159 ;;; Constituents from compositions: tempi
|
m@46
|
160
|
m@46
|
161 (defmethod tempi ((c mtp-composition))
|
m@46
|
162 (let ((results nil)
|
m@46
|
163 (interval 0)
|
m@46
|
164 (current nil))
|
m@46
|
165 (sequence:dosequence (event c)
|
m@46
|
166 (when (and (%mtp-tempo event)
|
m@46
|
167 (or (null current)
|
m@46
|
168 (not (= (bpm current) (%mtp-tempo event)))))
|
m@46
|
169 (unless (null current)
|
m@46
|
170 (setf (duration current) interval)
|
m@46
|
171 (push current results))
|
m@46
|
172 (let ((new (amuse:make-tempo (%mtp-tempo event)
|
m@46
|
173 (timepoint event)
|
m@46
|
174 nil)))
|
m@46
|
175 (setf interval 0
|
m@46
|
176 current new)))
|
m@46
|
177 (incf interval (%mtp-deltast event))
|
m@46
|
178 (incf interval (duration event)))
|
m@46
|
179 (when current
|
m@46
|
180 (setf (duration current) interval)
|
m@46
|
181 (push current results))
|
m@46
|
182 (nreverse results)))
|
m@46
|
183
|
m@46
|
184
|
m@46
|
185 ;;; Events: Pitch
|
m@46
|
186
|
m@46
|
187 (defmethod chromatic-pitch ((e mtp-event))
|
m@46
|
188 (make-chromatic-pitch (%mtp-cpitch e)))
|
m@46
|
189
|
m@46
|
190 (defmethod midi-pitch-number ((e mtp-event))
|
m@46
|
191 (%mtp-cpitch e))
|
m@46
|
192
|
m@46
|
193 (defmethod diatonic-pitch ((e mtp-event))
|
m@46
|
194 ;; (make-diatonic-pitch (event-mpitch e)
|
m@46
|
195 ;; (event-accidental e)
|
m@46
|
196 ;; octave)
|
m@46
|
197 )
|