[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

[MD:4262] mw32cdplay.el(was: Sound support)



もはや格好の息抜きを提供しているMCIですが、^^;;;
ちょっといじって、mw32cdplay.elのstatus bufferを
major modeにしてみました。

## Meadow標準に加えようかな。^^;;;

from himi
--------------------------------------------------------------------------------
;; mw32cdplay

(require 'timer)

(defconst mw32-cdplayer-device-name "mw32cdplay")
(defconst mw32-cdplayer-buffer-name "*cdplayer*")
(defconst mw32-cdplayer-refresh-time 0.3)

;; [<status> <time> <track> <tot. time> <num. of tracks>]
(defvar mw32-cdplayer-current-status
  (make-vector 5 nil))
(defvar mw32-cdplayer-buffer nil)
(defvar mw32-cdplayer-timer nil)

(defvar mw32-cdplayer-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "P" 'mw32-cdplayer-play)
    (define-key map "S" 'mw32-cdplayer-stop)
    (define-key map "p" 'mw32-cdplayer-previous-track)
    (define-key map "n" 'mw32-cdplayer-next-track)
    (define-key map " " 'mw32-cdplayer-toggle)
    (define-key map "O" 'mw32-cdplayer-door-open)
    (define-key map "C" 'mw32-cdplayer-door-close)
    map))

(defsubst mw32-cdplayer-current-status ()
  (aref mw32-cdplayer-current-status 0))
(defsubst mw32-cdplayer-current-time ()
  (aref mw32-cdplayer-current-status 1))
(defsubst mw32-cdplayer-current-track ()
  (aref mw32-cdplayer-current-status 2))
(defsubst mw32-cdplayer-total-time ()
  (aref mw32-cdplayer-current-status 3))
(defsubst mw32-cdplayer-number-of-tracks ()
  (aref mw32-cdplayer-current-status 4))

(defun mw32-cdplayer-send (cmd &optional arg)
  (let ((result
	 (mw32-mci-send-string
	  (format "%s %s %s" cmd mw32-cdplayer-device-name (or arg "")))))
    (if (numberp result)
	(progn
	  (mw32-cdplayer-uninit)
	  (error "MCI error!:%d" result)))
    result))

(defun mw32-cdplayer-update-status ()
  (aset mw32-cdplayer-current-status 0
	(mw32-cdplayer-send "status" "mode"))
  (aset mw32-cdplayer-current-status 1
	(mw32-cdplayer-send "status" "position"))
  (aset mw32-cdplayer-current-status 2
	(mw32-cdplayer-send "status" "current track"))
  (aset mw32-cdplayer-current-status 3
	(mw32-cdplayer-send "status" "length"))
  (aset mw32-cdplayer-current-status 4
	(mw32-cdplayer-send "status" "number of tracks")))

(defun mw32-cdplayer-get-position (trk)
  (mw32-cdplayer-send "status" (format "position track %s" trk)))

(defsubst mw32-cdplayer-format-time (time)
  (if (string-match "\\([0-9]+\\):\\([0-9]+\\):[0-9]+" time)
      (concat (match-string 1 time) ":" (match-string 2 time))
    time))

(defun mw32-cdplayer-show-status (buf)
  (save-excursion
    (set-buffer buf)
    (let ((inhibit-read-only t))
      (erase-buffer)
      (insert "Meadow simple CD Player\n")
      (insert (format "   Status:%s\n"
		      (mw32-cdplayer-current-status)))
      (insert (format "   Track:%s/%s\n"
		      (mw32-cdplayer-current-track)
		      (mw32-cdplayer-number-of-tracks)))
      (insert (format "   Time:%s/%s\n"
		      (mw32-cdplayer-format-time
		       (mw32-cdplayer-current-time))
		      (mw32-cdplayer-format-time
		       (mw32-cdplayer-total-time)))))))

(defun mw32-cdplayer-init ()
  (let ((st (mw32-mci-send-string
	     (format "open cdaudio alias %s"
		     mw32-cdplayer-device-name))))
    (if (numberp st)
	(if (= st 291)
	    (error "Other program may open CD device!")
	  (if (/= st 289)
	      (error "MCI error:%d" st))))
    (mw32-cdplayer-update-status)
    (if (not (bufferp mw32-cdplayer-buffer))
	(setq mw32-cdplayer-buffer
	      (get-buffer-create mw32-cdplayer-buffer-name)))
    (mw32-cdplayer-show-status
     mw32-cdplayer-buffer)
    (if (null mw32-cdplayer-timer)
	(setq mw32-cdplayer-timer
	      (timer-create)))
    (timer-set-function
     mw32-cdplayer-timer
     (function mw32-cdplayer-timer-handler))
    (timer-set-time mw32-cdplayer-timer
		    (current-time)
		    mw32-cdplayer-refresh-time)
    (timer-activate mw32-cdplayer-timer)))

(defun mw32-cdplayer-timer-handler ()
  (if (bufferp mw32-cdplayer-buffer)
      (progn
	(mw32-cdplayer-update-status)
	(mw32-cdplayer-show-status
	 mw32-cdplayer-buffer))))

(defun mw32-cdplayer-uninit
  (mw32-cdplayer-send "close")
  (if mw32-cdplayer-timer
      (cancel-timer mw32-cdplayer-timer)))

(defun mw32-cdplayer-play (&optional start end)
  (interactive)
  (let ((arg ""))
    (if start (setq arg (format "from %s" start)))
    (if end (setq arg (format "%s to %s" arg end)))
    (mw32-cdplayer-send "play" arg)))

(defun mw32-cdplayer-stop ()
  (interactive)
  (mw32-cdplayer-send "stop"))

(defun mw32-cdplayer-toggle ()
  (interactive)
  (mw32-cdplayer-update-status)
  (if (string= (mw32-cdplayer-current-status)
	       "playing")
      (mw32-cdplayer-stop)
    (mw32-cdplayer-play)))

(defun mw32-cdplayer-pause ()
  (interactive)
  (mw32-cdplayer-send "pause"))

(defun mw32-cdplayer-door-close ()
  (interactive)
  (mw32-cdplayer-send "set" "door open"))

(defun mw32-cdplayer-door-open ()
  (interactive)
  (mw32-cdplayer-send "set" "door close"))

(defun mw32-cdplayer-next-track ()
  (interactive)
  (mw32-cdplayer-update-status)
  (let ((trk
	 (string-to-number
	  (mw32-cdplayer-current-track)))
	pos)
    (setq pos (mw32-cdplayer-get-position
	       (1+ trk)))
    (mw32-cdplayer-play pos)))

(defun mw32-cdplayer-previous-track ()
  (interactive)
  (mw32-cdplayer-update-status)
  (let ((trk
	 (string-to-number
	  (mw32-cdplayer-current-track)))
	pos)
    (setq pos (mw32-cdplayer-get-position
	       (max 1 (1- trk))))
    (mw32-cdplayer-play pos)))

(defun mw32-cdplayer-mode ()
  (kill-all-local-variables)
  (buffer-disable-undo)
  (setq major-mode 'mw32-cdplayer-mode)
  (setq mode-name "CD Player")
  (use-local-map mw32-cdplayer-mode-map)
  (setq buffer-read-only t))

(defun mw32-cdplayer ()
  (interactive)
  (mw32-cdplayer-init)
  (switch-to-buffer
   mw32-cdplayer-buffer)
  (mw32-cdplayer-mode))

(provide 'mw32cdplay)