Text-to-Speech in Emacs

旧巷老猫 提交于 2019-12-03 00:34:22

Festival for Windows is available here. I can't guarantee that festival.el will work with these binaries. I do have experience working with these binaries, though, so if you have problems getting them to work outside of Emacs, I may be able to help.

I don't think you will have control over playback speed with festival, though I could be mistaken. As far as retaining control over it, I'd say your best bet is to program it so that it is only sending small portions at a time to festival. Otherwise, there really isn't any way to prevent it from reading until done.

Basically, I don't think that there is anything out there that would meet your minimum requirements without some work.

Edit: after looking back over your requirements, I'd say the best approach would be to hack festival.el to send a sentence at a time to Festival. Then you can program a keystroke that will kill it, so that it will only finish the current sentence. At the same time, your script could highlight the sentence that is currently being sent to Festival.

I have a simple solution based on the Python pyttsx module. This starts a python script as an emacs process and sends it strings to be read out.

(defvar tts nil "text to speech process")

(defun tts-up ()
  (interactive)
  (and (not (null tts))
       (eq (process-status tts) 'run)))

(defun tts-start ()
  (interactive)
  (if (not (tts-up))
      (setq tts
            (start-process "tts-python"
                           "*tts-python*"
                           "python" "speak.py"))))

(defun tts-end ()
  (interactive)
  (delete-process tts)
  (setq tts nil))

(defun tts-say (text)
  (interactive)
  (tts-start)
  (process-send-string tts (concat text "\n")))

The python file speak.py:

import pyttsx

engine = pyttsx.init()

def say(data):
    engine.say(data)
    engine.runAndWait()

while True:
    say(raw_input())
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!