Event recording in CM
Rick Taube
hkt@cmp-nxt1.music.uiuc.edu
Wed, 13 Nov 1996 12:21:34 -0600
Here is the implementatin of a new copy-stream as i mentioned in my last
message -- 5 methods and one patch so the open command does not insist on
files. An example of recording a performance is at the end of the message.
hope this helps!
-hkt
(in-package :cm)
(defclass copy-stream (event-stream)
((container :initform nil)
(previous :initform nil)))
(defmethod print-object ((object copy-stream) stream)
(format stream "#<Copy: to ~:(~A~)>" (slot-value object 'name)))
(defmethod open-event-stream ((stream copy-stream)
&optional (mode ':default) &rest args)
(declare (ignore args))
(unless (or (eq mode ':default) (eq mode ':initialize))
;; make sure the container is a thread.
(unless (typep (slot-value stream 'container) 'thread)
(let ((name (intern (string-upcase (slot-value stream 'name)))))
(setf (slot-value stream 'container)
(make-object `(thread ,name)))))
;; mark stream as 'opened'.
(setf (slot-value stream 'stream)
(slot-value stream 'container)))
stream)
(defmethod initialize-stream-for-processing :after ((stream copy-stream))
;; throw out current contents unless user explicitly freezes it
(unless (frozenp (slot-value stream 'container))
(remove-all-objects (slot-value stream 'stream)))
(setf (slot-value stream 'previous) nil))
(defmethod write-event ((object element) (stream copy-stream))
(let ((copy (copy-object object)))
(add-object copy (slot-value stream 'stream))
(setf (slot-value stream 'previous) copy)))
(defmethod write-event :before ((object rhythmic-element)
(stream copy-stream))
;; reset rhythm to reflect the time line of the performance.
(let ((last (slot-value stream 'previous)))
(when last
(setf (slot-value last 'rhythm)
(- (slot-value object 'time)
(slot-value last 'time))))))
;;;
;;; patch main open-event-stream to allow object names.
(defmethod open-event-stream ((object string)
&optional (mode ':default) &rest args)
(let ((stream (find-stream object)))
(if stream
(apply #'open-event-stream stream mode args)
(multiple-value-bind (syntax class)
(pathname-syntax object)
(declare (ignore syntax))
(unless class
;; allow user to specify object names for copy streams
;(error "Can't determine stream class for ~S." object)
(setf class (find-class 'copy-stream))
)
(apply #'open-event-stream class mode 'name object args)))))
#|
(algorithm hoo midi-note (length 5 rhythm 1 duration 1.5)
(setf note (item (notes c5 d e f g))))
(algorithm doo midi-note (length 15 rhythm .333 duration .5)
(setf note (item (notes c4 d e f g))))
Stella [Top-Level]: open recording
Stream: #<Copy: to Recording>
Stella [Top-Level]: mix hoo,doo 0
Stella [Top-Level]: tlist recording 0
Recording
0.00 1. #<MIDI-NOTE | C5| 0| 1.500| 64| 0|>
2. #<MIDI-NOTE | C4| 0.333| 0.500| 64| 0|>
0.33 3. #<MIDI-NOTE | D4| 0.333| 0.500| 64| 0|>
0.67 4. #<MIDI-NOTE | E4| 0.333| 0.500| 64| 0|>
1.00 5. #<MIDI-NOTE | F4| 0.001| 0.500| 64| 0|>
1.00 6. #<MIDI-NOTE | D5| 0.332| 1.500| 64| 0|>
1.33 7. #<MIDI-NOTE | G4| 0.333| 0.500| 64| 0|>
1.67 8. #<MIDI-NOTE | C4| 0.333| 0.500| 64| 0|>
2.00 9. #<MIDI-NOTE | D4| 0.002| 0.500| 64| 0|>
2.00 10. #<MIDI-NOTE | E5| 0.331| 1.500| 64| 0|>
2.33 11. #<MIDI-NOTE | E4| 0.333| 0.500| 64| 0|>
2.66 12. #<MIDI-NOTE | F4| 0.333| 0.500| 64| 0|>
3.00 13. #<MIDI-NOTE | G4| 0.003| 0.500| 64| 0|>
3.00 14. #<MIDI-NOTE | F5| 0.330| 1.500| 64| 0|>
3.33 15. #<MIDI-NOTE | C4| 0.333| 0.500| 64| 0|>
3.66 16. #<MIDI-NOTE | D4| 0.333| 0.500| 64| 0|>
4.00 17. #<MIDI-NOTE | E4| 0.004| 0.500| 64| 0|>
4.00 18. #<MIDI-NOTE | G5| 0.329| 1.500| 64| 0|>
4.33 19. #<MIDI-NOTE | F4| 0.333| 0.500| 64| 0|>
4.66 20. #<MIDI-NOTE | G4| 0.333| 0.500| 64| 0|>
Stella [Top-Level]: open midi
Stella [Top-Level]: mix recording
|#