Turn every built-in Mac voice into a Unix pipe filter. Zero disk I/O. Zero GPU. Pure CPU inference.
echo "Hello" | tts_pipe com.apple.voice.premium.en-US.Samantha 0.5 > out.pcm
echo "你好" | tts_pipe com.apple.voice.premium.zh-CN.Yun 0.5 | ffplay -f s16be -ar 22050 -ac 1 pipe:0 -
rec -t raw -r 16000 -c 1 -b 16 -e signed - | stt_pipe --lang zh-CN
say writes AIFF files (must seek, so pipes are impossible). tts_pipe calls AVSpeechSynthesizer.write(toBuffer:) to get PCM buffers directly in memory — a true Unix filter.
Mac Premium voices (Yun, Han, Samantha, Kyoko, etc.) come from Apple's decades of speech synthesis R&D. Quality surpasses most open-source local TTS solutions. No GPU needed — pure CPU inference delivers natural, fluid speech.
make build-tts
# Play
./tts_pipe com.apple.voice.premium.zh-CN.Yun "Hello" 0.5 | ffplay -f s16be -ar 22050 -ac 1 pipe:0 -
# Install
sudo make install# Single sentence
tts_pipe <voice-identifier> <text> [rate]
# Stream mode (stdin, one sentence per line)
tts_pipe --stdin <voice-identifier> [rate]Chinese: Yun ★ Yue ★ Han ★ Lili ★ Lilian ★ Tingting English: Samantha ★ Alex ★ Ava ★ Japanese: Kyoko ★
★ = Premium (download in System Settings → Accessibility → Spoken Content)
List all installed:
swift -e 'import AVFoundation; AVSpeechSynthesisVoice.speechVoices().forEach { print($0.identifier, "|", $0.name, "|", $0.language) }'Sample rate 22050 Hz · 16-bit signed integer · mono · Big Endian
Python: subprocess.Popen(['tts_pipe', '--stdin', voice, rate], stdin=..., stdout=...)
Node: spawn('tts_pipe', ['--stdin', voice, rate])
Full examples in examples/.
stt_pipe uses Apple's on-device SFSpeechRecognizer. All processing is local — no network, no API keys, no per-minute billing. On Apple Silicon, recognition runs on the Neural Engine.
make build-stt
# Pipe audio from a file
sox input.wav -t raw -r 16000 -c 1 -b 16 -e signed - | ./stt_pipe --lang zh-CN
# Record from microphone
./stt_pipe --mic --lang en-US
# With ffmpeg (any format)
ffmpeg -i recording.mp3 -f s16le -ar 16000 -ac 1 pipe:1 | ./stt_pipe --lang zh-CN
# Install
sudo make install# Pipe mode (stdin → raw PCM)
stt_pipe --lang <locale> < audio.pcm
# Microphone mode
stt_pipe --mic --lang <locale>| Parameter | Description |
|---|---|
--lang |
Language locale (default: en-US). e.g. zh-CN, ja-JP, de-DE |
--mic |
Record from microphone instead of stdin |
60+ locales. Common ones:
| Locale | Language |
|---|---|
en-US |
English (US) |
zh-CN |
Chinese (Simplified) |
ja-JP |
Japanese |
ko-KR |
Korean |
de-DE |
German |
fr-FR |
French |
es-ES |
Spanish |
For the full list:
swift -e 'import Speech; SFSpeechRecognizer.supportedLocales().forEach { print($0.identifier) }' | sortSample rate 16000 Hz · 16-bit signed integer · mono · Little Endian
Convert anything to this format with ffmpeg:
ffmpeg -i input.mp3 -f s16le -ar 16000 -ac 1 pipe:1 | stt_pipe --lang en-USJust for fun — synthesize with one voice and transcribe with another:
tts_pipe com.apple.voice.premium.zh-CN.Yun "你好世界" 0.5 2>/dev/null \
| ffmpeg -f s16be -ar 22050 -ac 1 -i pipe:0 -f s16le -ar 16000 -ac 1 pipe:1 2>/dev/null \
| stt_pipe --lang zh-CN 2>/dev/null
# → 你好世界git clone https://github.com/rrlab-tech/mac-tts.git
cd mac-tts
make build
sudo make installThis installs both tts_pipe and stt_pipe to /usr/local/bin/.
A higher-level Dart CLI that wraps tts_pipe with sentence splitting and WAV output:
cd rrtts && dart pub get
dart run bin/rrtts.dart -f README.md --voice=YunMIT.
Extracted from Juhoushu macOS voice modules.