Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions CODEX_TASK_PIPER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Codex task: replace gTTS realtime speech synthesis with Piper

Repository: trinitron88/ChinTranslator
Base branch: main
Issue: #11

Goal
Replace per-utterance gTTS MP3 generation in the realtime Hugging Face Space with local Piper TTS to reduce latency, network dependency, and phone battery drain.

Context
hf_space/app.py currently calls gTTS, writes an MP3 temp file, reloads it via librosa, converts it to PCM, and yields it back to FastRTC. This works but is slow and network-bound. The project roadmap already calls out Piper as the next step for low-latency local TTS.

Suggested implementation
- Work primarily in hf_space/app.py and hf_space/requirements.txt.
- Add backend config with environment variables such as TTS_BACKEND, PIPER_MODEL, and PIPER_CONFIG.
- Keep gTTS as fallback while Piper is being tested.
- Implement a speak_piper(text, lang) path for English output in Chin to English mode.
- Return FastRTC-compatible sample rate and int16 PCM audio.
- Avoid shelling out per phrase if a Python API or persistent process is practical; otherwise document the tradeoff.
- English to Chin can remain text-only unless a suitable Chin voice exists.
- Update REALTIME.md and/or README.md with required Space variables and model setup.

Acceptance criteria
- Chin to English mode speaks English using Piper when configured.
- App still boots if Piper is unavailable and falls back cleanly to gTTS or text-only.
- Per-utterance latency is materially lower than gTTS in local or HF testing.
- No temp MP3 round-trip is required for the Piper path.
- Docs explain how to configure Piper in the Space.

Suggested validation
- Run or import hf_space/app.py enough to confirm syntax and imports.
- Test the gTTS fallback still behaves like current production.
- Test text-only mode if implemented.
- Test Piper path on a short English phrase and confirm PCM output shape and sample rate are accepted by FastRTC.
8 changes: 7 additions & 1 deletion hf_space/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@

CHIN_CODE = "cnh"

APP_VERSION = os.environ.get("APP_VERSION", "v5.0.1")
print(f"[app] version={APP_VERSION}", flush=True)

# Skip translating/speaking when the input is detected as English. Besides being
# the requested behavior, this breaks the TTS→mic feedback loop (the English we
# speak won't get re-transcribed and echoed). Tunable via env: SKIP_ENGLISH=0
Expand Down Expand Up @@ -332,7 +335,7 @@ def _update_transcript(current: str, chin: str, english: str) -> str:
server_rtc_configuration=server_rtc_configuration,
# Short, one-line title so it doesn't wrap and overlap the record button
# on mobile.
ui_args={"title": "Hahka Chin Audio Translator"},
ui_args={"title": "Hakha Chin Audio Translator"},
)

# Spaces (gradio SDK) serves this `demo` object. Append a mic-sensitivity slider;
Expand Down Expand Up @@ -375,8 +378,11 @@ def _update_transcript(current: str, chin: str, english: str) -> str:
".button-wrap .mute-button {"
" padding: var(--size-2) var(--size-4) !important;"
" border-radius: var(--radius-lg) !important; }"
".app-version { font-size: 0.85rem; opacity: 0.7; text-align: center;"
" margin: -0.25rem 0 0.75rem; }"
"</style>"
)
gr.HTML(f"<div class='app-version'>Build: {APP_VERSION}</div>")
direction = gr.Radio(
choices=[("Hakha Chin → English", "cnh2en"),
("English → Hakha Chin", "en2cnh")],
Expand Down