Commit Graph

11 Commits

Author SHA1 Message Date
91887ae296 feat: Add XTTS v2 support, refactor Docker/GPU infra, and improve Piper engine
- Add XTTS v2 configuration to .env.example
- Refactor Dockerfile to multi-stage build with CUDA 12.1 support
- Update Makefile with Kokoro and XTTS test environment targets
- Refactor Piper engine (app/engines/piper.py) to use python module execution
- Add comprehensive documentation for Kokoro and XTTS plans
- Add helper scripts and patches for build process
2025-12-13 11:37:58 +01:00
d6d1fe9d23 docs: Update documentation for OpenAI API and XTTS support
- Updated README.md to include XTTS engine details and model setup instructions.
- Added section on OpenAI API compatibility in README.md.
- Updated API_DOCUMENTATION.md to include the new POST /v1/audio/speech endpoint.
2025-12-09 14:37:40 +01:00
7a2c6bb209 test: Add comprehensive tests for OpenAI-compatible TTS endpoint
- Refactor existing tests to use a shared mock engine fixture.
- Add tests for unsupported response formats.
- Add tests for engine synthesis failures.
- Add tests for 'engine:model_id' parsing in the 'model' parameter.
- Add tests for different audio response formats (opus, flac).
2025-12-09 12:53:07 +01:00
fff0252d52 feat: Add OpenAI-compatible TTS endpoint and engines
- Implements POST /v1/audio/speech endpoint (OpenAI API compatible).
- Integrates Kokoro and XTTS engines (including dependencies and implementations).
- Updates main application to register new engines and router.
- Adds unit tests for OpenAI compatibility.
- Updates requirements.txt for new engines.
2025-12-09 12:45:17 +01:00
c06fd677dc fix: Resolve 7 critical bugs in Piper TTS engine and add cache versioning
This commit fixes all critical bugs identified in the Piper engine that were
causing server crashes, hung processes, resource leaks, and audio synthesis
failures.

## Bug Fixes

**Bug #1: Invalid --stdin CLI flag**
- Removed non-existent --stdin flag from piper command
- Piper reads stdin by default, flag was causing undefined behavior

**Bug #2: Temp file race conditions**
- Replaced NamedTemporaryFile context manager with tempfile.mkstemp()
- Prevents file handle locking issues on some systems

**Bug #3: Missing process timeouts**
- Added asyncio.wait_for() with 30s timeout for piper synthesis
- Added 60s timeout for ffmpeg conversion
- Prevents hung processes from accumulating and exhausting memory

**Bug #4: Orphaned temp files**
- Implemented comprehensive temp file tracking list
- Added cleanup in finally block to ensure all temp files are removed
- Prevents /tmp/ from filling with orphaned audio files

**Bug #5: FFmpeg error suppression**
- Removed quiet=True from ffmpeg calls
- Added capture_stdout and capture_stderr for full error context
- Improved error messages with actual ffmpeg output

**Bug #6: No config file validation**
- Added upfront validation for .onnx and .onnx.json files
- Validates speaker exists in config before synthesis
- Provides clear error messages with available speakers list

**Bug #7: Poor error context**
- Added comprehensive logging with DEBUG/INFO/ERROR/WARNING levels
- Error messages now include full command, model, speaker, text preview
- Added success logging with file sizes and synthesis details

## New Features

**Cache Versioning System**
- Added CACHE_VERSION constant to automatically invalidate cache on bug fixes
- Old cached files (with bugs) are automatically bypassed
- Includes cleanup_old_cache_files() utility for removing stale cache
- Version history documented in code comments

**Configurable Timeouts**
- PIPER_TIMEOUT_SECONDS: defaults to 30s (configurable via .env)
- FFMPEG_TIMEOUT_SECONDS: defaults to 60s (configurable via .env)

**Path Fixes**
- Fixed audio file path validation in main.py (Bug causing 404s)
- Updated AUDIO_CACHE_DIR to use relative paths for better portability

**Documentation**
- Added CLAUDE.md for future AI assistant context
- Updated .env.example with new timeout configuration options

## Testing

- ✅ Health check passed
- ✅ Synthesis working correctly
- ✅ No temp file leaks
- ✅ No hung processes
- ✅ Cache versioning prevents old buggy files from being served
- ✅ Voice preview in wizard working correctly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 00:38:00 +01:00
06a484d0aa docs: Add model downloading instructions to README
This commit adds a crucial "Downloading Models" section to the README.md.

- Explains that models are not included in the Docker image and must be downloaded manually.
- Provides detailed instructions for downloading Piper models from Hugging Face, including an example for the  voice.
- Clarifies the expected directory structure for placing the downloaded models.
- Mentions that StyleTTS is currently a placeholder and does not require model downloads.
2025-12-04 23:04:08 +01:00
2669af6cf1 docs: Update README with container registry workflow
This commit updates the main README.md file to reflect the recent changes related to the container registry integration.

- Clarifies the difference between Starting development environment by pulling image from registry...
export IMAGE_NAME=audio-engine-hub && \
export REGISTRY=git.wlkns.org && \
export USERNAME=stephan && \
export TAG=latest && \
docker compose up -d (for registry images) and Starting development environment (local build) on port 8000... (for local builds).
- Adds a dedicated "Container Registry" section explaining the push/pull workflow.
- Updates the "Makefile Commands" section with the new , , and  targets.
2025-12-04 22:48:33 +01:00
527f611061 feat: Integrate container registry support and Makefile enhancements
This commit integrates support for pushing and pulling Docker images from a container registry and enhances the Makefile for a more flexible development workflow.

Key changes include:

- **Container Registry Configuration:** Added  and  variables to the Makefile and updated  and  targets to correctly tag and push images to the configured registry.
- **Docker Compose Registry Integration:** Modified  to use the image from the registry by default instead of building locally.
- **Makefile Workflow Enhancements:**
    - Introduced a  target (Pulling image git.wlkns.org/stephan/audio-engine-hub:latest from registry...
docker pull git.wlkns.org/stephan/audio-engine-hub:latest) for explicitly downloading images from the registry.
    - Modified the  target (Starting development environment by pulling image from registry...
export IMAGE_NAME=audio-engine-hub && \
export REGISTRY=git.wlkns.org && \
export USERNAME=stephan && \
export TAG=latest && \
docker compose up -d) to use the registry image.
    - Added a  target (Starting development environment (local build) on port 8000...) for local development, which explicitly builds the image from source () before starting the service.
    - Updated  and GNU bash, Version 5.1.16(1)-release (x86_64-pc-linux-gnu)
Diese Shellkommandos sind intern definiert. Geben Sie »help« ein, um diese
Liste zu sehen. Geben Sie »help Name« ein, um die Beschreibung der Funktion
»Name« zu sehen. Geben Sie »info bash« ein, um die vollständige Dokumentation
zu sehen. Geben Sie »man -k« oder »info« ein, um detaillierte Beschreibungen
der Shellkommandos zu sehen.

Ein Stern (*) neben dem Namen kennzeichnet deaktivierte Kommandos.

 Jobbezeichnung [&]                                                         history [-c] [-d Offset] [n] oder history -anrw [Dateiname] oder histor>
 (( Ausdruck ))                                                             if Kommandos; then Kommandos; [ elif Kommandos; then Kommandos; ]... [ >
 . Dateiname [Argumente]                                                    jobs [-lnprs] [Jobbezeichnung ...] or jobs -x Kommando [Arg]
 :                                                                          kill [-s Signalname | -n Signalnummer | -Signalname] pid | jobspec ... >
 [ Argument... ]                                                            let Argument [Argument ...]
 [[ Ausdruck ]]                                                             local [Option] Name[=Wert] ...
 alias [-p] [Name[=Wert] ... ]                                              logout [n]
 bg [Jobbezeichnung ...]                                                    mapfile [-d Begrenzer] [-n Anzahl] [-O Quelle] [-s Anzahl] [-t] [-u fd]>
 bind [-lpsvPSVX] [-m Tastaturtabelle] [-f Dateiname] [-q Name] [-u Name]>  popd [-n] [+N | -N]
 break [n]                                                                  printf [-v var] Format [Argumente]
 builtin [Shell-Kommando [Argument ...]]                                    pushd [-n] [+N | -N | Verzeichnis]
 caller [Ausdruck]                                                          pwd [-LP]
 case Wort in [Muster [| Muster]...) Kommandos ;;]... esac                  read [-ers] [-a Feld] [-d Begrenzer] [-i Text] [-n Zeichenanzahl] [-N Z>
 cd [-L|[-P [-e]] [-@]] [Verzeichnis]                                       readarray [-d Begrenzer] [-n Anzahl] [-O Quelle] [-s Anzahl] [-t]      >
 command [-pVv] Kommando [Argument ...]                                     readonly [-aAf] [Name[=Wert] ...] oder readonly -p
 compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlis>  return [n]
 complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpa>  select Name [in Wortliste ... ;] do Kommandos; done
 compopt [-o|+o Option] [-DEI] [Name ...]                                   set [-abefhkmnptuvxBCHP] [-o Option] [--] [Argument ...]
 continue [n]                                                               shift [n]
 coproc [Name] Kommando [Umleitungen]                                       shopt [-pqsu] [-o] [Optionsname ...]
 declare [-aAfFgiIlnrtux] [-p] [Name[=Wert] …]                              source Dateiname [Argumente]
 dirs [-clpv] [+N] [-N]                                                     suspend [-f]
 disown [-h] [-ar] [Jobbezeichnung ... | pid ...]                           test [Ausdruck]
 echo [-neE] [Argument ...]                                                 time [-p] Pipeline
 enable [-a] [-dnps] [-f Dateiname] [Name ...]                              times
 eval [Argument ...]                                                        trap [-lp] [[Argument] Signalbezeichnung ...]
 exec [-cl] [-a Name] [Befehl [Argument …]] [Umleitung …]                   true
 exit [n]                                                                   type [-afptP] Name [Name ...]
 export [-fn] [Name[=Wert] ...] oder export -p                              typeset [-aAfFgiIlnrtux] [-p] Name[=Wert] …
 false                                                                      ulimit [-SHabcdefiklmnpqrstuvxPT] [Grenze]
 fc [-e Editor] [-lnr] [Anfang] [Ende] oder fc -s [Muster=Ersetzung] [Kom>  umask [-p] [-S] [Modus]
 fg [Jobbezeichnung]                                                        unalias [-a] Name [Name ...]
 for Name [in Wortliste ... ] ; do Kommandos; done                          unset [-f] [-v] [-n] [NAME ...]
 for (( Ausdruck1; Ausdruck2; Ausdruck3 )); do Kommandos; done              until Kommandos; do Kommandos; done
 function Name { Kommandos ; } oder Name () { Kommandos ; }                 variables - Namen und Bedeutung einiger Shell-Variablen
 getopts optstring name [arg ...]                                           wait [-fn] [-p var] [id ...]
 hash [-lr] [-p Pfadname] [-dt] [Name ...]                                  while Kommandos; do Kommandos; done
 help [-dms] [Muster ...]                                                   { Kommandos ; } targets accordingly.
- **Session Resume Update:** Updated  to document the container registry integration.
2025-12-04 22:42:38 +01:00
a466d8e00f fix: Resolve model loading and deployment issues
This commit fixes several critical issues that prevented the service from deploying correctly and loading the TTS models.

- **Fix Model Loading:** Corrected the volume mount path in  to point to the correct  source directory. The  engine code was also updated to use absolute paths () inside the container, making the model loading mechanism robust.
- **Update Session Resume:** The  has been updated to reflect the final debugging steps and the successful resolution of all issues.
2025-12-04 22:24:58 +01:00
528a185d3b feat: Overhaul application and add DX improvements
This commit introduces a wide range of improvements to the application, focusing on stability, developer experience (DX), and documentation.

Key changes include:

- **Fix Application Startup:** Resolved a critical bug where the FastAPI application instance was not correctly exposed, preventing Uvicorn from starting ().
- **Simplify Docker Compose:** Removed the integrated Traefik setup from the default  to support users with existing reverse proxies and simplify the local development environment.
- **Improve Makefile:**
    - Implemented a robust, automatic port-finding mechanism for Starting development environment on port 8001...
#1 [internal] load local bake definitions
#1 reading from stdin 534B done
#1 DONE 0.0s

#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 1.22kB done
#2 WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 2)
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/python:3.11
#3 DONE 0.7s

#4 [internal] load metadata for docker.io/library/python:3.11-slim
#4 DONE 0.7s

#5 [internal] load .dockerignore
#5 transferring context: 385B done
#5 DONE 0.0s

#6 [builder 1/4] FROM docker.io/library/python:3.11@sha256:bf2d36b8fb1b4a0b590b36736cdd8a6b5175b411bf135c42694ecd68ab8fed02
#6 DONE 0.0s

#7 [stage-1 1/6] FROM docker.io/library/python:3.11-slim@sha256:193fdd0bbcb3d2ae612bd6cc3548d2f7c78d65b549fcaa8af75624c47474444d
#7 DONE 0.0s

#8 [internal] load build context
#8 transferring context: 4.90kB done
#8 DONE 0.0s

#9 [builder 2/4] WORKDIR /opt/venv
#9 CACHED

#10 [stage-1 4/6] WORKDIR /home/appuser
#10 CACHED

#11 [stage-1 3/6] RUN useradd --create-home --shell /bin/bash appuser
#11 CACHED

#12 [stage-1 2/6] RUN apt-get update && apt-get install -y --no-install-recommends     ffmpeg     && rm -rf /var/lib/apt/lists/*
#12 CACHED

#13 [stage-1 5/6] COPY --from=builder /opt/venv /opt/venv
#13 CACHED

#14 [builder 4/4] RUN python -m venv . && . /opt/venv/bin/activate && pip install --no-cache-dir -r requirements.txt
#14 CACHED

#15 [builder 3/4] COPY requirements.txt .
#15 CACHED

#16 [stage-1 6/6] COPY app/ ./app
#16 CACHED

#17 exporting to image
#17 exporting layers done
#17 writing image sha256:6cac7caac7fda2808672ad2f3d117d46d38c1d93013867858543ec74917857b7 done
#17 naming to docker.io/library/audioenginehub-app done
#17 DONE 0.0s

#18 resolving provenance for metadata file
#18 DONE 0.0s and Using host port 8000 for single app container
8a1c69e868e7f13b4c8c9948e81921b48efd9536f326d200b9e912fb12ff66e3 to prevent port conflicts.
    - Added a  target (Running health check on running container...
App container is running on port 8001.
Waiting for app to initialize...
ERROR: Failed to decode JSON from health endpoint.) to run post-deployment sanity checks against the running container's  endpoint.
    - Recommended using Starting development environment on port 8002...
#1 [internal] load local bake definitions
#1 reading from stdin 534B done
#1 DONE 0.0s

#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 1.22kB done
#2 WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 2)
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/python:3.11-slim
#3 DONE 0.1s

#4 [internal] load metadata for docker.io/library/python:3.11
#4 DONE 0.2s

#5 [internal] load .dockerignore
#5 transferring context: 385B done
#5 DONE 0.0s

#6 [builder 1/4] FROM docker.io/library/python:3.11@sha256:bf2d36b8fb1b4a0b590b36736cdd8a6b5175b411bf135c42694ecd68ab8fed02
#6 DONE 0.0s

#7 [stage-1 1/6] FROM docker.io/library/python:3.11-slim@sha256:193fdd0bbcb3d2ae612bd6cc3548d2f7c78d65b549fcaa8af75624c47474444d
#7 DONE 0.0s

#8 [internal] load build context
#8 transferring context: 1.09GB 5.1s
#8 transferring context: 1.66GB 7.9s done
#8 DONE 8.0s

#9 [builder 3/4] COPY requirements.txt .
#9 CACHED

#10 [builder 4/4] RUN python -m venv . && . /opt/venv/bin/activate && pip install --no-cache-dir -r requirements.txt
#10 CACHED

#11 [stage-1 4/6] WORKDIR /home/appuser
#11 CACHED

#12 [stage-1 3/6] RUN useradd --create-home --shell /bin/bash appuser
#12 CACHED

#13 [builder 2/4] WORKDIR /opt/venv
#13 CACHED

#14 [stage-1 2/6] RUN apt-get update && apt-get install -y --no-install-recommends     ffmpeg     && rm -rf /var/lib/apt/lists/*
#14 CACHED

#15 [stage-1 5/6] COPY --from=builder /opt/venv /opt/venv
#15 CACHED

#16 [stage-1 6/6] COPY app/ ./app
#16 CACHED

#17 exporting to image
#17 exporting layers done
#17 writing image sha256:6cac7caac7fda2808672ad2f3d117d46d38c1d93013867858543ec74917857b7 done
#17 naming to docker.io/library/audioenginehub-app done
#17 DONE 0.0s

#18 resolving provenance for metadata file
#18 DONE 0.0s for reliable port detection.
- **Update Documentation:**
    - Replaced the outdated  (which contained old source code) with a comprehensive guide covering setup, usage, and  commands.
    - Added a note to  to clarify that it describes an older, more advanced setup, pointing readers to the new  for the current recommended workflow.

These changes address the service startup failures and significantly improve the project's usability and maintainability.
2025-12-04 17:33:44 +01:00
21cdc65ade first commit 2025-12-04 11:58:36 +01:00