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

|#