Speak TTS
Give your agent the ability to speak to you real-time. Talk to your Claude! Local TTS, text-to-speech, voice synthesis, audio generation with voice cloning on Apple Silicon. Use for reading articles aloud, audiobook narration, or voice responses. Runs entirely on-device via MLX - private, no API keys.
- Skill ID
- emzod/speak/speak-tts
- Publisher
- emzod
- Repository
- speak
- Installs
- 0
- Files
- 111
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
emzod/speak/speak-ttsInstalls these files- .agentic/README.md
- .agentic/skill-optimization/OPTIMIZATION_REPORT.md
- .agentic/skill-optimization/SKILL_OPTIMIZED.md
- .agentic/skill-optimization/focus-group-runs/README.md
- .agentic/skill-optimization/focus-group-runs/round1a-v0-pdf-audiobook.md
- .agentic/skill-optimization/focus-group-runs/round1b-v0-podcast.md
- .agentic/skill-optimization/focus-group-runs/round2a-v1-pdf-audiobook.md
- .agentic/skill-optimization/focus-group-runs/round2b-v1-podcast.md
- .agentic/skill-optimization/focus-group-runs/round3-v2-news-article.md
- .agentic/skill-optimization/focus-group-runs/round4-v3-voice-clone.md
- .agentic/skill-optimization/focus-group-runs/round5a-v4-voice-clone.md
- .agentic/skill-optimization/focus-group-runs/round5b-v4-pdf-audiobook.md
- .agentic/skill-optimization/focus-group-runs/round5c-v5-combined.md
- .agentic/skill-optimization/iterations/SKILL_v0_original.md
- .agentic/skill-optimization/iterations/SKILL_v1.md
- .agentic/skill-optimization/iterations/SKILL_v2.md
- .agentic/skill-optimization/iterations/SKILL_v3.md
- .agentic/skill-optimization/iterations/SKILL_v4.md
- .agentic/skill-optimization/iterations/SKILL_v5_final.md
- .github/workflows/install-test.yml
- .github/workflows/test.yml
- .gitignore
- AGENTS.md
- CHANGELOG.md
- README.md
- SKILL.md
- assets/banner.jpeg
- bun.lock
- dev/Implementation_plan.md
- dev/README.md
- dev/all-docs.txt
- dev/bug-report-audio-cutoff.md
- dev/bug-report-streaming-hang.md
- dev/bug-report.md
- dev/fix-audio-cutoff-log.md
- dev/fix-streaming-audio-log.md
- dev/fix-streaming-log.md
- dev/issues/001-output-path-creates-directory.md
- dev/issues/002-no-progress-for-long-files.md
- dev/issues/003-silent-timeout-no-partial-output.md
- dev/issues/004-no-builtin-chunking.md
- dev/issues/005-no-resume-capability.md
- dev/issues/006-add-batch-mode.md
- dev/issues/007-add-concat-command.md
- dev/issues/008-add-duration-estimate.md
- dev/issues/009-distinguish-model-loading-vs-generating.md
- dev/issues/010-add-dry-run-flag.md
- dev/issues/README.md
- dev/log.md
- dev/merge_core.js
- dev/test-log.md
- dev/v1.1-plan.md
- docs/configuration.md
- docs/troubleshooting.md
- docs/usage.md
- package.json
- src/audio/device.ts
- src/audio/ring-buffer.ts
- src/audio/stream-player.ts
- src/bridge/binary-reader.ts
- src/bridge/client.ts
- src/bridge/daemon.ts
- src/bridge/protocol.ts
- src/core/batch.ts
- src/core/chunker.ts
- src/core/concatenate.ts
- src/core/config.ts
- src/core/estimate.ts
- src/core/health.ts
- src/core/killswitch.ts
- src/core/manifest.ts
- src/core/markdown.ts
- src/core/output.ts
- src/core/types.ts
- src/index.ts
- src/python/__pycache__/binary_protocol.cpython-310.pyc
- src/python/binary_protocol.py
- src/python/embedded.ts
- src/python/health.ts
- src/python/server.py
- src/python/setup.ts
- src/streaming/orchestrator.ts
- src/streaming/state-machine.ts
- src/types/speaker.d.ts
- src/ui/logger.ts
- src/ui/progress.ts
- src/utils/completions.ts
- test/e2e/cli-commands.test.ts
- test/e2e/streaming.test.ts
- test/e2e/tts-generation.test.ts
- test/fixtures/config/invalid-config.toml
- test/fixtures/config/valid-config.toml
- test/fixtures/markdown/code-blocks.md
- test/fixtures/markdown/complex.md
- test/fixtures/markdown/simple.md
- test/helpers/test-utils.ts
- test/integration/bridge/binary-reader.test.ts
- test/integration/bridge/client-daemon.test.ts
- test/integration/python/setup-health.test.ts
- test/integration/streaming/orchestrator.test.ts
- test/integration/streaming/stream-player.test.ts
- test/unit/audio/ring-buffer.test.ts
- test/unit/bridge/binary-protocol.test.ts
- test/unit/bridge/protocol.test.ts
- test/unit/core/config.test.ts
- test/unit/core/markdown.test.ts
- test/unit/core/output.test.ts
- test/unit/streaming/state-machine.test.ts
- test/unit/ui/progress.test.ts
- test/unit/utils/completions.test.ts
- tsconfig.json
What this skill tells the agent
speak - Talk to your Claude!
Give your agent the ability to speak to you real-time. Local text-to-speech, voice cloning, and audio generation on Apple Silicon. Give your agent the ability to speak to you real-time. Local TTS with voice cloning on Apple Silicon.
Prerequisites
| Requirement | Check | Install |
|---|---|---|
| Apple Silicon Mac | uname -m → arm64 | Intel not supported |
| macOS 12.0+ | sw_vers | - |
| sox | which sox | brew install sox |
| ffmpeg | which ffmpeg | brew install ffmpeg |
| poppler (PDF) | which pdftotext | brew install poppler |
Input Sources
| Source | Example | |
|---|---|---|
| Text file | speak article.txt | |
| Markdown | speak doc.md | |
| Direct string | speak "Hello" | |
| Clipboard | `pbpaste \ | speak` |
| Stdin | `cat file.txt \ | speak` |
Web Articles
lynx -dump -nolist "https://example.com/article" | speak --output article.wavConverting Formats
| Format | Convert Command |
|---|---|
pdftotext doc.pdf doc.txt | |
| DOCX | textutil -convert txt doc.docx |
| HTML | pandoc -f html -t plain doc.html > doc.txt |
Output Modes
| Goal | Command |
|---|---|
| Save for later | speak text.txt --output file.wav |
| Listen now (streaming) | speak text.txt --stream |
| Listen now (complete) | speak text.txt --play |
| Both | speak text.txt --stream --output file.wav |
Default Behavior
speak article.txt # → ~/Audio/speak/article.wav (no playback)
speak "Hello" # → ~/Audio/speak/speak_<timestamp>.wavDirectory Auto-Creation
| Directory | Auto-Created? |
|---|---|
~/Audio/speak/ | ✓ Yes |
~/.chatter/voices/ | ✗ No |
| Custom directories | ✗ No |
Always create custom directories first:
mkdir -p ~/.chatter/voices/
mkdir -p ~/Audio/custom/Voice Cloning
Voice cloning generates speech that matches your vocal characteristics (pitch, tone, cadence) from a short recording.
Quality Expectations
- Output captures general voice characteristics but is not a perfect replica
- Quality depends heavily on sample quality
- 15-25 seconds is optimal (10s minimum, 30s maximum)
Recording Your Voice
Using QuickTime:
- Open QuickTime Player → File → New Audio Recording
- Record 20 seconds of clear speech
- File → Export As → Audio Only (.m4a)
- Convert to WAV (see below)
Using sox (command line):
# -d = use default microphone
# Recording starts immediately and stops after 25 seconds
sox -d -r 24000 -c 1 ~/.chatter/voices/my_voice.wav trim 0 25Converting to Required Format
Voice samples MUST be: WAV, 24000 Hz, mono, 10-30 seconds.
# From MP3
ffmpeg -i voice.mp3 -ar 24000 -ac 1 voice.wav
# From M4A (QuickTime)
ffmpeg -i voice.m4a -ar 24000 -ac 1 voice.wav
# Trim to 25 seconds
ffmpeg -i long.wav -t 25 -ar 24000 -ac 1 trimmed.wav
# Check sample properties
ffprobe -i voice.wav 2>&1 | grep -E "Duration|Stream"
# Should show: Duration ~15-25s, 24000 Hz, monoUsing Your Voice
# Create directory
mkdir -p ~/.chatter/voices/
# Move sample
mv voice.wav ~/.chatter/voices/my_voice.wav
# Test
speak "Testing my voice" --voice ~/.chatter/voices/my_voice.wav --stream
# Use for content
speak notes.txt --voice ~/.chatter/voices/my_voice.wav --output presentation.wavPath requirements:
- ✓ Works:
~/.chatter/voices/my_voice.wav(tilde expanded by shell) - ✓ Works:
/Users/name/.chatter/voices/my_voice.wav - ✗ Fails:
my_voice.wav(relative path) - ✗ Fails:
./voices/my_voice.wav(relative path)
Voice Sample Tips
| Good Sample | Bad Sample |
|---|---|
| Quiet room | Background noise |
| Natural pace | Rushed or monotone |
| Clear diction | Mumbling |
| Varied content | Repetitive phrases |
Default Voice
When --voice is omitted, a built-in default voice is used:
speak "Hello world" --stream # Uses default voiceEmotion Tags
Tags produce audible effects (actual sounds), not spoken words:
speak "[sigh] Monday again." --stream
# Output: (sigh sound) "Monday again."| Tag | Effect |
|---|---|
[laugh] | Laughter |
[chuckle] | Light chuckle |
[sigh] | Sighing |
[gasp] | Gasping |
[groan] | Groaning |
[clear throat] | Throat clearing |
[cough] | Coughing |
[crying] | Crying |
[singing] | Sung speech |
NOT supported: [pause], [whisper] (ignored)
For pauses: Use punctuation: "Wait... let me think."
Batch Processing
mkdir -p ~/Audio/book/
speak ch01.txt ch02.txt ch03.txt --output-dir ~/Audio/book/
# Creates: ch01.wav, ch02.wav, ch03.wav
# With auto-chunking (for long files)
speak chapters/*.txt --output-dir ~/Audio/book/ --auto-chunk
# Skip completed files
speak chapters/*.txt --output-dir ~/Audio/book/ --skip-existingAuto-Chunk Behavior
When using --auto-chunk with batch processing:
- Each input file is chunked independently
- Chunks are generated and automatically concatenated per file
- Final output: one
.wavper input file (e.g.,ch01.wav) - Intermediate chunks deleted (unless
--keep-chunks)
You don't need to manually concatenate chunks — only concatenate final chapter files.
Concatenating Audio
# Explicit order (recommended)
speak concat ch01.wav ch02.wav ch03.wav --output book.wav
# Glob pattern (REQUIRES zero-padded filenames)
speak concat audiobook/*.wav --output book.wavZero-Padding Rules
Critical for correct concatenation order:
| Files | Correct | Wrong |
|---|---|---|
| 1-9 | 01, 02, ..., 09 | 1, 2, ..., 9 |
| 10-99 | 01, 02, ..., 99 | 1, 10, 2, ... |
| 100+ | 001, 002, ..., 999 | 1, 100, 2, ... |
Why: Shell glob expansion sorts alphabetically. 1, 10, 2 vs 01, 02, 10.
PDF to Audiobook (Complete Workflow)
Step 1: Find Chapter Boundaries
# Preview table of contents
pdftotext -f 1 -l 5 textbook.pdf toc.txt
cat toc.txt # Note chapter page numbers
# Or search for "Chapter" markers
pdftotext textbook.pdf - | grep -n "Chapter"Step 2: Extract Chapters (Zero-Padded!)
# For 100-page book with ~10 chapters
pdftotext -f 1 -l 12 -layout textbook.pdf ch01.txt
pdftotext -f 13 -l 25 -layout textbook.pdf ch02.txt
pdftotext -f 26 -l 38 -layout textbook.pdf ch03.txt
# ... continue for all chaptersStep 3: Estimate Time
speak --estimate ch*.txt
# Shows: total audio duration, generation time, storage needed
# Quick estimates:
# 1 page ≈ 2 min audio ≈ 1 min generation
# 100 pages ≈ 200 min audio ≈ 100 min generation ≈ 500 MBStep 4: Generate Audio
mkdir -p audiobook/
speak ch01.txt ch02.txt ch03.txt --output-dir audiobook/ --auto-chunk
# Creates: audiobook/ch01.wav, audiobook/ch02.wav, audiobook/ch03.wavStep 5: Concatenate
speak concat audiobook/ch01.wav audiobook/ch02.wav audiobook/ch03.wav --output complete_audiobook.wav
# Or with glob (only if zero-padded):
speak concat audiobook/ch*.wav --output complete_audiobook.wavPDF Troubleshooting
| Issue | Solution | |
|---|---|---|
| Empty/garbled text | Scanned PDF — use OCR: brew install tesseract | |
| Wrong encoding | Try: pdftotext -enc UTF-8 doc.pdf | |
| Check word count | `pdftotext doc.pdf - \ | wc -w` (should be >100) |
Multi-Voice Content
mkdir -p podcast/scripts podcast/wav
echo "Welcome to the show." > podcast/scripts/01_host.txt
echo "Thanks for having me." > podcast/scripts/02_guest.txt
speak podcast/scripts/01_host.txt --voice ~/.chatter/voices/host.wav --output podcast/wav/01.wav
speak podcast/scripts/02_guest.txt --voice ~/.chatter/voices/guest.wav --output podcast/wav/02.wav
speak concat podcast/wav/01.wav podcast/wav/02.wav --output podcast.wavOptions Reference
| Option | Description | Default |
More from emzod
Use this skill in a project
Open any RiverX project, search the Skills panel for emzod/speak/speak-tts, and install it in one click.
