A lightweight text-to-speech (TTS) package for Emacs on macOS that uses the Mac OS built-in say command.
- Reading aloud text to catch confusing wording. This is often useful during the later stages of editing.
- Reading aloud chunks of text while preoccupied with mundane chores like cleaning up your desk or office.
- greader Depends on the external program espeak.
- read-aloud.el This package can use the Mac
sayprogram, but it also works on other operating systems. - piper-mode Mac only. Uses external dependencies.
- speechd-el This package is for the hearing impaired.
- say-what-im-doing This package verbalizes the commands that you issue in Emacs.
- ✅ Works with all Apple Silicon chips (M1, M2, M3, M4, etc.)
- ✅ No external dependencies - uses native macOS TTS capabilities
- ✅ Speak words, sentences, paragraphs, or selected regions
- ✅ Access to all high-quality macOS voices
- ✅ Easy to install and use
- ✅ Configurable keybindings
- ✅ Minimal and maintainable code
(straight-use-package
'(mac-say-tts :type git :host github :repo "MooersLab/mac-say-tts"))(use-package mac-say-tts
:straight (mac-say-tts :type git :host github :repo "MooersLab/mac-say-tts")
:config
(add-hook 'org-mode-hook 'mac-say-tts-mode)
(add-hook 'text-mode-hook 'mac-say-tts-mode))This is a new (Emacs 29+), built-in interactive function. You will be prompted for the GitHub repo URL.
- Download
mac-say-tts.elto your local machine - Add it to your load path and require it:
(add-to-list 'load-path "/path/to/directory/containing/mac-say-tts.el")
(require 'mac-say-tts)Fourteen tests are located in the file mac-say-tts-tests.el.
These tests use the ert package that is built into Emacs.
The test can be run from the command line.
I have to provide a full path to the Emacs executable to be sure that invoke the one that I want.
/Applications/Emacs30.1.app/Contents/MacOS/Emacs -batch -l ert -l mac-say-tts.el -l mac-say-tts-tests.el -f ert-run-tests-batch-and-exitAlternatively, you can add the test to your load path and require them as you would a package. Issue the following interactive command in the min buffer to run the tests:
M-x ert-run-tests-interactively RET t RET`
The package provides several ways to enable the text-to-speech functionality:
- Toggle in current buffer:
M-x mac-say-toggleorC-c t t - Enable in specific modes: Add to mode hooks
(add-hook 'org-mode-hook 'mac-say-tts-mode) (add-hook 'latex-hook 'mac-say-tts-mode) (add-hook 'markdown-hook 'mac-say-tts-mode)
- Enable globally:
M-x mac-say-enable-globally
When the mode is active, the following commands are available:
| Keybinding | Command | Description |
|---|---|---|
C-c M w |
mac-say-current-word |
Speak the word at point |
C-c M s |
mac-say-current-sentence |
Speak the sentence at point |
C-c M p |
mac-say-current-paragraph |
Speak the paragraph at point |
C-c M r |
mac-say-region |
Speak the selected region |
C-c M k |
mac-say-stop |
Stop all speech |
C-c M v |
mac-say-list-voices |
List all available voices for the Mac say program |
C-c M t |
mac-say-toggle |
Toggle the mode in current buffer |
C-c M V |
`mac-say-with-voice | Enables quick tests of different voices |
C-c M d |
mac-say-set-default-voice |
Reset the default voice |
|
You can customize the key bindings by modifying mac-say-tts-mode-map in your configuration:
(define-key mac-say-tts-mode-map (kbd "C-c s w") 'mac-say-current-word)To change the default voice (uses Samantha by default), you can use the C-c t d key binding or advice the mac-say function:
(defadvice mac-say (around use-alex activate)
"Use Alex voice by default."
(let ((voice (or (ad-get-arg 1) "Alex")))
(ad-set-arg 1 voice)
ad-do-it))- Requires macOS (works on all versions)
- Works with all Apple Silicon chips (M1, M2, M3, M4, etc.)
- Tested with Emacs 30, but should work with earlier versions
Contributions are welcome! Feel free to submit issues or pull requests.
This project is licensed under the GPL-3.0 License - see the LICENSE file for details.
- NIH: R01 CA242845
- NIH: R01 AI088011
- NIH: P30 CA225520 (PI: R. Mannel)
- NIH: P20 GM103640 and P30 GM145423 (PI: A. West)