Subject: eci.el
From: Mario Lang (mlang_AT_delysid.org)
Date: Tue Oct 08 2002 - 21:19:23 EEST
Hello.
Given the recent talk of switching to socket/tcp based controlling completely,
I've attempted to implement eci.el.
The example sort of works, I need to tweak the output accept
code a bit, but the overall thing works quite nicely.
Comments and suggestions are very welcome.
Try it by invoking M-x eci-example RET
;;; eci.el --- Implementing the ECI in Emacs-Lisp.
;; Written by Mario Lang 2002 <mlang_AT_delysid.org>
;; This is only a pretest version. It can use alot of improvements,
;; but the example works.
(defvar eci-program "ecasound"
"*Program to invoke when doing `eci-init'.")
(defvar eci-buffer "*eci-ecasound*"
"Buffer name to use for ecasound process buffers.")
(defun eci-init ()
(save-current-buffer
(set-buffer (get-buffer-create eci-buffer))
(start-process "ecasound" (current-buffer) eci-program "-c" "-D")
(current-buffer)))
(defun eci-interactive-startup ()
"Used to interactively startup a eci session.
This will mostlyy be used to testing sessions."
(interactive)
(switch-to-buffer (eci-init)))
(defun eci-command (command &optional buffer-or-process)
"Send a ECI command to BUFFER-OR-PROCESS or if that is nil, to the current
buffers process."
(interactive "sECI Command: ")
(let ((proc (cond ((processp buffer-or-process) buffer-or-process)
((bufferp buffer-or-process) (get-buffer-process buffer-or-process))
(t (get-buffer-process (current-buffer))))))
(with-current-buffer (process-buffer proc)
(save-excursion
(goto-char (process-mark proc))
(insert-before-markers (format "%s\n" command))
(process-send-string proc (format "%s\n" command))
(let ((here (point)) res)
(when (accept-process-output proc 2)
(setq res (buffer-substring here (point-max)))
; This is a ugly hack which prevents getting out of sync
(while (accept-process-output proc 0 50))
res))))))
(defun eci-cs-status (&optional buffer-or-process)
"Return ChainSetup status as a Lisp object."
(let ((chains (split-string (eci-command "cs-status" buffer-or-process)
"^Chainsetup " ))
(chainlist))
(if (string-match "[\\* Controller/Chainsetup status \\*]" (car chains))
(progn
(setq chains (cdr chains))
(mapc
(lambda (str)
(if (string-match "(\\([0-9]+\\)) \"\\([^\"\n]+\\)\".*\n\tFilename:\t\t\\([^\n]*\\)\n\tSetup:\t\t\tinputs \\([0-9]+\\) - outputs \\([0-9]+\\) - chains \\([0-9]+\\)\n\tBuffersize:\t\t\\([0-9]+\\)\n\tInternal sample rate:\t\\([0-9]+\\)\n\tDefault sformat:\t\\(.*\\)\n\tFlags:\t\t\t\\(.*\\)\n\tState:[\t ]+\\(.*\\)" str)
(setq
chainlist
(cons
(list
(string-to-number (match-string 1 str))
(match-string 2 str)
(list 'filename (match-string 3 str))
(list 'inputs (string-to-number (match-string 4 str)))
(list 'outputs (string-to-number (match-string 5 str)))
(list 'chains (string-to-number (match-string 6 str)))
(list 'buffersize (string-to-number (match-string 7 str)))
(list 'srate (string-to-number (match-string 8 str)))
(list 'sformat (match-string 9 str))
(list 'flags (match-string 10 str))
(list 'state (match-string 11 str))) chainlist))))
chains))
(error "Unknown return value"))
chainlist))
(defun eci-c-list (&optional buffer-or-process)
(split-string (eci-command "c-list") "[,\n]"))
(defun eci-cs-list (&optional buffer-or-process)
(split-string (eci-command "cs-list") "[,\n]"))
(defun eci-c-select (chain &optional buffer-or-process)
(interactive (list (completing-read "Chain: " (mapcar #'list
(eci-c-list)))))
(eci-command (format "c-select %s" chain)))
(defun eci-cs-select (chain &optional buffer-or-process)
(interactive (list (completing-read "Chainsetup: " (mapcar
#'list (eci-cs-list)))))
(eci-command (format "cs-select %s" chain)))
(defun eci-ai-add (filename)
(interactive "fInput filename: ")
(eci-command (format "ai-add %s" filename)))
(defun eci-ao-add (filename)
(interactive "fOutput filename: ")
(eci-command (format "ao-add %s" filename)))
(defun eci-engine-status (&optional buffer-or-process)
(car (split-string (eci-command "engine-status") "\n")))
(defun eci-get-position (&optional buffer-or-process)
(string-to-number (eci-command "get-position" buffer-or-process)))
(defun eci-copp-get (&optional buffer-or-process)
(string-to-number (eci-command "copp-get" buffer-or-process)))
(defun eci-example ()
"Implements the example given in the ECI documentation.
This nicely shows that we still have timing problem, but it already
looks quite good."
(interactive)
(save-current-buffer
(set-buffer (eci-init))
(display-buffer (current-buffer))
(sit-for 0)
(eci-command "cs-add play_chainsetup")
(eci-command "c-add 1st_chain")
(call-interactively #'eci-ai-add)
(eci-command "ao-add /dev/dsp")
(eci-command "cop-add -efl:100")
(eci-command "cop-select 1")
(eci-command "copp-select 1")
(eci-command "cs-connect")
(eci-command "start")
(while (and (string= (eci-engine-status) "running")
(< (eci-get-position) 15))
(sit-for 1)
(eci-command (format "copp-set %f" (+ (eci-copp-get) 500))))
(eci-command "stop")
(eci-command "cs-disconnect")
(message (concat "Chain operator status: "
(eci-command "cop-status")))))
-- CYa, Mario
This archive was generated by hypermail 2b28 : Tue Oct 08 2002 - 21:17:30 EEST