1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
;;; chess-sound.el --- Announce chess moves with pre-recorded sound files -*- lexical-binding: t; -*-
;; Copyright (C) 2002, 2008, 2014 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw@gnu.org>
;; Maintainer: Mario Lang <mlang@delysid.org>
;; Keywords: games
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This is very similar to chess-announce, except it uses specific
;; .WAV files instead of text-to-speech.
;;; Code:
(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 'function
: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)
(defcustom chess-sound-moves nil
"If non-nil, plays move.wav for each move."
:type 'boolean
:group 'chess-sound)
(defcustom chess-sound-voiced-moves nil
"If non-nil, announces opponent's algebraic move."
:type 'boolean
:group 'chess-sound)
(defsubst chess-sound (file)
(ignore-errors
(let ((wav (expand-file-name (concat file ".wav") chess-sound-directory)))
(if (file-readable-p wav)
(funcall chess-sound-play-function wav)
(ding)))))
(defsubst chess-sound-play (file)
(apply 'call-process chess-sound-program
nil nil nil (append chess-sound-args (list file))))
(defun chess-sound-handler (game event &rest _args)
(cond
((eq event 'initialize)
(and (file-directory-p chess-sound-directory)
(file-readable-p (expand-file-name "move.wav"
chess-sound-directory))
(or (eq chess-sound-play-function 'play-sound-file)
(and chess-sound-program
(file-executable-p chess-sound-program)))))
((eq event 'move)
(let* ((ply (chess-game-ply game (1- (chess-game-index game))))
(pos (chess-ply-pos ply)))
(if (and chess-sound-voiced-moves
(not (eq (chess-game-data game 'my-color)
(chess-pos-side-to-move pos))))
(let* ((source (chess-ply-source ply))
(target (chess-ply-target ply))
(s-piece (and source (chess-pos-piece pos source)))
(t-piece (and target (chess-pos-piece pos target)))
(which (chess-ply-keyword ply :which)))
(cond
((chess-ply-keyword ply :castle)
(chess-sound "O-O"))
((chess-ply-keyword ply :long-castle)
(chess-sound "O-O-O"))
((and s-piece t-piece (= t-piece ? ) target)
(if which
(chess-sound (char-to-string which)))
(chess-sound (format "%c_" (downcase s-piece)))
(chess-sound (chess-index-to-coord target)))
((and s-piece t-piece target)
(if which
(chess-sound (char-to-string which)))
(chess-sound (format "%c_" (downcase s-piece)))
(chess-sound "x_")
(chess-sound (format "%c_" (downcase t-piece)))
(chess-sound (chess-index-to-coord target))))
(if (chess-ply-keyword ply :promote)
(chess-sound
(format "%c_" (downcase
(chess-ply-keyword ply :promote)))))
(if (chess-ply-keyword ply :en-passant)
(chess-sound "enpassant"))
(if (chess-ply-keyword ply :check)
(chess-sound "+_"))
(if (chess-ply-keyword ply :checkmate)
(chess-sound "#_"))
(if (chess-ply-keyword ply :stalemate)
(chess-sound "smate")))
(if chess-sound-moves (chess-sound "move")))))))
(provide 'chess-sound)
;;; chess-sound.el ends here
|