Unified Speech-to-Text (STT) and Text-to-Speech (TTS) API Server.

Create .env before running:
cp .env.example .env
See .env.example for available options.
Before installing dependencies, configure .env:
DEVICE=cuda, leave PYTORCH_BACKEND= for PyPI default or set a specific backend like cu128DEVICE=cpu and PYTORCH_BACKEND=cpuRESONANCE_PORT (default 8000)RESONANCE_CORS_ORIGINS only for custom origins; default follows RESONANCE_PORTjust build
just run
install it on your platform
./scripts/install-macos.sh
This creates .env if missing, configures the device, installs dev dependencies
manually choose your method
winget install "FFmpeg (Essentials Build)"
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
uv tool install rust-just
winget install Microsoft.VCRedist.2015+.x64 -e
just dev-deps
just dev
On macOS you can build Resonance.app menu bar app via:
just build-macos
and if you want to run from terminal with live logs:
./build/Resonance.app/Contents/MacOS/Resonance
Open http://localhost:${RESONANCE_PORT} (default: http://localhost:8000)
Models are loaded lazily on first real STT/TTS use. Startup does not pre-download or pre-load model weights, so the first request to a specific backend may take noticeably longer.
| Endpoint | Method | Description |
|---|---|---|
/api/health | GET | Health check |
/api/config | GET | Public configuration including TTS language -> voice catalog |
/api/models | GET | List backend/model status plus TTS catalog |
/api/jobs | GET | List current session jobs (compact DTO); query limit (default 60), offset; JSON includes has_more, next_offset |
/api/jobs/stt | POST | Start STT job, returns job_id |
/api/jobs/tts | POST | Start TTS job with text, language, voice_id; returns job_id |
/api/jobs/{job_id} | GET | Get job status/result (session-scoped) |
/api/jobs/{job_id}/events | GET | Stream job events (SSE, session-scoped) |
/api/jobs/{job_id}/cancel | POST | Cancel active job (session-scoped) |
/api/stream/download | GET | Download TTS audio |
/api/system-audio/start | POST | Start internal system & microphone audio capture |
/api/system-audio/stop | POST | Stop capture and launch interleaved dual-stream STT job |
localStorage:
resonance_stt_active_job_idresonance_tts_active_job_idGET /api/jobs (paginated with offset / has_more) and contains only jobs for the current browser session.resonance_session_id cookie and enforces ownership on status/events/cancel endpoints.GET /api/jobs/{job_id} and continues progress via /events.JobRegistry), so after server restart unknown job_id is cleared on client and UI resets to neutral state.29 commits
Python
44.6%
HTML
42.4%
JavaScript
5.6%
Swift
5.4%
Just
1.1%
Unified Speech-to-Text (STT) and Text-to-Speech (TTS) API Server.

Create .env before running:
cp .env.example .env
See .env.example for available options.
Before installing dependencies, configure .env:
DEVICE=cuda, leave PYTORCH_BACKEND= for PyPI default or set a specific backend like cu128DEVICE=cpu and PYTORCH_BACKEND=cpuRESONANCE_PORT (default 8000)RESONANCE_CORS_ORIGINS only for custom origins; default follows RESONANCE_PORTjust build
just run
install it on your platform
./scripts/install-macos.sh
This creates .env if missing, configures the device, installs dev dependencies
manually choose your method
winget install "FFmpeg (Essentials Build)"
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
uv tool install rust-just
winget install Microsoft.VCRedist.2015+.x64 -e
just dev-deps
just dev
On macOS you can build Resonance.app menu bar app via:
just build-macos
and if you want to run from terminal with live logs:
./build/Resonance.app/Contents/MacOS/Resonance
Open http://localhost:${RESONANCE_PORT} (default: http://localhost:8000)
Models are loaded lazily on first real STT/TTS use. Startup does not pre-download or pre-load model weights, so the first request to a specific backend may take noticeably longer.
| Endpoint | Method | Description |
|---|---|---|
/api/health | GET | Health check |
/api/config | GET | Public configuration including TTS language -> voice catalog |
/api/models | GET | List backend/model status plus TTS catalog |
/api/jobs | GET | List current session jobs (compact DTO); query limit (default 60), offset; JSON includes has_more, next_offset |
/api/jobs/stt | POST | Start STT job, returns job_id |
/api/jobs/tts | POST | Start TTS job with text, language, voice_id; returns job_id |
/api/jobs/{job_id} | GET | Get job status/result (session-scoped) |
/api/jobs/{job_id}/events | GET | Stream job events (SSE, session-scoped) |
/api/jobs/{job_id}/cancel | POST | Cancel active job (session-scoped) |
/api/stream/download | GET | Download TTS audio |
/api/system-audio/start | POST | Start internal system & microphone audio capture |
/api/system-audio/stop | POST | Stop capture and launch interleaved dual-stream STT job |
localStorage:
resonance_stt_active_job_idresonance_tts_active_job_idGET /api/jobs (paginated with offset / has_more) and contains only jobs for the current browser session.resonance_session_id cookie and enforces ownership on status/events/cancel endpoints.GET /api/jobs/{job_id} and continues progress via /events.JobRegistry), so after server restart unknown job_id is cleared on client and UI resets to neutral state.29 commits
Python
44.6%
HTML
42.4%
JavaScript
5.6%
Swift
5.4%
Just
1.1%