[CM] CM for live performance

andersvi@extern.uio.no andersvi@extern.uio.no
Tue, 12 Apr 2005 08:48:02 +0200


--=-=-=

>>> "IS" == Ian Smith-Heisters <heisters@0x09.com> writes:
IS> 
IS> Howdy all,
IS> I've been using Pure Data to do live performance for a few years, but
IS> I'm getting frustrated with its patch paradigm, and I think I could
IS> produce better stuff in a text based language. So I've started to look
IS> at SuperCollider, JSyn, and CM. CM is the most attractive to me because
IS> I love Lisp and it's open source, whereas JSyn doesn't seem to be OSS.

My 2 cents.

I think the midishare output class in CM schedules output in
realtime.

But CM has powerful tools for generating (and analyzing) patterns
and control structure at various levels.  A good use of CM in
realtime situations is running pd or supercollider or some other
realtime sound-engine together with CM.  And calling various
processes in CM at will to generate .qlist-files or similar for
pd or files with lists of instrument-calls for supercollider.

Heres a io-class for outputting to a .qlist-file (intended for
PD's qlist-object) together with an example fm-object in case you
want to try it.  Just load it in after booting cm.


--=-=-=
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=qlist-io.cl
Content-Description: qlist-io-class for cm

(progn
  (defclass qlist-stream
    (event-stream)
    ((header :initform nil :initarg :header :accessor
             qlist-stream-header)
     (userargs :accessor qlist-userargs :initform '()))
    #+metaclasses
    (:metaclass io-class))
  (defparameter <qlist-stream> (find-class 'qlist-stream))
  (finalize-class <qlist-stream>)
  (setf (io-class-file-types <qlist-stream>) '("*.qlist"))
  (setf (io-class-mime-type <qlist-stream>) "text/x-qlist-score")
  (values))

(defmethod io-handler-args? ((io qlist-stream)) io t)

(defmethod io-handler-args ((io qlist-stream)) (qlist-userargs io))

(defmethod set-io-handler-args!
           ((io qlist-stream) args)
           (setf (qlist-userargs io) args)
           (values))

(defmethod initialize-io
  ((io qlist-stream))
  (let ((header (qlist-stream-header io)))
    (cond
     ((consp header)
      (dolist (h header) (format (io-open io) "~a~%" h)))
     ((stringp header) (format (io-open io) "~a~%" header))
     ((not header) nil)
     (t (error "Bad .qlist file header: ~A" header)))))


;;And an example fm-object which is aimed at PD

(defobject pd-fm-ins ()                 
  ((ins :initform 'fm :accessor object-name)
   (time :accessor object-time)
   (dur :initform 1)
   (amplitude :initform .5)
   (keynum :initform 54)
   (index :initform 3.0))
  (:parameters time dur amplitude keynum index)
  )


(defmethod object->midi ((obj pd-fm-ins))
  (new midi :time (object-time obj)
       :duration (pd-fm-ins-dur obj)
       :keynum (pd-fm-ins-keynum obj)
       :amplitude (pd-fm-ins-amplitude obj)))

(defmethod write-event
  ((obj pd-fm-ins) (io qlist-stream) scoretime)
  (let ((fp (io-open io)))
    (format fp "dur ~A; key ~A; amp ~A; index ~A;~%~A "
            (floor (* 1000 (pd-fm-ins-dur obj)))
            (pd-fm-ins-keynum obj)
            (pd-fm-ins-amplitude obj)
            (pd-fm-ins-index obj)
            (floor (* 1000 (object-time obj))))
    (values)))





(defprocess test-pd-output (dur tempo)
  (let ((keys (new funcall :of #'(lambda () (ran :from 30 :below 80))))
        (rhys (new heap :of '(q e s s))))
    (process while (< (now) dur)
             for key = (next keys)
             for rhythm = (rhythm (next rhys) tempo)
             for amp = (ran :from 0.2 :below 1.0 :type :lp)
             output (new pd-fm-ins
                      :time (now)
                      :keynum key
                      :dur rhythm
                      :amplitude amp
                      :index 1.0)
             wait rhythm)))

;; (events (test-pd-output 10.0 120) "test.qlist")

--=-=-=


If you're in for a lisp-based realtime DSP tool to replace PD or
supercollider, take a look at Kjetil Matheussens new
rt-engine.scm for snd, available in the snd-7 distribution at
CCRMA.  The interface is all scheme, like clm and cm, and it
seems to run very efficiently.

IS> Does CM lend itself to live performance? Is it easy to build up GUIs for
IS> interaction/control? What do most people use it for? I've searched the
IS> web and haven't found too many examples of projects using CM; the
IS> impression I've developed is that it's used for research, but not too
IS> much for more everyday media. Is there any possibility of using CM along
IS> with another Lisp library to do real-time video manipulation?

This should be straight forward if you know of any such tool.
There used to be (is?) a vrml-output-class in cm.

-anders

--=-=-=--