Files
FabledScribe/alembic/versions/0047_reset_voice_tts_settings.py
T
bvandeusen a28f75994a feat(voice): swap kokoro TTS → piper-tts
Kokoro has been stale upstream since April 2025 (`requires_python<3.13`),
which broke the Python 3.14 build. Piper is the active replacement:
maintained by OHF/Home Assistant, depends only on onnxruntime +
pathvalidate (no torch, no spacy, no transformers), and has cp314
support today.

Dockerfile:
- Add `pip install piper-tts` after the STT install.
- Bundle two default voices (en_US-amy-medium, en_US-ryan-medium) into
  /opt/piper-voices at build. Additional voices can be downloaded into
  /data/voices via the admin UI (separate commit).
- Image add over the STT-only baseline: ~150 MB.

services/tts.py — full rewrite:
- New voice-discovery layer scans /opt/piper-voices + /data/voices for
  .onnx + .onnx.json pairs. /data wins over /opt for the same id so
  admin-downloaded voices can override bundled defaults.
- Single PiperVoice kept warm; switches via _switch_voice() when the
  user changes their voice_tts_voice setting.
- list_voices() returns metadata read from .onnx.json sidecars (label
  derived from filename, language, quality, sample_rate).
- synthesise() uses piper's SynthesisConfig; converts kokoro-shaped
  `speed` multiplier to piper's `length_scale` (1.0 / speed).
- `voice_blend` parameter accepted but ignored — piper has no blend
  equivalent; first entry's voice is used if anything is passed.
- Dropped: HuggingFace commit-hash tracking (~80 lines), the daily
  check_for_kokoro_updates task, voice-tensor blending math.

routes/voice.py:
- tts_backend reports "piper" in /api/voice/status.
- /api/voice/voices no longer requires tts_available() — even with
  the active voice failed to load, the catalog still lets the user
  pick a different one.
- Synthesise request body dropped the voice_blend field; speed and
  voice still supported.

alembic 0047_reset_voice_tts_settings:
- Deletes any stored voice_tts_voice (kokoro IDs that don't map to
  piper) and voice_tts_blend (no piper equivalent) rows. Both
  re-default cleanly on next read.

frontend:
- VoiceBlendEntry type removed from api/client.ts.
- synthesiseSpeech() signature dropped the voiceBlend parameter.
- SettingsView.vue Voice Blend section removed entirely (slider,
  preview, slot management). voice_tts_blend save path removed.
- Default voice id changed from "af_heart" to "en_US-amy-medium".
- VoiceEntry gains optional language/quality/sample_rate fields
  from the richer piper sidecar metadata.

Voice paths remain lazily guarded — `VOICE_ENABLED=false` (default)
starts the app cleanly regardless of which TTS deps are present.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 07:59:09 -04:00

39 lines
1.1 KiB
Python

"""reset voice_tts_voice and voice_tts_blend settings for piper migration
Revision ID: 0047
Revises: 0046
Create Date: 2026-05-22
The TTS backend swapped from kokoro to piper. Kokoro voice IDs
(`af_heart`, `am_adam`, etc.) don't map to piper voice files
(`en_US-amy-medium`, etc.) and there's no sensible auto-translation.
Clear the stored voice selection so every user falls back to the piper
default the next time they synthesize.
`voice_tts_blend` goes away entirely — piper has no voice-blending
equivalent. The TTS service accepts the field for backward compat but
ignores it; clearing the rows makes the DB match reality.
Both settings re-default cleanly on read, so this migration just deletes
the rows without backfilling anything.
"""
from alembic import op
revision = "0047"
down_revision = "0046"
branch_labels = None
depends_on = None
def upgrade() -> None:
op.execute(
"DELETE FROM settings WHERE key IN ('voice_tts_voice', 'voice_tts_blend')"
)
def downgrade() -> None:
# No-op. The deleted settings just re-default on read; restoring the
# kokoro IDs wouldn't help anyway since kokoro is gone.
pass