[CM] The Emacs saga continues: Music editing and programming

Mario Lang mlang@delysid.org
Thu, 04 Aug 2005 15:31:51 +0200


Hi.

IIRC, I already told of my plans to write a midi.el for Emacs Lisp to
handle MIDI file data in Emacs directly on LAD.  This idea has been recently
supersceeded by something much more powerful, the marriage of
CommonMusic and Emacs.  SLIME is the key, SLIME makes it possible!

I've been recently learning CommonMusic again, and discovered that
it already can nicely handle MIDI file data (and much more).  So reimplementing
the wheel in yet another lisp dialect doesn't seem like a very
useful exercise.  What I can do, actually, is bring
Emacs and CM a little more together, using SLIME.  This effectively means
that now, I can control SC and CM from Emacs, very easily.
Its all a bit of puzzlework for now, but as soon as we/I worked
out some ways to make things stick more together, I think this is
going to be a very powerful combination.

;; Example Emacs Lisp code:

(require 'slime)

(defun cm-eval (form &optional callback)
  "Eval FORM in the CM package.  If CALLBACK is a function, pass result
to it as soon as evaluation is finished (async).  Otherwise, return
result."
  (setq form `(swank:interactive-eval ,(format "%S" form)))
  (if callback
      (slime-eval-async form `(lambda (arg) (funcall ,callback (read arg))) "CM")
    (read (slime-eval form "CM")))))

(defun cm-get-midi-notes (filename)
  "Return all notes in a midi file in sequencial order."
  ;; Not very useful in real world, just a demonstration
  (cm-eval
   `(note (nreverse (fold-objects 'cons
				  (events (import-events ,(expand-file-name filename)) (new seq))
				  ()
				  :slot 'keynum :class 'midi))))))

;(cm-get-midi-notes "~/music/Bach_Suite_no4_BWV1006a_Prelude.mid") =>
; (E2 E5 EF5 E5 B4 AF4 B4 E4 FS4 E4 EF4 E4 ...)
;(length (cm-get-midi-notes "~/music/Bach_Suite_no4_BWV1006a_Prelude.mid")) =>
; 1741

>From here on, it should be fairly trivial to integrate SC and CM since
both can be easily talked to from within Emacs programmatically.

One thing I'd like to attempt for instance is a tree-widget based browser
for CM objects.

Thoughts?  More code?  If you are interested in this, send private mail.

-- 
CYa,
  Mario