Mercurial > hg > amuse
changeset 158:49b418a68acb
Finally added mcsv-exporting file...
darcs-hash:20071211145641-f76cc-58fb06b2d2d58120c56d7c9f4629936eb327eace.gz
author | David Lewis <d.lewis@gold.ac.uk> |
---|---|
date | Tue, 11 Dec 2007 14:56:41 +0000 |
parents | f5f4bf8d74d7 |
children | d47c5d14ec9a |
files | utils/meltools.lisp |
diffstat | 1 files changed, 111 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils/meltools.lisp Tue Dec 11 14:56:41 2007 +0000 @@ -0,0 +1,111 @@ +;;; Tools for simile, melconv and melfeature + +(cl:in-package #:amuse-utils) + +;; Basic tools and variables for mcsv output + +(defgeneric get-timebase (constituent) + (:method (c) + (apply #'lcm + (nconc (map 'list #'(lambda (x) + (denominator + (timepoint x))) + c) + (map 'list #'(lambda (x) + (denominator + (timepoint (cut-off x)))) + c))))) + +(defparameter *default-field-list* + '(:onset :onsetics :takt :beat :ticks :pitch :durs :durtic :dur16)) + +(defparameter *mcsv-field-functions* + '((:onset mcsv-real-time-onset) + (:onsetics mcsv-tick-onset) + (:takt mcsv-bar-number) + (:beat mcsv-beat-in-bar) + (:ticks mcsv-ticks-in-beat) + (:pitch mcsv-pitch) + (:durs mcsv-seconds-duration) + (:durtic mcsv-ticks-duration) + (:dur16 mcsv-quarter-beat-duration))) + +;; method or function? +(defgeneric write-mcsv (filename constituent fieldlist ticks) + (:method (fn c fl ticks) + (with-open-file (file fn :direction :output :if-exists :supersede) + (let ((time-sig (car (get-applicable-time-signatures c c))) + (timebase (or ticks (get-timebase c))) + (fieldlist (or fl *default-field-list*))) + (format file "Signature: ~D/~D, Ticks per Beat: ~D~%" + (if time-sig + (time-signature-numerator time-sig) + 4) + (if time-sig + (time-signature-denominator time-sig) + 4) + timebase) + (dolist (field fieldlist (format file "~%")) + (format file "~D;" field)) + (write-mcsv-to-stream file c fieldlist timebase))))) + +(defun write-mcsv-to-stream (stream composition fieldlist ticks) + (sequence:dosequence (event composition) + (dolist (field fieldlist (format stream "~%")) + (format stream "~D;" (get-mcsv-data field event composition ticks))))) + +(defun get-mcsv-data (field event composition ticks) + (funcall (second (assoc field *mcsv-field-functions*)) + event composition ticks)) + +;; mcsv data functions + +(defun mcsv-real-time-onset (event composition ticks) + (declare (ignore ticks)) + (fraction-to-comma-string + (beats-to-seconds (onset event) composition))) + +(defun mcsv-tick-onset (event composition ticks) + (declare (ignore composition)) + (round (* ticks (timepoint event)))) + +(defun mcsv-bar-number (event composition ticks) + (declare (ignore ticks)) + (bar-number event composition)) + +(defun mcsv-beat-in-bar (event composition ticks) + ;; FIXME: broken if beat!= crotchet + (declare (ignore ticks)) + (1+ (floor (- (timepoint event) + (timepoint (bar-onset (bar-number event composition) + composition)))))) + +(defun mcsv-ticks-in-beat (event composition ticks) + ;; FIXME: broken if beat!= crotchet + (declare (ignore composition)) + (round (* ticks + (rem (timepoint event) 1)))) + +(defun mcsv-pitch (event composition ticks) + (declare (ignore composition ticks)) + (midi-pitch-number event)) + +(defun mcsv-seconds-duration (event composition ticks) + (declare (ignore ticks)) + (fraction-to-comma-string (beats-to-seconds event composition))) + +(defun mcsv-ticks-duration (event composition ticks) + (declare (ignore composition)) + (round (* ticks (duration event)))) + +(defun mcsv-quarter-beat-duration (event composition ticks) + (declare (ignore ticks composition)) + (round (* 4 (duration event)))) + +(defun fraction-to-comma-string (number) + (multiple-value-bind (int rem) + (floor number) + (concatenate 'string + (princ-to-string int) + "," + (princ-to-string (floor (* 10000 rem))))))