annotate utils/meltools.lisp @ 330:2fbff655ba47 tip

Removed cpitch-adj and cents SQL columns
author Jeremy Gow <jeremy.gow@gmail.com>
date Mon, 21 Jan 2013 11:08:11 +0000
parents 49b418a68acb
children
rev   line source
d@158 1 ;;; Tools for simile, melconv and melfeature
d@158 2
d@158 3 (cl:in-package #:amuse-utils)
d@158 4
d@158 5 ;; Basic tools and variables for mcsv output
d@158 6
d@158 7 (defgeneric get-timebase (constituent)
d@158 8 (:method (c)
d@158 9 (apply #'lcm
d@158 10 (nconc (map 'list #'(lambda (x)
d@158 11 (denominator
d@158 12 (timepoint x)))
d@158 13 c)
d@158 14 (map 'list #'(lambda (x)
d@158 15 (denominator
d@158 16 (timepoint (cut-off x))))
d@158 17 c)))))
d@158 18
d@158 19 (defparameter *default-field-list*
d@158 20 '(:onset :onsetics :takt :beat :ticks :pitch :durs :durtic :dur16))
d@158 21
d@158 22 (defparameter *mcsv-field-functions*
d@158 23 '((:onset mcsv-real-time-onset)
d@158 24 (:onsetics mcsv-tick-onset)
d@158 25 (:takt mcsv-bar-number)
d@158 26 (:beat mcsv-beat-in-bar)
d@158 27 (:ticks mcsv-ticks-in-beat)
d@158 28 (:pitch mcsv-pitch)
d@158 29 (:durs mcsv-seconds-duration)
d@158 30 (:durtic mcsv-ticks-duration)
d@158 31 (:dur16 mcsv-quarter-beat-duration)))
d@158 32
d@158 33 ;; method or function?
d@158 34 (defgeneric write-mcsv (filename constituent fieldlist ticks)
d@158 35 (:method (fn c fl ticks)
d@158 36 (with-open-file (file fn :direction :output :if-exists :supersede)
d@158 37 (let ((time-sig (car (get-applicable-time-signatures c c)))
d@158 38 (timebase (or ticks (get-timebase c)))
d@158 39 (fieldlist (or fl *default-field-list*)))
d@158 40 (format file "Signature: ~D/~D, Ticks per Beat: ~D~%"
d@158 41 (if time-sig
d@158 42 (time-signature-numerator time-sig)
d@158 43 4)
d@158 44 (if time-sig
d@158 45 (time-signature-denominator time-sig)
d@158 46 4)
d@158 47 timebase)
d@158 48 (dolist (field fieldlist (format file "~%"))
d@158 49 (format file "~D;" field))
d@158 50 (write-mcsv-to-stream file c fieldlist timebase)))))
d@158 51
d@158 52 (defun write-mcsv-to-stream (stream composition fieldlist ticks)
d@158 53 (sequence:dosequence (event composition)
d@158 54 (dolist (field fieldlist (format stream "~%"))
d@158 55 (format stream "~D;" (get-mcsv-data field event composition ticks)))))
d@158 56
d@158 57 (defun get-mcsv-data (field event composition ticks)
d@158 58 (funcall (second (assoc field *mcsv-field-functions*))
d@158 59 event composition ticks))
d@158 60
d@158 61 ;; mcsv data functions
d@158 62
d@158 63 (defun mcsv-real-time-onset (event composition ticks)
d@158 64 (declare (ignore ticks))
d@158 65 (fraction-to-comma-string
d@158 66 (beats-to-seconds (onset event) composition)))
d@158 67
d@158 68 (defun mcsv-tick-onset (event composition ticks)
d@158 69 (declare (ignore composition))
d@158 70 (round (* ticks (timepoint event))))
d@158 71
d@158 72 (defun mcsv-bar-number (event composition ticks)
d@158 73 (declare (ignore ticks))
d@158 74 (bar-number event composition))
d@158 75
d@158 76 (defun mcsv-beat-in-bar (event composition ticks)
d@158 77 ;; FIXME: broken if beat!= crotchet
d@158 78 (declare (ignore ticks))
d@158 79 (1+ (floor (- (timepoint event)
d@158 80 (timepoint (bar-onset (bar-number event composition)
d@158 81 composition))))))
d@158 82
d@158 83 (defun mcsv-ticks-in-beat (event composition ticks)
d@158 84 ;; FIXME: broken if beat!= crotchet
d@158 85 (declare (ignore composition))
d@158 86 (round (* ticks
d@158 87 (rem (timepoint event) 1))))
d@158 88
d@158 89 (defun mcsv-pitch (event composition ticks)
d@158 90 (declare (ignore composition ticks))
d@158 91 (midi-pitch-number event))
d@158 92
d@158 93 (defun mcsv-seconds-duration (event composition ticks)
d@158 94 (declare (ignore ticks))
d@158 95 (fraction-to-comma-string (beats-to-seconds event composition)))
d@158 96
d@158 97 (defun mcsv-ticks-duration (event composition ticks)
d@158 98 (declare (ignore composition))
d@158 99 (round (* ticks (duration event))))
d@158 100
d@158 101 (defun mcsv-quarter-beat-duration (event composition ticks)
d@158 102 (declare (ignore ticks composition))
d@158 103 (round (* 4 (duration event))))
d@158 104
d@158 105 (defun fraction-to-comma-string (number)
d@158 106 (multiple-value-bind (int rem)
d@158 107 (floor number)
d@158 108 (concatenate 'string
d@158 109 (princ-to-string int)
d@158 110 ","
d@158 111 (princ-to-string (floor (* 10000 rem))))))