comparison utils/utils.lisp @ 41:90abdf9adb60

monodising and some n-gram utilities darcs-hash:20070614140028-f76cc-9bdeba6db4097e425b1fee4f58a3327eeb486685.gz
author David Lewis <d.lewis@gold.ac.uk>
date Thu, 14 Jun 2007 15:00:28 +0100
parents 262aa7a3d500
children e3d86a0f25b3
comparison
equal deleted inserted replaced
40:5bec705db9d6 41:90abdf9adb60
183 (apply substitution-function (list (elt s1 x) (elt s2 y))) 183 (apply substitution-function (list (elt s1 x) (elt s2 y)))
184 (if (apply substitution-test (list (elt s1 x) (elt s2 y))) 184 (if (apply substitution-test (list (elt s1 x) (elt s2 y)))
185 0 185 0
186 substitution-cost))))))) 186 substitution-cost)))))))
187 (aref d (1- height) (1- width)))) 187 (aref d (1- height) (1- width))))
188
189 ;;;;;;;;;;;;;;;;;;;;;;
190 ;;
191 ;; More experimental (from amuse-geerdes)
192 ;;
193 ;; Monody functions
194
195 (defun monodificate (composition)
196 (let ((events-bags) (latest-cut-off))
197 ;; - Filter out very short notes (<50ms)
198 ;; - If there are notes with the same onset time or a large
199 ;; proportion (e.g. >25%) of the notes in the segment have
200 ;; overlapping durations (of >75%), do for every simultaneous or
201 ;; overlapping pair of notes
202 ;; -- if one note is louder than the other note (e.g. quieter note
203 ;; <75% of louder one) select it as melody note
204 ;; -- else select note with higher pitch
205 ;; [FIXME: I'm ignoring overlaps for the time being]
206 ;; - For non-simultaneous notes with little overlap, set note ends
207 ;; to beginning of of onset of next (overlapping) note.
208
209 ;; STEP 1:
210 ;; `Filter out very short notes (<50ms)' and find `segments' for
211 ;; further filtering.
212 (sequence::dosequence (event composition)
213 (when (> (beats-to-seconds event composition)
214 1/20)
215 (if (or (not latest-cut-off)
216 (time> (onset event) latest-cut-off))
217 (push (list event) events-bags)
218 (push event (car events-bags)))
219 (when (or (not latest-cut-off)
220 (time> (cut-off event) latest-cut-off))
221 (setf latest-cut-off (cut-off event)))))
222 ;; Now check each segment for overlaps and
223 ;; simultanaieties. N.B. this is a reverse list of reversed
224 ;; lists.
225 (let ((adjusted-bags))
226 (dolist (events-bag events-bags)
227 (setf events-bag (reverse events-bag))
228 (let ((polyphonic-p (check-events-bag-for-polyphony events-bag)))
229 (cond
230 (polyphonic-p
231 (push (resolve-polyphony events-bag composition) adjusted-bags))
232 (t
233 (if (cdr events-bag)
234 (push (adjust-durations events-bag) adjusted-bags)
235 (push events-bag adjusted-bags))))))
236 (apply #'nconc adjusted-bags))))
237
238 (defun resolve-polyphony (event-list composition)
239 (do ((i 0 (1+ i)))
240 ((>= i (length event-list)) event-list)
241 (let ((event (nth i event-list)))
242 (do ((j (1+ i) (1+ j)))
243 ((or (>= j (length event-list))
244 (time>= (onset (nth j event-list))
245 (cut-off event))))
246 (let* ((event-2 (nth j event-list))
247 (inter-onset (time- (onset event-2) (onset event))))
248 (cond
249 ((and inter-onset
250 (< (* 2 (duration inter-onset))
251 (duration event))
252 (< (* 2 (duration inter-onset))
253 (duration event-2))
254 (< (beats-to-seconds inter-onset composition)
255 1/8))
256 ;; This is clearly polyphony
257 (cond
258 ((significantly-louderp event-2 event)
259 ;; Take event-2
260 (setf event-list (remove event event-list))
261 (decf i)
262 (return))
263 ((significantly-louderp event event-2)
264 ;; Take event
265 (setf event-list (remove event-2 event-list))
266 (decf j))
267 ((pitch> event event-2)
268 ;; Take event
269 (setf event-list (remove event-2 event-list))
270 (decf j))
271 (t
272 ;; Take event-2
273 (setf event-list (remove event event-list))
274 (decf i)
275 (return))))
276 (t
277 (cond
278 ((substantially-louderp event-2 event)
279 ;; Take event-2
280 (setf event-list (remove event event-list))
281 (decf i)
282 (return))
283 ((substantially-louderp event event-2)
284 ;; Take event
285 (setf event-list (remove event-2 event-list))
286 (decf j))
287 (t
288 ;; Take both
289 (let ((event-overlap (period-intersection event event-2)))
290 (when event-overlap
291 (setf (duration event)
292 (duration (time- event-overlap event))))))))))))))
293
294 (defgeneric significantly-louderp (event1 event2)
295 ;; noticably louder
296 (:method (e1 e2) (declare (ignore e1 e2)) nil))
297
298 (defgeneric substantially-louderp (event1 event2)
299 ;; much louder
300 (:method (e1 e2) (declare (ignore e1 e2)) nil))
301
302 (defun adjust-durations (events-list)
303 (do* ((old-list events-list (cdr old-list))
304 (event (first old-list) (first old-list))
305 (event-2 (second old-list) (second old-list)))
306 ((not event-2) events-list)
307 (let ((event-overlap (period-intersection event event-2)))
308 (when event-overlap
309 (setf (duration event)
310 (duration (time- event-overlap event)))))))
311
312 (defun check-events-bag-for-polyphony (events-bag)
313 (let ((overlaps (make-array (length events-bag) :initial-element nil)))
314 (when (= (length events-bag) 1)
315 ;; obviously no overlaps
316 (return-from check-events-bag-for-polyphony nil))
317 (unless (= (length (remove-duplicates events-bag :test #'time=))
318 (length events-bag))
319 ;; Duplicated onsets
320 (return-from check-events-bag-for-polyphony 'T))
321 ;; Now for the main bit
322 (do* ((events events-bag (cdr events))
323 (i 0 (1+ i))
324 (event (car events) (car events)))
325 ((null (cdr events)))
326 (unless (and (aref overlaps i)
327 (= (aref overlaps i) 1))
328 ;; Would mean we already have a maximal value
329 ;; and don't need any more checks
330 (do* ((events-2 (cdr events) (cdr events-2))
331 (j (1+ i) (1+ j))
332 (event-2 (car events-2) (car events-2)))
333 ((null events-2))
334 (when (time>= (onset event-2) (cut-off event))
335 ;; So no more overlaps
336 (return))
337 (let ((shorter (if (duration< event event-2)
338 i
339 j))
340 (overlap (/ (duration (period-intersection event event-2))
341 (min (duration event) (duration event-2)))))
342 ;; only look at pairings for the shorter note. This can
343 ;; have odd side effects, but means we never
344 ;; under-represent an overlap (I think)
345 (when (or (not (aref overlaps shorter))
346 (>= overlap (aref overlaps shorter)))
347 (setf (aref overlaps shorter) overlap)
348 (when (and (= shorter i)
349 (= overlap 1))
350 ;; Maximum value - we can stop
351 (return)))))))
352 (let ((total 0) (overs 0))
353 (loop for i from 0 to (1- (length events-bag))
354 do (when (aref overlaps i)
355 (incf total)
356 (when (>= (aref overlaps i) 3/4)
357 (incf overs))))
358 (if (and (> total 0)
359 (>= (/ overs total)
360 1/4))
361 'T
362 'nil))))