Mercurial > hg > amuse
view implementations/geerdes/constructors.lisp @ 288:d1e5bbcc5ea4
Rationalise base and geerdes classes, constructors and methods.
Ignore-this: d9d4d88566a6d110844d91d4c70513cd
Towards a more standardised interface. Some of these changes (generalised
constructors and reader functions) are necessary for amuse-database-admin
functionality and some other CHARM-like things.
darcs-hash:20090716154406-16a00-8a9b4fb1fc1f5ba75af66a1bbd87e1bb68e02493.gz
author | j.forth <j.forth@gold.ac.uk> |
---|---|
date | Thu, 16 Jul 2009 16:44:06 +0100 |
parents | 4a03a1478c02 |
children | 7afb8cfdcdcf |
line wrap: on
line source
(cl:in-package #:amuse-geerdes) ;; Identifiers ;; FIXME: use standard constructor names? ;; FIXME: use standard composition-identifier? (defun g-id (cat-id) "Make a geerdes-identifier based on a catalogue id" (make-instance 'geerdes-identifier-cat-id :cat-id cat-id)) (defun g-id-file-id (file-id) "Make a geerdes-identifier based on the file id. This is used as the standard composition-id." (make-instance 'geerdes-identifier-file-id :file-id file-id)) (defun make-geerdes-event-identifier (event-id) (make-instance 'geerdes-event-identifier :event-id event-id)) ;; Events (defgeneric %initialise-notes (composition)) (defmethod %initialise-notes ((composition geerdes-composition)) (let ((notes) (l 0) (last-time 0) (monody-notes) (monody (make-instance 'geerdes-monody :file-id (file-id composition))) (timebase (midi-timebase composition))) (dolist (row (%midi-events composition)) (let* ((note (if (pitched-row-p row) (make-geerdes-pitched-event (%fast-pitch row) (%fast-velocity row) (%fast-patch row) (%fast-channel row) (%fast-track row) (%fast-onset row timebase) (%fast-duration row timebase) (%fast-id row)) (make-geerdes-percussive-event (%fast-pitch row) (%fast-velocity row) (%fast-patch row) (%fast-channel row) (%fast-track row) (%fast-onset row timebase) (%fast-duration row timebase) (%fast-id row))))) (when (%fast-monodyp row) (let ((monody-note (copy-event note))) (setf (duration monody-note) (%fast-monody-duration row timebase)) (push monody-note monody-notes))) (when (> (timepoint (cut-off note)) last-time) (setf last-time (timepoint (cut-off note)))) (push note notes) (incf l))) (sequence:adjust-sequence composition l :initial-contents (reverse notes)) (setf (duration composition) last-time (timepoint composition) 0) (when monody-notes (setf (%monody composition) (sequence:adjust-sequence monody (length monody-notes) :initial-contents (reverse monody-notes)) (timepoint (%monody composition)) (timepoint (elt monody 0)) (duration (%monody composition)) (- (timepoint (cut-off (car monody-notes))) (timepoint (elt monody 0))))) composition)) (defgeneric %initialise-constituents (composition)) (defmethod %initialise-constituents ((composition geerdes-composition)) ;; FIXME: Should the duration of composition be affected by this? On ;; the one hand, it makes no difference to the musical content, but ;; on the other, it seems illogical to reach outside the period. (let ((timebase (midi-timebase composition)) (time-sigs) (tempi) (mystery 0)) (dolist (row (%midi-constituents composition)) (cond ((%fast-tempo row) (push (make-standard-tempo-period (microsecond-per-crotchet-to-bpm (%fast-tempo row)) (%fast-onset row timebase) (%fast-duration row timebase)) tempi)) ((%fast-numerator row) (push (make-standard-time-signature-period (%fast-numerator row) (%fast-denominator row) (%fast-onset row timebase) (%fast-duration row timebase)) time-sigs)) (t (incf mystery)))) (setf (time-signatures composition) (reverse time-sigs) (tempi composition) (reverse tempi)) (when (%monody composition) (setf (time-signatures (%monody composition)) (time-signatures composition) (tempi (%monody composition)) (tempi composition))) (format t "There are ~D constituents not processed~%" mystery) composition)) (defun %fast-track (row) (first row)) (defun %fast-channel (row) (second row)) (defun %fast-onset (row timebase) (/ (third row) timebase)) (defun %fast-duration (row timebase) (/ (fourth row) timebase)) (defun %fast-patch (event-row) (fifth event-row)) (defun %fast-pitch (event-row) (sixth event-row)) (defun %fast-velocity (event-row) (seventh event-row)) (defun %fast-id (event-row) (eighth event-row)) (defun %fast-monodyp (event-row) (ninth event-row)) (defun %fast-monody-duration (event-row timebase) (/ (tenth event-row) timebase)) (defun %fast-tempo (tp-row) (eighth tp-row)) (defun %fast-numerator (ts-row) (ninth ts-row)) (defun %fast-denominator (ts-row) (tenth ts-row)) (defun pitched-row-p (event-row) (and (not (= (%fast-channel event-row) 10)) (< (%fast-patch event-row) 112))) (defun make-geerdes-pitched-event (pitch-number velocity patch channel track onset duration event-id) (make-instance 'geerdes-pitched-event :number pitch-number :velocity velocity :patch patch :channel channel :track track :time onset :interval duration :identifier (make-geerdes-event-identifier event-id))) (defun make-geerdes-percussive-event (pitch-number velocity patch channel track onset duration event-id) (make-instance 'geerdes-percussive-event :sound pitch-number :velocity velocity :patch patch :channel channel :track track :time onset :interval duration :identifier (make-geerdes-event-identifier event-id))) (defmethod copy-event ((event geerdes-pitched-event)) (with-slots ((channel amuse-midi::channel) (track amuse-midi::track) (number amuse::number) (time amuse::time) (interval amuse::interval) (velocity amuse-midi::velocity) (patch amuse-midi::patch) identifier) event (make-instance 'geerdes-pitched-event :channel channel :track track :number number :time time :interval interval :velocity velocity :patch patch :identifier identifier))) (defmethod copy-event ((event geerdes-percussive-event)) (with-slots ((channel amuse-midi::channel) (track amuse-midi::track) (time amuse::time) (interval amuse::interval) (velocity amuse-midi::velocity) (patch amuse-midi::patch) (sound amuse-midi::sound) identifier) event (make-instance 'geerdes-percussive-event :channel channel :track track :time time :interval interval :velocity velocity :patch patch :sound sound :identifier identifier))) ;; We want any function that generates a sequence from a geerdes ;; composition to preserve all slot values: #+nil (defmethod sequence:make-sequence-like :around ((o geerdes-composition) length &key (initial-element nil iep) (initial-contents nil icp)) (declare (ignore iep icp length initial-element initial-contents)) (let ((result (call-next-method))) (setf (%db-entry result) (%db-entry o)) result))