;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; This is very similar to chess-announce, except it uses specific ;; .WAV files instead of text-to-speech. ;; ;; $Revision$ (require 'chess-game) (defgroup chess-sound nil "Code to play specific sounds when announcing chess moves." :group 'chess) (defcustom chess-sound-directory (expand-file-name "sounds" (file-name-directory (or load-file-name buffer-file-name))) "The directory where chess sounds can be found." :type 'directory :group 'chess-sound) (defcustom chess-sound-play-function (if (fboundp 'play-sound-file) 'play-sound-file 'chess-sound-play) "Non-nil if chess-sound should play sounds ." :type 'file :group 'chess-sound) (defcustom chess-sound-program (or (executable-find "esdplay") (executable-find "play")) "Program used to play sounds, if `play-sound-file' does not exist." :type 'file :group 'chess-sound) (defcustom chess-sound-args nil "Additional args to pass to `chess-sound-program', before the .WAV file." :type '(repeat string) :group 'chess-sound) (defun chess-sound-for-game (game) "Announce the opponent's moves in GAME." (if (and (file-directory-p chess-sound-directory) (file-exists-p (expand-file-name "tap.wav" chess-sound-directory))) (chess-game-add-hook game 'chess-sound-event-handler))) (defun chess-sound (ch) (let ((file (cond ((stringp ch) (format "%s.wav" ch)) ((memq ch '(?\# ?\+ ?k ?q ?b ?n ?r ?p ?x)) (format "%c_.wav" ch)) (t (format "%s.wav" (chess-index-to-coord ch)))))) (funcall chess-sound-play-function (expand-file-name file chess-sound-directory)))) (defun chess-sound-play (file) (apply 'call-process chess-sound-program nil nil nil chess-sound-args)) (defun chess-sound-event-handler (game ignore event &rest args) "This display module presents a standard chessboard. See `chess-display-type' for the different kinds of displays." (cond ((memq event '(move game-over)) (let* ((ply (chess-game-ply game (1- (chess-game-index game)))) (pos (chess-ply-pos ply))) (if (eq (chess-game-data game 'my-color) (chess-pos-side-to-move pos)) (chess-sound "tap") (let* ((source (chess-ply-source ply)) (target (chess-ply-target ply)) (s-piece (chess-pos-piece pos source)) (t-piece (chess-pos-piece pos target)) text) (cond ((memq :castle changes) (chess-sound "O-O")) ((memq :long-castle changes) (chess-sound "O-O-O")) ((= t-piece ? ) (chess-sound (downcase s-piece)) (chess-sound target)) (t (chess-sound (downcase s-piece)) (chess-sound ?x) (chess-sound (downcase t-piece)) (chess-sound target))) (if (memq :check changes) (chess-sound ?+)) (if (memq :checkmate changes) (chess-sound ?#)) (if (memq :stalemate changes) (chess-sound "smate"))))) nil))) (provide 'chess-sound) ;;; chess-sound.el ends here