Spaces:
Runtime error
Runtime error
;;; | |
;;; File: festival.el | |
;;; Emacs Lisp | |
;;; | |
;;; Alan W Black CSTR (awb .ed.ac.uk) June 1996 | |
;;; | |
;;; Provide an emacs mode for interfacing to the festival speech | |
;;; synthesizer system | |
;;; | |
;;; I've looked at many examples from the emacs Lisp directory | |
;;; copying relevant bits from here and there, so this can only | |
;;; reasonably inherit the GNU licence (GPL) | |
;;; | |
;;; Setup: | |
;;; In your .emacs add the following 2 lines to get a Say menu: | |
;;; | |
;;; (autoload 'say-minor-mode "festival" "Menu for using Festival." t) | |
;;; (say-minor-mode t) | |
;;; (setq auto-mode-alist | |
;;; (append '(("\\.festivalrc$" . scheme-mode)) auto-mode-alist)) | |
;;; | |
;;; The following gives you pretty colors in emacs-19 if you are into | |
;;; such things | |
;;; ;;; Some colors for scheme mode | |
;;; (hilit-set-mode-patterns | |
;;; '(scheme-mode) | |
;;; '( | |
;;; (";.*" nil comment) | |
;;; (hilit-string-find ?\\ string) | |
;;; ("^\\s *(def\\s +" "\\()\\|nil\\)" defun) | |
;;; ("^\\s *(defvar\\s +\\S +" nil decl) | |
;;; ("^\\s *(set\\s +\\S +" nil decl) | |
;;; ("^\\s *(defconst\\s +\\S +" nil define) | |
;;; ("^\\s *(\\(provide\\|require\\).*$" nil include) | |
;;; ("(\\(let\\*?\\|cond\\|if\\|or\\|and\\|map\\(car\\|concat\\)\\|prog[n1*]?\\|while\\|lambda\\|function\\|Parameter\\|set\\([qf]\\|car\\|cdr\\)?\\|nconc\\|eval-when-compile\\|condition-case\\|unwind-protect\\|catch\\|throw\\|error\\)[ \t\n]" 1 keyword))) | |
;;; | |
;;; | |
;;;-------------------------------------------------------------------- | |
;;; Copyright (C) Alan W Black 1996 | |
;;; This code is distributed in the hope that it will be useful, | |
;;; but WITHOUT ANY WARRANTY. No author or distributor accepts | |
;;; responsibility to anyone for the consequences of using this code | |
;;; or for whether it serves any particular purpose or works at all, | |
;;; unless explicitly stated in a written agreement. | |
;;; | |
;;; Everyone is granted permission to copy, modify and redistribute | |
;;; this code, but only under the conditions described in the GNU | |
;;; Emacs General Public License. A copy of this license is | |
;;; distrubuted with GNU Emacs so you can know your rights and | |
;;; responsibilities. It should be in a file named COPYING. Among | |
;;; other things, the copyright notice and this notice must be | |
;;; preserved on all copies. | |
;;;-------------------------------------------------------------------- | |
;;; | |
(defvar festival-program-name "festival") | |
(defvar festival-process nil) | |
(defvar festival-tmp-file | |
(format "/tmp/festival-emacs-tmp-%s" (user-real-login-name)) | |
"Filename to save input for Festivial.") | |
(defun festival-fast () | |
(interactive) | |
(festival-send-command '(Parameter.set 'Duration.Stretch 0.8))) | |
(defun festival-slow () | |
(interactive) | |
(festival-send-command '(Parameter.set 'Duration.Stretch 1.2))) | |
(defun festival-ndur () | |
(interactive) | |
(festival-send-command '(Parameter.set 'Duration.Stretch 1.0))) | |
(defun festival-intro () | |
(interactive) | |
(festival-send-command '(intro))) | |
(defun festival-gsw () | |
(interactive) | |
(festival-send-command '(voice_gsw_diphone))) | |
(defun festival-rab () | |
(interactive) | |
(festival-send-command '(voice_rab_diphone))) | |
(defun festival-ked () | |
(interactive) | |
(festival-send-command '(voice_ked_diphone))) | |
(defun festival-kal () | |
(interactive) | |
(festival-send-command '(voice_kal_diphone))) | |
(defun festival-don () | |
(interactive) | |
(festival-send-command '(voice_don_diphone))) | |
(defun festival-welsh () | |
(interactive) | |
(festival-send-command '(voice_welsh_hl))) | |
(defun festival-spanish () | |
(interactive) | |
(festival-send-command '(voice_spanish_el))) | |
(defun festival-say-string (string) | |
"Send string to festival and have it said" | |
(interactive "sSay: ") | |
(festival-start-process) | |
(process-send-string festival-process | |
(concat "(SayText " (format "%S" string) ") | |
"))) | |
(defun festival-send-command (cmd) | |
"Send command to festival" | |
(interactive "px") | |
(festival-start-process) | |
(process-send-string festival-process (format "%S | |
" cmd))) | |
(defun festival-process-status () | |
(interactive) | |
(if festival-process | |
(message (format "Festival process status: %s" | |
(process-status festival-process))) | |
(message (format "Festival process status: NONE")))) | |
(defun festival-start-process () | |
"Check status of process and start it if necessary" | |
(interactive ) | |
(let ((process-connection-type t)) | |
(if (and festival-process | |
(eq (process-status festival-process) 'run)) | |
't | |
;;(festival-kill-festival t) | |
(message "Starting new synthesizer process...") | |
(sit-for 0) | |
(setq festival-process | |
(start-process "festival" (get-buffer-create "*festival*") | |
festival-program-name))) | |
)) | |
(defun festival-kill-process () | |
"Kill festival sub-process" | |
(interactive) | |
(if festival-process | |
(kill-process festival-process)) | |
(setq festival-process nil) | |
(message "Festival process killed")) | |
(defun festival-send-string (string) | |
"Send given string to fesitval process." | |
(interactive) | |
(festival-start-process) | |
(process-send-string festival-process string)) | |
(defun festival-say-region (reg-start reg-end) | |
"Send given region to festival for saying. This saves the region | |
as a file in /tmp and then tells festival to say that file. The | |
major mode is *not* passed as text mode name to Festival." | |
(interactive "r") | |
(write-region reg-start reg-end festival-tmp-file) | |
(festival-send-command (list 'tts festival-tmp-file nil))) | |
(defun festival-say-buffer () | |
"Send given region to festival for saying. This saves the region | |
as a file in /tmp and then tells festival to say that file. The | |
major-mode is passed as a text mode to Festival." | |
(interactive) | |
(write-region (point-min) (point-max) festival-tmp-file) | |
;; Because there may by sgml-like sub-files mentioned | |
;; ensure festival tracks the buffer's default-directory | |
(festival-send-command (list 'cd (expand-file-name default-directory))) | |
(if (equal "-mode" (substring (format "%S" major-mode) -5 nil)) | |
(if (equal "sgml" (substring (format "%S" major-mode) 0 -5)) | |
(festival-send-command | |
(list 'tts festival-tmp-file "sable")) | |
(festival-send-command | |
(list 'tts festival-tmp-file | |
(substring (format "%S" major-mode) 0 -5)))) | |
(festival-send-command (list 'tts festival-tmp-file nil)))) | |
;; | |
;; say-minor-mode provides a menu offering various speech synthesis commands | |
;; | |
(defvar say-minor-mode nil) | |
(defun say-minor-mode (arg) | |
"Toggle say minor mode. | |
With arg, turn say-minor-mode on iff arg is positive." | |
(interactive "P") | |
(setq say-minor-mode | |
(if (if (null arg) (not say-minor-mode) | |
(> (prefix-numeric-value arg) 0)) | |
t)) | |
(force-mode-line-update)) | |
(setq say-params-menu (make-sparse-keymap "Pitch/Duration")) | |
(fset 'say-params-menu (symbol-value 'say-params-menu)) | |
(define-key say-params-menu [say-fast] '("Fast" . festival-fast)) | |
(define-key say-params-menu [say-slow] '("Slow" . festival-slow)) | |
(define-key say-params-menu [say-ndur] '("Normal Dur" . festival-ndur)) | |
(setq say-lang-menu (make-sparse-keymap "Select language")) | |
(fset 'say-lang-menu (symbol-value 'say-lang-menu)) | |
(define-key say-lang-menu [say-lang-spain1] '("Spanish el" . festival-spanish)) | |
(define-key say-lang-menu [say-lang-welsh1] '("Welsh hl" . festival-welsh)) | |
(define-key say-lang-menu [say-lang-eng5] '("English gsw" . festival-gsw)) | |
(define-key say-lang-menu [say-lang-eng4] '("English don" . festival-don)) | |
(define-key say-lang-menu [say-lang-eng3] '("English rab" . festival-rab)) | |
(define-key say-lang-menu [say-lang-eng2] '("English ked" . festival-ked)) | |
(define-key say-lang-menu [say-lang-eng1] '("English kal" . festival-kal)) | |
;(define-key say-params-menu [say-set-dur-stretch] | |
; '("Set Duration Stretch" . festival-set-dur-stretch)) | |
;(define-key say-params-menu [say-high] '("High" . festival-high)) | |
;(define-key say-params-menu [say-low] '("Low" . festival-low)) | |
;(define-key say-params-menu [say-npit] '("Normal Pitch" . festival-npit)) | |
;(define-key say-params-menu [say-set-pitch-stretch] | |
; '("Set Pitch Stretch" . festival-set-pitch-stretch)) | |
(setq say-minor-mode-map (make-sparse-keymap)) | |
(setq say-menu (make-sparse-keymap "SAY")) | |
(define-key say-minor-mode-map [menu-bar SAY] (cons "Say" say-menu)) | |
(define-key say-minor-mode-map [menu-bar SAY festival-intro] '("Festival Intro" . festival-intro)) | |
(define-key say-minor-mode-map [menu-bar SAY festival-process-status] '("Festival status" . festival-process-status)) | |
(define-key say-minor-mode-map [menu-bar SAY festival-kill-process] '("Kill Festival" . festival-kill-process)) | |
(define-key say-minor-mode-map [menu-bar SAY festival-start-process] '("(Re)start Festival" . festival-start-process)) | |
;;(define-key say-menu [separator-process] '("--")) | |
;;(define-key say-menu [params] '("Pitch/Durations" . say-params-menu)) | |
(define-key say-menu [separator-buffers] '("--")) | |
(define-key say-menu [festival-send-command] '("Festival eval command" . festival-send-command)) | |
(define-key say-menu [say-lang-menu] '("Select language" . say-lang-menu)) | |
(define-key say-menu [festival-say-buffer] '("Say buffer" . festival-say-buffer)) | |
(define-key say-menu [festival-say-region] '("Say region" . festival-say-region)) | |
(setq minor-mode-map-alist | |
(cons | |
(cons 'say-minor-mode say-minor-mode-map) | |
minor-mode-map-alist)) | |
(or (assq 'say-minor-mode minor-mode-alist) | |
(setq minor-mode-alist | |
(cons '(say-minor-mode "") minor-mode-alist))) | |
;;; | |
;;; A FESTIVAL inferior mode (copied from prolog.el) | |
;;; | |
(defvar inferior-festival-mode-map nil) | |
(defun inferior-festival-mode () | |
"Major mode for interacting with an inferior FESTIVAL process. | |
The following commands are available: | |
\\{inferior-festival-mode-map} | |
Entry to this mode calls the value of `festival-mode-hook' with no arguments, | |
if that value is non-nil. Likewise with the value of `comint-mode-hook'. | |
`festival-mode-hook' is called after `comint-mode-hook'. | |
You can send text to the inferior FESTIVAL from other buffers | |
using the commands `send-region', `send-string' | |
Return at end of buffer sends line as input. | |
Return not at end copies rest of line to end and sends it. | |
\\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing. | |
\\[comint-interrupt-subjob] interrupts the shell or its current subjob if any. | |
\\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal." | |
(interactive) | |
(require 'comint) | |
(comint-mode) | |
(setq major-mode 'inferior-festival-mode | |
mode-name "Inferior FESTIVAL" | |
comint-prompt-regexp "^festival> ") | |
(if inferior-festival-mode-map nil | |
(setq inferior-festival-mode-map (copy-keymap comint-mode-map)) | |
(festival-mode-commands inferior-festival-mode-map)) | |
(use-local-map inferior-festivalr-mode-map) | |
(run-hooks 'festival-mode-hook)) | |
;;;###autoload | |
(defun run-festival () | |
"Run an inferior FESTIVAL process, input and output via buffer *festival*." | |
(interactive) | |
(require 'comint) | |
(switch-to-buffer (make-comint "festival" festival-program-name)) | |
(inferior-festival-mode)) | |
(provide 'festival) | |