comparison implementations/geerdes/constructors.lisp @ 88:8ea75cc8bc2c

Basic geerdes functionality moved to implementations/geerdes from separate package darcs-hash:20070720161242-f76cc-fd256cbbb81d8c418a6c7c45844264184c5ed932.gz
author David Lewis <d.lewis@gold.ac.uk>
date Fri, 20 Jul 2007 17:12:42 +0100
parents
children d041118612d4
comparison
equal deleted inserted replaced
87:19a263fb92d1 88:8ea75cc8bc2c
1 (cl:in-package #:amuse-geerdes)
2
3 (defgeneric %initialise-notes (composition))
4 (defmethod %initialise-notes ((composition geerdes-composition))
5 (let ((notes) (l 0) (last-time 0) (monody-notes)
6 (monody (make-instance 'geerdes-monody :file-id (file-id composition)))
7 (timebase (%midi-timebase composition)))
8 (dolist (row (%midi-events composition))
9 (let* ((note (if (pitched-row-p row)
10 (make-geerdes-pitched-event (%fast-pitch row)
11 (%fast-velocity row)
12 (%fast-patch row)
13 (%fast-channel row)
14 (%fast-track row)
15 (%fast-onset row timebase)
16 (%fast-duration row timebase)
17 (%fast-id row))
18 (make-geerdes-percussive-event (%fast-pitch row)
19 (%fast-velocity row)
20 (%fast-patch row)
21 (%fast-channel row)
22 (%fast-track row)
23 (%fast-onset row timebase)
24 (%fast-duration row timebase)
25 (%fast-id row)))))
26 (when (%fast-monodyp row)
27 (push note monody-notes))
28 (when (> (timepoint (cut-off note)) last-time)
29 (setf last-time (timepoint (cut-off note))))
30 (push note notes)
31 (incf l)))
32 (sequence:adjust-sequence composition l :initial-contents (reverse notes))
33 (setf (duration composition) last-time
34 (timepoint composition) 0)
35 (when monody-notes
36 (setf (%monody composition) (sequence:adjust-sequence monody (length monody-notes)
37 :initial-contents (reverse monody-notes))
38 (timepoint (%monody composition)) (timepoint (elt monody 0))
39 (duration (%monody composition)) (- (timepoint (cut-off (car monody-notes)))
40 (timepoint (elt monody 0)))))
41 composition))
42
43 (defgeneric %initialise-constituents (composition))
44 (defmethod %initialise-constituents ((composition geerdes-composition))
45 ;; FIXME: Should the duration of composition be affected by this? On
46 ;; the one hand, it makes no difference to the musical content, but
47 ;; on the other, it seems illogical to reach outside the period.
48 (let ((timebase (%midi-timebase composition))
49 (time-sigs)
50 (tempi)
51 (mystery 0))
52 (dolist (row (%midi-constituents composition))
53 (cond
54 ((%fast-tempo row)
55 (push (make-tempo
56 (microsecond-per-crotchet-to-bpm
57 (%fast-tempo row))
58 (%fast-onset row timebase)
59 (%fast-duration row timebase))
60 tempi))
61 ((%fast-numerator row)
62 (push (make-basic-time-signature
63 (%fast-numerator row)
64 (%fast-denominator row)
65 (%fast-onset row timebase)
66 (%fast-duration row timebase))
67 time-sigs))
68 (t (incf mystery))))
69 (setf (time-signatures composition) (reverse time-sigs)
70 (tempi composition) (reverse tempi))
71 (when (%monody composition)
72 (setf (time-signatures (%monody composition)) (time-signatures composition)
73 (tempi (%monody composition)) (tempi composition)))
74 (format t "There are ~D constituents not processed~%" mystery)
75 composition))
76
77 (defun %fast-track (row)
78 (first row))
79 (defun %fast-channel (row)
80 (second row))
81 (defun %fast-onset (row timebase)
82 (/ (third row) timebase))
83 (defun %fast-duration (row timebase)
84 (/ (fourth row) timebase))
85 (defun %fast-patch (event-row)
86 (fifth event-row))
87 (defun %fast-pitch (event-row)
88 (sixth event-row))
89 (defun %fast-velocity (event-row)
90 (seventh event-row))
91 (defun %fast-id (event-row)
92 (eighth event-row))
93 (defun %fast-monodyp (event-row)
94 (ninth event-row))
95
96 (defun %fast-tempo (tp-row)
97 (eighth tp-row))
98 (defun %fast-numerator (ts-row)
99 (ninth ts-row))
100 (defun %fast-denominator (ts-row)
101 (tenth ts-row))
102
103 (defun pitched-row-p (event-row)
104 (and (not (= (%fast-channel event-row) 10))
105 (< (%fast-patch event-row) 112)))
106
107 (defun make-geerdes-pitched-event (pitch-number velocity patch
108 channel track onset duration id)
109 (make-instance 'geerdes-pitched-event
110 :number pitch-number
111 :velocity velocity
112 :patch patch
113 :channel channel
114 :track track
115 :time onset
116 :interval duration
117 :id id))
118
119 (defun make-geerdes-percussive-event (pitch-number velocity patch
120 channel track onset duration id)
121 (make-instance 'geerdes-percussive-event
122 :sound pitch-number
123 :velocity velocity
124 :patch patch
125 :channel channel
126 :track track
127 :time onset
128 :interval duration
129 :id id))
130
131 (defgeneric copy-event (event))
132 (defmethod copy-event ((event geerdes-pitched-event))
133 (with-slots ((channel amuse-midi::channel)
134 (track amuse-midi::track)
135 (number amuse::number)
136 (time amuse::time)
137 (interval amuse::interval)
138 (velocity amuse-midi::velocity)
139 (patch amuse-midi::patch) id)
140 event
141 (make-instance 'geerdes-pitched-event
142 :channel channel
143 :track track
144 :number number
145 :time time
146 :interval interval
147 :velocity velocity
148 :patch patch
149 :id id)))
150 (defmethod copy-event ((event geerdes-percussive-event))
151 (with-slots ((channel amuse-midi::channel)
152 (track amuse-midi::track)
153 (time amuse::time)
154 (interval amuse::interval)
155 (velocity amuse-midi::velocity)
156 (patch amuse-midi::patch)
157 (sound amuse-midi::sound) id)
158 event
159 (make-instance 'geerdes-percussive-event
160 :channel channel
161 :track track
162 :time time
163 :interval interval
164 :velocity velocity
165 :patch patch
166 :sound sound
167 :id id)))
168
169 ;; We want any function that generates a sequence from a geerdes
170 ;; composition to preserve all slot values:
171 (defmethod sequence:make-sequence-like :around ((o geerdes-composition)
172 length
173 &key (initial-element nil iep)
174 (initial-contents nil icp))
175 (declare (ignore iep icp length initial-element initial-contents))
176 (let ((result (call-next-method)))
177 (setf (%db-entry result) (%db-entry o))
178 result))