diff --git a/Makefile b/Makefile index 510f7c0..18a2010 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ REMOTE_USER ?= $(USER) REMOTE_PATH ?= ~/uncloseai-speech CONTAINER_NAME ?= uncloseai-speech-server-1 -.PHONY: help deploy sync restart logs test clean stop start voices +.PHONY: help deploy sync restart logs test clean stop start voices voices-piper voices-xtts help: @echo "๐Ÿฆ Raccoon TTS Mission - Development Commands" @@ -26,8 +26,11 @@ help: @echo "" @echo "Development:" @echo " make logs - Tail container logs" - @echo " make test - Test TTS endpoint" - @echo " make voices - Download Piper voices properly" + @echo " make test - Test TTS endpoint (Piper)" + @echo " make test-xtts - Test XTTS HD endpoint" + @echo " make voices - Download all voices (Piper + XTTS)" + @echo " make voices-piper - Download Piper voices only" + @echo " make voices-xtts - Download XTTS voices and samples" @echo "" @echo "Container:" @echo " make start - Start Docker container" @@ -74,7 +77,10 @@ test: @echo "โœ… Test complete! Playing audio..." @firefox /tmp/raccoon_test.mp3 || mpv /tmp/raccoon_test.mp3 || echo "Install firefox or mpv to play audio" -voices: +voices: voices-piper voices-xtts + @echo "โœ… All voices downloaded!" + +voices-piper: @echo "๐ŸŽค Downloading Piper voices with correct directory structure..." ssh $(REMOTE_USER)@$(REMOTE_HOST) "docker exec $(CONTAINER_NAME) bash -c '\ mkdir -p /app/voices/en/en_US/libritts_r/medium && \ @@ -89,4 +95,18 @@ voices: ssh $(REMOTE_USER)@$(REMOTE_HOST) "docker exec $(CONTAINER_NAME) bash -c '\ sed -i \"s|model: voices/en_US-libritts_r-medium.onnx|model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx|g\" /app/config/voice_to_speaker.yaml && \ sed -i \"s|model: voices/en_GB-northern_english_male-medium.onnx|model: /app/voices/en/en_GB/northern_english_male/medium/en_GB-northern_english_male-medium.onnx|g\" /app/config/voice_to_speaker.yaml'" - @echo "โœ… Voices installed with absolute paths!" + @echo "โœ… Piper voices installed with absolute paths!" + +voices-xtts: + @echo "๐ŸŽค Downloading XTTS speaker samples..." + ssh $(REMOTE_USER)@$(REMOTE_HOST) "docker exec $(CONTAINER_NAME) bash -c 'cd /app && ./scripts/download_samples.sh'" + @echo "โœ… XTTS speaker samples downloaded!" + +test-xtts: + @echo "๐Ÿงช Testing XTTS HD endpoint (this may take 1-2 minutes on first run)..." + curl -X POST http://$(REMOTE_HOST):8000/v1/audio/speech \ + -H "Content-Type: application/json" \ + -d '{"model":"tts-1-hd","voice":"alloy","input":"Testing XTTS high definition"}' \ + -o /tmp/xtts_test.mp3 + @echo "โœ… Test complete! Playing audio..." + @firefox /tmp/xtts_test.mp3 || mpv /tmp/xtts_test.mp3 || echo "Install firefox or mpv to play audio" diff --git a/docs/CLAUDE.md b/docs/CLAUDE.md new file mode 100644 index 0000000..d3fb58e --- /dev/null +++ b/docs/CLAUDE.md @@ -0,0 +1,212 @@ +# Instructions for Claude Code + +**Project:** UncloseAI Speech - Raccoon Mission TTS System +**License:** AGPL v3 (must provide source code to network service users) + +## Core Principles + +### 1. Makefile-First Development + +**ALWAYS prefer Makefile targets over manual commands.** + +- โœ… DO: `make deploy`, `make voices`, `make test` +- โŒ DON'T: Manual ssh commands, docker commands, curl commands + +**When adding new functionality:** +1. Add it to the Makefile first +2. Document it in `make help` +3. Test it works from scratch +4. Only then modify other files if needed + +**Makefile is the source of truth** for all deployment and development tasks. + +### 2. Work Locally, Deploy Remotely + +- **Local development:** `/home/fox/git/openedai-speech/` +- **Remote server:** Configured in `vars.sh` (gitignored) +- **Never create remote directories manually** - let Makefile handle it +- **Always test from scratch** - `make clean` then `make deploy` + +### 3. Configuration Management + +- `vars.sh` - Deployment secrets (gitignored, never commit) +- `vars.sh.example` - Template for users (commit this) +- `sample.env` - Default environment (commit this) +- `speech.env` - Runtime environment (created automatically by Makefile) + +**Never view or log secrets** - source them and use them. + +### 4. Documentation Requirements + +When adding features, update ALL relevant docs: +- `Makefile` help text +- `docs/MODELS.md` for new TTS engines +- `docs/MIRRORS.md` for binary downloads +- `docs/AUDIT.md` for file changes +- This file (`docs/CLAUDE.md`) for new patterns + +## Common Tasks + +### Full Deployment from Scratch + +```bash +# 1. Clean everything +make clean + +# 2. Deploy (syncs files, creates env, builds container) +make deploy + +# 3. Download voices (Piper + XTTS samples) +make voices + +# 4. Test +make test +make test-xtts +``` + +### Adding a New TTS Engine + +1. Document it in `docs/MODELS.md` first +2. Add download target to Makefile (e.g., `voices-silero`) +3. Implement engine wrapper in `speech.py` or `src/engines/` +4. Add test target (e.g., `test-silero`) +5. Update `make voices` to include it +6. Test full cycle: `make clean && make deploy && make voices` + +### Debugging Issues + +```bash +make logs # Tail live logs +make logs | grep ERROR # Filter errors +``` + +Never use raw docker/ssh commands - extend Makefile if needed. + +## File Organization + +### Scripts vs Docs + +- `scripts/` - Executable utilities (add_voice.py, download_samples.sh, etc.) +- `docs/` - Documentation ONLY (no executable code) +- Dockerfiles, startup.sh - Root level (build artifacts) +- Makefile - Root level (primary interface) + +**Never put executable scripts in docs/ directory.** + +### Current Structure (as of 2025-11-09) + +``` +uncloseai-speech/ +โ”œโ”€โ”€ Makefile # PRIMARY INTERFACE - always update first +โ”œโ”€โ”€ vars.sh # Secrets (gitignored) +โ”œโ”€โ”€ vars.sh.example # Template +โ”œโ”€โ”€ speech.py # Main server (will refactor to src/) +โ”œโ”€โ”€ openedai.py # API models +โ”œโ”€โ”€ voice_to_speaker.default.yaml # Voice config +โ”œโ”€โ”€ docs/ +โ”‚ โ”œโ”€โ”€ CLAUDE.md # This file +โ”‚ โ”œโ”€โ”€ AUDIT.md # Repository audit +โ”‚ โ”œโ”€โ”€ MODELS.md # TTS engines +โ”‚ โ””โ”€โ”€ MIRRORS.md # Binary mirror strategy +โ”œโ”€โ”€ scripts/ +โ”‚ โ”œโ”€โ”€ add_voice.py +โ”‚ โ”œโ”€โ”€ say.py +โ”‚ โ”œโ”€โ”€ test_voices.sh +โ”‚ โ””โ”€โ”€ download_samples.sh +โ”œโ”€โ”€ Dockerfile +โ”œโ”€โ”€ docker-compose.yml +โ””โ”€โ”€ startup.sh +``` + +## TTS Engine Status + +### Working +- โœ… Piper TTS (tts-1) - Fast, 100+ voices, absolute paths working +- โš ๏ธ XTTS v2 (tts-1-hd) - High quality, needs speaker samples + +### High Priority Integration +- ๐ŸŽฏ Silero TTS - Active project, fast, good quality +- ๐ŸŽฏ StyleTTS2 - Best quality available +- ๐ŸŽฏ Fish Speech - Modern, multilingual + +See `docs/MODELS.md` for complete roadmap. + +## Deployment Workflow + +``` +Local: + /home/fox/git/openedai-speech/ + + โ†“ make deploy (rsync) + +Remote (ai.foxhop.net): + ~/uncloseai-speech/ + + โ†“ docker compose up --build + +Container: + /app/ + โ”œโ”€โ”€ speech.py + โ”œโ”€โ”€ voices/ + โ”‚ โ””โ”€โ”€ en/en_US/libritts_r/medium/*.onnx + โ””โ”€โ”€ config/ + โ””โ”€โ”€ voice_to_speaker.yaml +``` + +## Testing Philosophy + +**Always test the full stack:** +1. Clean state (`make clean`) +2. Fresh deploy (`make deploy`) +3. Voice download (`make voices`) +4. API test (`make test`, `make test-xtts`) + +**Never assume** - if you changed something, test from scratch. + +## Raccoon Mission Values + +1. **Resilience** - Assume upstream dies, plan mirrors +2. **Simplicity** - Makefile > manual commands +3. **Documentation** - Write docs before code +4. **Liberation** - Keep TTS libre (AGPL v3) +5. **Unification** - All TTS engines, one API + +## Common Mistakes to Avoid + +โŒ DON'T create directories with raw ssh +โœ… DO add Makefile target for deployment + +โŒ DON'T assume container has changes after rsync +โœ… DO rebuild with `make deploy` (runs docker compose up --build) + +โŒ DON'T put scripts in docs/ +โœ… DO put scripts in scripts/, reference from docs + +โŒ DON'T hardcode paths/hosts +โœ… DO use vars.sh variables + +โŒ DON'T forget to test from scratch +โœ… DO run `make clean && make deploy && make voices` + +## When Things Break + +1. Check `make logs` for errors +2. Verify Makefile was updated +3. Test from clean state +4. Check if container was rebuilt (`make deploy` does this) +5. Verify voices downloaded (`ls` in container via `make logs` approach) + +## Future Refactoring (Planned) + +- Move `speech.py`, `openedai.py`, `audio_reader.py` โ†’ `src/` +- Create engine abstraction layer in `src/engines/` +- Unified voice config with engine selection +- Binary mirror implementation (MinIO on ai.foxhop.net) + +See `docs/AUDIT.md` for detailed refactoring plan. + +--- + +**Remember:** Makefile first, documentation second, code third. Test from scratch every time. + +๐Ÿฆ **Raccoon Mission:** Keep TTS libre, rescue abandoned models, unify all engines. diff --git a/speech.py b/speech.py index a8508a8..dfa2e4c 100755 --- a/speech.py +++ b/speech.py @@ -243,7 +243,6 @@ async def generate_speech(request: GenerateSpeechRequest): # Log any stderr output from Piper if tts_proc.stderr: - import threading def log_stderr(): stderr_output = tts_proc.stderr.read().decode('utf-8', errors='replace') if stderr_output.strip():