From eed26b55e4bc18d95168ae2a99a65a75750d4ffb Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Fri, 17 Jul 2026 09:59:03 +0100 Subject: [PATCH 01/10] ci: add per-engine CI lanes for parakeet-cpp and tts-cpp + repo-reorg QIP (PR 0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nothing in this repo's CI built or tested our engines until now — real verification happened three repos downstream in tetherto/qvac. This adds path-filtered workflows that, per PR: - build qvac-ext-ggml@speech (CPU-only, cached by branch-tip SHA — the same fork the ggml-speech vcpkg port ships) - build each engine + all test harnesses against it as system ggml - run the non-GPU ctest lanes (`-LE 'gpu|perf'`); model-dependent tests auto-DISABLE to "Not Run" per the existing harness design Validated locally on macOS arm64: tts lane 68/68 pass, parakeet lane green (1 runnable test model-free; parity suites need staged GGUF fixtures — follow-up documented in the QIP). GPU lanes are stubbed behind workflow_dispatch until self-hosted GPU runners exist. docs/QIP-speech-repo-reorg.md is the reorg proposal this is "PR 0" of (symmetric engines/ layout, upstream vendored as a minimally-divergent git subtree under third_party/). The workflows land against today's paths; the reorg PRs only touch the path filters. Co-Authored-By: Claude Fable 5 --- .github/workflows/parakeet-ci.yml | 128 ++++++++++++++++++++++ .github/workflows/tts-ci.yml | 128 ++++++++++++++++++++++ docs/QIP-speech-repo-reorg.md | 176 ++++++++++++++++++++++++++++++ 3 files changed, 432 insertions(+) create mode 100644 .github/workflows/parakeet-ci.yml create mode 100644 .github/workflows/tts-ci.yml create mode 100644 docs/QIP-speech-repo-reorg.md diff --git a/.github/workflows/parakeet-ci.yml b/.github/workflows/parakeet-ci.yml new file mode 100644 index 00000000000..311e93b3fcd --- /dev/null +++ b/.github/workflows/parakeet-ci.yml @@ -0,0 +1,128 @@ +# CI for the parakeet engine (parakeet-cpp/ — engines/parakeet/ after the +# repo reorg QIP lands; update the path filters below when it does). +# +# Scope (QIP "PR 0" lane): build the engine + every test harness against +# system ggml (qvac-ext-ggml @ speech, the same fork the ggml-speech vcpkg +# port ships), then run the non-GPU ctest suites. Tests whose model/reference +# fixtures aren't present are registered as DISABLED by the CMakeLists and +# show up as "Not Run" — the lane stays green with the committed fixtures +# only. GPU suites (`ctest -L gpu`) need real GPUs → self-hosted lane, see +# the gpu job stub at the bottom. +name: parakeet CI + +on: + push: + branches: [master] + paths: + - 'parakeet-cpp/**' + - '.github/workflows/parakeet-ci.yml' + pull_request: + paths: + - 'parakeet-cpp/**' + - '.github/workflows/parakeet-ci.yml' + workflow_dispatch: + inputs: + run_gpu: + description: 'Also run the GPU ctest lane (needs a [self-hosted, gpu] runner)' + type: boolean + default: false + +permissions: + contents: read + +concurrency: + group: parakeet-ci-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +env: + GGML_REPO: https://github.com/tetherto/qvac-ext-ggml.git + GGML_BRANCH: speech # keep in sync with parakeet-cpp/scripts/setup-ggml.sh + +jobs: + build-test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, macos-14] + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + + - name: Install ccache + run: | + if [ "$RUNNER_OS" = "macOS" ]; then brew install ccache; else sudo apt-get update -q && sudo apt-get install -y ccache; fi + echo "CCACHE_DIR=${{ github.workspace }}/.ccache" >> "$GITHUB_ENV" + + - name: Resolve ggml pin (tip of ${{ env.GGML_BRANCH }}) + id: ggml + run: echo "sha=$(git ls-remote "$GGML_REPO" "refs/heads/$GGML_BRANCH" | cut -f1)" >> "$GITHUB_OUTPUT" + + - name: Cache ggml install + id: ggml-cache + uses: actions/cache@v4 + with: + path: ggml-install + key: ggml-install-${{ matrix.os }}-${{ steps.ggml.outputs.sha }} + + - name: Cache ccache + uses: actions/cache@v4 + with: + path: .ccache + key: ccache-parakeet-${{ matrix.os }}-${{ github.sha }} + restore-keys: ccache-parakeet-${{ matrix.os }}- + + # CPU-only ggml: this lane runs `-LE gpu` tests, and hosted runners + # have no Vulkan/OpenCL; Metal is exercised by the gpu lane instead. + - name: Build ggml (system ggml, qvac-ext-ggml@${{ env.GGML_BRANCH }}) + if: steps.ggml-cache.outputs.cache-hit != 'true' + run: | + git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + git -C ggml-src checkout ${{ steps.ggml.outputs.sha }} || true + cmake -S ggml-src -B ggml-src/build \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=ON \ + -DGGML_METAL=OFF \ + -DGGML_BUILD_TESTS=OFF \ + -DGGML_BUILD_EXAMPLES=OFF \ + -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" + cmake --build ggml-src/build -j4 + cmake --install ggml-src/build + + - name: Configure + run: | + cmake -S parakeet-cpp -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DPARAKEET_USE_SYSTEM_GGML=ON \ + -DPARAKEET_BUILD_TESTS=ON \ + -DCMAKE_PREFIX_PATH="$PWD/ggml-install" + + - name: Build + run: cmake --build build -j4 + + # Excludes gpu (no GPU on hosted runners) and perf (timing gates are + # meaningless on shared runners). Model-dependent tests are DISABLED + # at configure time when fixtures are absent and report as "Not Run". + - name: Test (non-GPU) + run: ctest --test-dir build -LE 'gpu|perf' --output-on-failure --timeout 600 + + # GPU lane stub: opt-in until self-hosted GPU runners exist. Trial note: + # hosted macos-14 exposes Metal, so moving `-L gpu` into the macOS + # build-test job is a cheap first experiment. + gpu: + if: github.event_name == 'workflow_dispatch' && inputs.run_gpu + runs-on: [self-hosted, gpu] + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + - name: Build ggml + engine (native backends) and run GPU suites + run: | + git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + cmake -S ggml-src -B ggml-src/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" + cmake --build ggml-src/build -j && cmake --install ggml-src/build + cmake -S parakeet-cpp -B build -DCMAKE_BUILD_TYPE=Release \ + -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=ON \ + -DCMAKE_PREFIX_PATH="$PWD/ggml-install" + cmake --build build -j + ctest --test-dir build -L gpu --output-on-failure --timeout 1200 diff --git a/.github/workflows/tts-ci.yml b/.github/workflows/tts-ci.yml new file mode 100644 index 00000000000..9293dc938af --- /dev/null +++ b/.github/workflows/tts-ci.yml @@ -0,0 +1,128 @@ +# CI for the TTS engines (tts-cpp/ — engines/tts/ after the repo reorg QIP +# lands; update the path filters below when it does). +# +# Scope (QIP "PR 0" lane): build chatterbox + supertonic + lavasr and every +# test harness against system ggml (qvac-ext-ggml @ speech — mandatory here: +# TTS_CPP_USE_SYSTEM_GGML defaults ON and the bundled path is rejected in +# this tree), then run the non-GPU ctest suites (~68 pass with committed +# fixtures; model-dependent ones auto-DISABLE to "Not Run"). GPU suites need +# real GPUs → self-hosted lane, see the gpu job stub at the bottom. +name: tts CI + +on: + push: + branches: [master] + paths: + - 'tts-cpp/**' + - '.github/workflows/tts-ci.yml' + pull_request: + paths: + - 'tts-cpp/**' + - '.github/workflows/tts-ci.yml' + workflow_dispatch: + inputs: + run_gpu: + description: 'Also run the GPU ctest lane (needs a [self-hosted, gpu] runner)' + type: boolean + default: false + +permissions: + contents: read + +concurrency: + group: tts-ci-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +env: + GGML_REPO: https://github.com/tetherto/qvac-ext-ggml.git + GGML_BRANCH: speech # single ggml pin shared with parakeet-ci.yml + +jobs: + build-test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, macos-14] + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + + - name: Install ccache + run: | + if [ "$RUNNER_OS" = "macOS" ]; then brew install ccache; else sudo apt-get update -q && sudo apt-get install -y ccache; fi + echo "CCACHE_DIR=${{ github.workspace }}/.ccache" >> "$GITHUB_ENV" + + - name: Resolve ggml pin (tip of ${{ env.GGML_BRANCH }}) + id: ggml + run: echo "sha=$(git ls-remote "$GGML_REPO" "refs/heads/$GGML_BRANCH" | cut -f1)" >> "$GITHUB_OUTPUT" + + - name: Cache ggml install + id: ggml-cache + uses: actions/cache@v4 + with: + path: ggml-install + key: ggml-install-${{ matrix.os }}-${{ steps.ggml.outputs.sha }} + + - name: Cache ccache + uses: actions/cache@v4 + with: + path: .ccache + key: ccache-tts-${{ matrix.os }}-${{ github.sha }} + restore-keys: ccache-tts-${{ matrix.os }}- + + # CPU-only ggml: this lane runs `-LE gpu` tests, and hosted runners + # have no Vulkan/OpenCL; Metal is exercised by the gpu lane instead. + # Cache key is shared with parakeet-ci.yml so whichever lane builds + # first serves both. + - name: Build ggml (system ggml, qvac-ext-ggml@${{ env.GGML_BRANCH }}) + if: steps.ggml-cache.outputs.cache-hit != 'true' + run: | + git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + git -C ggml-src checkout ${{ steps.ggml.outputs.sha }} || true + cmake -S ggml-src -B ggml-src/build \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=ON \ + -DGGML_METAL=OFF \ + -DGGML_BUILD_TESTS=OFF \ + -DGGML_BUILD_EXAMPLES=OFF \ + -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" + cmake --build ggml-src/build -j4 + cmake --install ggml-src/build + + - name: Configure + run: | + cmake -S tts-cpp -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DTTS_CPP_BUILD_TESTS=ON \ + -DCMAKE_PREFIX_PATH="$PWD/ggml-install" + + - name: Build + run: cmake --build build -j4 + + # Excludes gpu (no GPU on hosted runners) and perf (timing gates are + # meaningless on shared runners). Model-dependent tests are DISABLED + # at configure time when fixtures are absent and report as "Not Run". + - name: Test (non-GPU) + run: ctest --test-dir build -LE 'gpu|perf' --output-on-failure --timeout 600 + + # GPU lane stub: opt-in until self-hosted GPU runners exist. Trial note: + # hosted macos-14 exposes Metal, so moving `-L gpu` / the mtl-* suites + # into the macOS build-test job is a cheap first experiment. + gpu: + if: github.event_name == 'workflow_dispatch' && inputs.run_gpu + runs-on: [self-hosted, gpu] + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + - name: Build ggml + engine (native backends) and run GPU suites + run: | + git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + cmake -S ggml-src -B ggml-src/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" + cmake --build ggml-src/build -j && cmake --install ggml-src/build + cmake -S tts-cpp -B build -DCMAKE_BUILD_TYPE=Release \ + -DTTS_CPP_BUILD_TESTS=ON \ + -DCMAKE_PREFIX_PATH="$PWD/ggml-install" + cmake --build build -j + ctest --test-dir build -L gpu --output-on-failure --timeout 1200 diff --git a/docs/QIP-speech-repo-reorg.md b/docs/QIP-speech-repo-reorg.md new file mode 100644 index 00000000000..4a07a3354f3 --- /dev/null +++ b/docs/QIP-speech-repo-reorg.md @@ -0,0 +1,176 @@ +# QIP: Reorganize `qvac-ext-lib-whisper.cpp` into a symmetric multi-engine speech repo + +| | | +|---|---| +| **Status** | Draft — for approval | +| **Owner** | Omar Gad | +| **Date** | 2026-07-17 | +| **Repo** | `tetherto/qvac-ext-lib-whisper.cpp` | +| **Related** | Ticket 2 (`transcription-ggml` NPM pkg), Ticket 4 (umbrella vcpkg port), repo rename (deferred) | + +## Summary + +Restructure the repo into a symmetric layout: upstream `whisper.cpp` vendored under `third_party/whisper.cpp/` via **git subtree**, our engines under `engines/{whisper,parakeet,tts}` (future: `engines/qwen-asr`), and a feature-gated umbrella `CMakeLists.txt` at the root that we own. Alongside the reorg, stand up **in-repo CI** that builds each engine and runs its existing `ctest` suites, so the team stops depending on the 3-PR downstream chain (`repo → registry → qvac`) for basic verification. + +One material amendment to the original plan: the vendored tree cannot be "pristine, never hand-edited" — **we already carry ~374 lines of patches on upstream files** (see [Audit findings](#audit-findings)). The policy is amended to *upstream-tracking, minimally divergent*, with a committed patch manifest and a CI guard that enforces the divergence stays declared and minimal. + +## Problem + +Our C++ speech engines live in asymmetric, hard-to-extend places: + +- Upstream `whisper.cpp` sits at the repo **root**, interleaved with our build glue, org workflows, and patches — there is no boundary between "upstream" and "ours". +- `parakeet-cpp/` and `tts-cpp/` are isolated sibling folders with their own conventions, not built or tested by anything in this repo's CI. +- Upstream now ships **its own `parakeet`** (`src/parakeet.cpp`, `include/parakeet.h`, C API `parakeet_*`) as of upstream PR #3735 / v1.9.1 — the root tree is no longer even purely "whisper", and it name-collides conceptually with our `parakeet-cpp` (C++ `namespace parakeet`). +- Upstream syncs are a manual squashed re-apply of the whole tree (commit `cb91a378`, single parent). Every sync re-resolves *all* of our divergence by hand instead of only the files we actually touch. +- There is no clean home for future engines (`qwen-asr`). +- **No CI in this repo exercises our engines.** The active workflows are upstream's build matrix (partially adapted in QVAC-19386) plus org-wide `check-approvals` / `security-baseline`. Real verification of parakeet/tts happens three repos downstream in `tetherto/qvac` (`on-pr-tts-ggml`), behind a registry pin bump and a `verified` label — a multi-day loop for changes that a `ctest` run would catch in minutes. + +## Audit findings + +Facts verified against the repo on 2026-07-17 that correct assumptions in the original draft: + +1. **The root tree is a fork, not a vendored copy.** Diff vs the upstream `v1.9.1` tag on upstream-owned paths: `src/whisper.cpp` +205 lines (vocab-logits slice, decoder QKV fusion — QVAC-21623), `include/whisper.h` +4, `src/whisper-logits-slice.h` (new), `ggml/src/ggml-backend-reg.cpp` +91, `ggml/src/ggml-vulkan/ggml-vulkan.cpp` +44, plus CMake glue — ~374 lines total. The v1.9.1 sync commit itself (`cb91a378`) carried ~278 of these forward. Any "never edit `third_party/`" rule is dead on arrival unless these patches get an explicit home. +2. **Canonical ggml is not in this repo.** Production builds consume the `ggml-speech` vcpkg port, built from the `qvac-ext-ggml` repo's `speech` branch. `tts-cpp` already *requires* system ggml in-tree (`TTS_CPP_USE_SYSTEM_GGML=ON`, bundled path rejected at configure time). The in-repo `ggml/` patches therefore only affect standalone dev builds — they duplicate (and can skew from) `qvac-ext-ggml/speech`. +3. **`git subtree add` cannot be applied to the existing tree directly** — the upstream files already exist at root with local modifications, and `git subtree pull` requires prior subtree metadata. The migration needs an explicit conversion step (recipe below). +4. **Both engines already have real, CI-ready test suites**: `parakeet-cpp/test` (19 harnesses: parity, streaming, determinism, perf regression) and `tts-cpp/test` (17+ harnesses), wired into `ctest` with **labels separating GPU and perf tests from the rest** (`ctest -LE 'gpu|perf'` is the hosted-runner lane). Fixtures are small (13 MB + 40 KB); tests whose model/reference files are absent auto-register as `DISABLED`, so a model-free run is still green. +5. Upstream's `.github/workflows` currently run on our repo. Moving the upstream tree under `third_party/` makes them inert automatically (GitHub only reads the root `.github/`) — a benefit, but it means we **must** ship replacement CI in the same change, or we lose the whisper build coverage `build.yml` provides today. +6. Minor: an `upstream` remote *is* configured in working clones; what's missing is scripted/documented sync, not the remote. + +## Decision + +Adopt **Model B (symmetric layout, upstream as git subtree)** with the amendments below. + +### Target layout + +``` +qvac-ext-lib-whisper.cpp/ (rename deferred — see Out of scope) + CMakeLists.txt # umbrella superbuild, feature-gated; ours + cmake/ # shared toolchain/helper modules; ours + .github/workflows/ # OUR CI only (upstream's becomes inert under third_party/) + docs/ + third_party/ + whisper.cpp/ # upstream via git subtree; minimally divergent (see policy) + PATCHES.md # manifest of every QVAC delta vs the pinned upstream tag + engines/ + whisper/ # thin adapter/glue over third_party (see Open decisions) + parakeet/ # git mv from parakeet-cpp/ + tts/ # git mv from tts-cpp/ (chatterbox + supertonic + lavasr) + qwen-asr/ # future +``` + +### Divergence policy for `third_party/whisper.cpp` (amendment) + +*Upstream-tracking, minimally divergent* — not "pristine": + +- Upstream lands via `git subtree pull --prefix third_party/whisper.cpp upstream --squash`. Subtree does a real 3-way merge, so conflicts occur **only on the handful of files we touch** (today: `src/whisper.cpp`, `src/CMakeLists.txt`, `include/whisper.h`), instead of today's whole-tree re-apply. +- Every QVAC change inside the prefix must be listed in `third_party/whisper.cpp/PATCHES.md` (file, ticket, rationale) and marked in code with `// QVAC:` comments where practical. +- **A CI guard job diffs the subtree against the pinned upstream tag and fails if any file outside the manifest differs.** This is what actually keeps divergence honest — not a convention in a doc. +- **ggml divergence is banned in this repo.** All ggml patches go to `qvac-ext-ggml` (`speech` branch), which feeds the `ggml-speech` port. The umbrella build forces system ggml (`WHISPER_USE_SYSTEM_GGML=ON` and the engines' equivalents), so the vendored `ggml/` is never compiled in our builds. The existing in-tree `ggml-backend-reg.cpp` / `ggml-vulkan.cpp` deltas must be confirmed present in `qvac-ext-ggml/speech` (or ported there) during migration, then dropped from the subtree. +- Whisper-core patches should be considered for upstreaming when generic; QVAC-specific ones (logits slice, QKV fusion) stay in the manifest. +- Upstream's `parakeet` (C API `parakeet_*`) is **not built** by the umbrella (feature-gated off) to avoid confusion with `engines/parakeet` (C++ `namespace parakeet`). Documented in `PATCHES.md` prose. + +### Umbrella build + +Root `CMakeLists.txt` (ours, from scratch — the current root one is upstream's with edits): + +```cmake +option(SPEECH_BUILD_WHISPER "Build the whisper engine" ON) +option(SPEECH_BUILD_PARAKEET "Build the parakeet engine" ON) +option(SPEECH_BUILD_TTS "Build the TTS engines" ON) +option(SPEECH_BUILD_TESTS "Build engine test harnesses" OFF) +``` + +- One `find_package(ggml CONFIG REQUIRED)` resolved from the `ggml-speech` port; all engines link the same ggml (already validated for whisper + parakeet). +- Each engine remains independently configurable standalone (their own `CMakeLists.txt` keep working) — the umbrella is additive, so per-engine vcpkg ports keep functioning until the umbrella port (Ticket 4) replaces them. + +## Migration plan + +Ordered to de-risk: CI first (so the moves are protected), then pure renames (reviewable as renames), then the vendor conversion. + +**PR 0 — CI scaffold (do now, before any reorg).** See [CI & testing](#ci--testing). Lands against current paths (`parakeet-cpp/`, `tts-cpp/`); the path updates in later PRs are one-line changes. + +**PR 1 — engine moves (rename-only).** +- `git mv parakeet-cpp engines/parakeet` and `git mv tts-cpp engines/tts` in a commit containing *no content changes*, so Git records pure renames and `git log --follow` / blame survive. Any path-string fixups (docs, scripts, CI paths) go in a separate follow-up commit in the same PR. +- Coordinate with the registry: the `parakeet-cpp` / `tts-cpp` vcpkg ports reference these paths, so the next pin bump after this PR must carry the port-side path updates (normal 3-PR propagation). + +**PR 2 — vendor conversion.** `git subtree add` can't target a prefix whose files already exist, so the conversion is: +1. `git rm -r` the upstream-owned root paths (`src/ include/ ggml/ examples/ bindings/ ci/ models/ samples/ grammars/ tests/ scripts/ Makefile …`). +2. `git subtree add --prefix third_party/whisper.cpp upstream v1.9.1 --squash` — creates proper subtree metadata so future `git subtree pull` works. +3. Re-apply our whisper delta as **one commit** ("QVAC patches on vendored whisper.cpp", cherry-picked from the pre-conversion tree) + commit `PATCHES.md`. One auditable divergence commit; the ggml deltas are *not* re-applied (routed to `qvac-ext-ggml` instead, verified first). +4. Add the new root umbrella `CMakeLists.txt` + prune root `.github/workflows` down to our own. +- Trade-off, stated plainly: blame *inside* the vendored tree points at the squash commit rather than per-line upstream history (acceptable for vendored code — upstream history lives upstream); our delta stays visible as its own commit + manifest. + +**PR 3 — sync docs + guard.** `docs/UPSTREAM-SYNC.md` (the subtree pull runbook: remote setup, `git subtree pull … --squash`, expected conflict files, post-pull checklist incl. re-verifying `PATCHES.md`), plus the CI divergence-guard job. + +**Freeze window:** PRs 1–2 rewrite most paths; land them back-to-back with open feature branches rebased immediately after (renames make `git rebase` handle it mostly automatically, but coordinate in the team channel). + +## CI & testing + +### What we can stand up now (PR 0, pre-reorg) + +Everything below runs against the engines as they exist today; the reorg only changes path filters. + +**`parakeet-ci.yml` / `tts-ci.yml`** — per-PR, path-filtered, no third-party actions beyond `actions/checkout` + `actions/cache`. *Validated end-to-end locally (macOS arm64): both engines build against a CPU-only system ggml and the test lanes pass — tts 68/68, parakeet 1 runnable (rest auto-`DISABLED`, see below).* + +| Job | Runner | What it does | +|---|---|---| +| `parakeet build-test` | `ubuntu-24.04`, `macos-14` | Build `qvac-ext-ggml@speech` (CPU-only, shared cache keyed by branch SHA) → configure `PARAKEET_USE_SYSTEM_GGML=ON` + `PARAKEET_BUILD_TESTS=ON` → build → `ctest -LE 'gpu\|perf'` | +| `tts build-test` | same | Same ggml install → `TTS_CPP_BUILD_TESTS=ON` (system ggml already mandatory in-tree) → `ctest -LE 'gpu\|perf'` — 68 tests pass model-free today | +| `gpu` (both files) | `[self-hosted, gpu]` | Stub behind `workflow_dispatch` input until runners exist; runs `ctest -L gpu` | + +- **Test filter:** the suites label tests `unit`/`fixture`/`cpu`/`gpu`/`perf`/`mtl-*`; the CI lane runs `-LE 'gpu|perf'` (GPU absent on hosted runners, perf gates meaningless on shared ones). +- **Path filters:** `parakeet-cpp/**` and `tts-cpp/**` respectively (post-reorg: `engines/parakeet/**`, `engines/tts/**`; `third_party/**` → all). +- **ggml provisioning:** both repos are public, so CI builds `qvac-ext-ggml@speech` directly (shallow clone, `actions/cache` on the install dir keyed by the branch tip SHA) — no vcpkg/registry auth in the loop. This *is* the production ggml source (`ggml-speech` port ships the same branch). The vcpkg overlay-pin variant moves to the port-smoke follow-up. +- **Models/fixtures:** committed fixtures are tiny (13 MB parakeet, 40 KB tts) and drive the lane above. The parity suites need converted GGUFs — `download-all-models.sh` pulls **~14.5 GiB of `.nemo` checkpoints requiring Python conversion**, which is not CI-viable. Both harnesses already accept pre-staged fixture roots (`PARAKEET_TEST_{MODEL,REF}_DIR` cache paths) and auto-`DISABLE` (→ "Not Run") when files are absent, so the enablement path is clear: host the small q8_0 GGUFs + `.npy` reference dumps on HF/S3 and restore them via `actions/cache` (follow-up, not PR 0). + +**`port-smoke.yml`** (follow-up to PR 0 — needs the registry portfiles as input) — packages repo HEAD as a vcpkg source tarball (codeload-style) into overlay ports for `parakeet-cpp`/`tts-cpp` and builds a minimal consumer. Catches "the port will break" *before* the registry PR, removing the most common failure of the 3-PR chain. + +**Whisper build job** — deferred to PR 2: upstream's (adapted) `build.yml` still runs at root today, so adding another whisper build now would duplicate it. PR 2 replaces it with a targeted build + `whisper-cli` smoke job when the upstream workflows go inert. + +**GPU lane (deferred, documented):** `ctest -L gpu` (`test_vk_vs_cpu`, `test_metal_ops`, Adreno/Mali suites) needs self-hosted runners with real GPUs. Scaffold the job behind a `workflow_dispatch` + `runs-on: [self-hosted, gpu]` label now, leave it manual until runners exist. Hosted `macos-14` runners do expose Metal, so `ctest -L gpu` on the macOS jobs can be trialled cheaply first. + +### What the reorg adds (PR 2/3) + +- **Umbrella job:** configure the root superbuild with all engines ON — proves the "one ggml, all engines" invariant on every PR that touches shared surface. +- **Divergence guard:** checks out the pinned upstream tag, diffs against `third_party/whisper.cpp`, fails if files outside `PATCHES.md` differ. Runs only when `third_party/**` changes. +- **Upstream CI noise gone:** upstream's workflows move under `third_party/` and stop executing; root `.github/workflows` contains only ours + org baselines. + +### What stays downstream + +`tetherto/qvac` e2e (`on-pr-tts-ggml`) remains the integration gate — this QIP doesn't replace it, it front-loads the failures that today only surface there. + +## Alternatives considered + +1. **Keep separate folders/repos + per-engine ports** — perpetuates version skew (whisper@one commit vs parakeet@another) and the asymmetry this QIP exists to remove. +2. **`git submodule` for upstream** — incompatible with vcpkg (`vcpkg_from_github` uses source tarballs, which exclude submodule content). Subtree content is baked into the tarball. +3. **Plain `git merge -X subtree=…` of upstream into the prefix** — works mechanically but leaves no subtree metadata and makes the pin implicit; `git subtree --squash` gives an explicit, greppable pin commit per sync. +4. **Truly pristine subtree + patch files applied at build time** (`engines/whisper/patches/*.patch`) — keeps the vendored tree byte-identical, but wrecks day-to-day DX (IDE navigation, debugging, blame all see un-patched sources), complicates the vcpkg port, and turns every upstream sync into patch-fuzz whack-a-mole. Rejected in favor of the minimally-divergent policy + CI guard. +5. **Pristine subtree + all our logic in an adapter layer** — impossible for the existing patches: QKV fusion and logits-slice modify whisper's internal graph construction; there is no seam an adapter could hook. + +## Consequences + +1. Symmetric engine layout; upstream pulls become 3-way merges touching ~3 known files instead of whole-tree re-applies; one in-repo upstream pin shared by all engines. +2. Engine regressions surface on the PR in minutes (`ctest -L cpu`) instead of days later in `qvac` e2e. +3. Divergence from upstream is explicit (manifest + guard) instead of implicit (scattered through a root tree that looks upstream-owned). +4. ggml patching gets a single home (`qvac-ext-ggml/speech`), removing today's silent two-copy skew. +5. Costs: blame inside the vendored tree coarsens to the squash/sync commits; a one-time freeze window for the moves; registry ports need a coordinated path bump; the team must learn one rule — *"don't touch `third_party/` outside a sync or manifest PR"* — with CI enforcing it. + +## Out of scope + +1. Repo rename to `qvac-fabric-speech.cpp` (tracked separately). +2. The umbrella vcpkg port (Ticket 4) — enabled by this reorg, delivered separately. +3. `transcription-ggml` NPM package + SDK changes (Ticket 2). +4. GPU self-hosted runner procurement (scaffolded, not delivered). + +## Open decisions + +1. **`engines/whisper/` adapter vs consuming `third_party/` directly.** Recommendation: create `engines/whisper/` now but keep it *thin* — the umbrella-facing CMake target, QVAC-side glue/headers, and the natural future home for whisper-adjacent code that would otherwise grow the `PATCHES.md`. Core patches stay in the subtree. +2. **`engines/qwen-asr/` scaffolding now vs at implementation time.** Recommendation: a README stub only; empty scaffolds rot. + +## Approvals + +| Reviewer | Role | Status | +|---|---|---| +| _TBD_ | Speech team lead | ☐ | +| _TBD_ | Infra/registry owner | ☐ | +| _TBD_ | Downstream (qvac) owner | ☐ | From 97e8ab04f232bb8c513b4bdec997beeafda8c70d Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Fri, 17 Jul 2026 10:04:47 +0100 Subject: [PATCH 02/10] fix(tts): link backend_selection.cpp into campplus test targets; move QIP to #94 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First run of the new tts CI lane caught a real cross-platform bug: test-campplus and test-campplus-backward-parity compile src/campplus.cpp (which calls tts_cpp::detail::init_cpu_backend()) without src/backend_selection.cpp, where that symbol lives. Apple's toolchain happened to optimize the reference away; GNU ld on Linux fails with an undefined reference — and Linux-with-tests was never built by any CI until now. Mirror the source list test-voice-embedding already uses. Also drop docs/QIP-speech-repo-reorg.md from this branch — the QIP now has its own approval PR (#94); this PR is CI + fixes only. Co-Authored-By: Claude Fable 5 --- docs/QIP-speech-repo-reorg.md | 176 ---------------------------------- tts-cpp/CMakeLists.txt | 6 +- 2 files changed, 4 insertions(+), 178 deletions(-) delete mode 100644 docs/QIP-speech-repo-reorg.md diff --git a/docs/QIP-speech-repo-reorg.md b/docs/QIP-speech-repo-reorg.md deleted file mode 100644 index 4a07a3354f3..00000000000 --- a/docs/QIP-speech-repo-reorg.md +++ /dev/null @@ -1,176 +0,0 @@ -# QIP: Reorganize `qvac-ext-lib-whisper.cpp` into a symmetric multi-engine speech repo - -| | | -|---|---| -| **Status** | Draft — for approval | -| **Owner** | Omar Gad | -| **Date** | 2026-07-17 | -| **Repo** | `tetherto/qvac-ext-lib-whisper.cpp` | -| **Related** | Ticket 2 (`transcription-ggml` NPM pkg), Ticket 4 (umbrella vcpkg port), repo rename (deferred) | - -## Summary - -Restructure the repo into a symmetric layout: upstream `whisper.cpp` vendored under `third_party/whisper.cpp/` via **git subtree**, our engines under `engines/{whisper,parakeet,tts}` (future: `engines/qwen-asr`), and a feature-gated umbrella `CMakeLists.txt` at the root that we own. Alongside the reorg, stand up **in-repo CI** that builds each engine and runs its existing `ctest` suites, so the team stops depending on the 3-PR downstream chain (`repo → registry → qvac`) for basic verification. - -One material amendment to the original plan: the vendored tree cannot be "pristine, never hand-edited" — **we already carry ~374 lines of patches on upstream files** (see [Audit findings](#audit-findings)). The policy is amended to *upstream-tracking, minimally divergent*, with a committed patch manifest and a CI guard that enforces the divergence stays declared and minimal. - -## Problem - -Our C++ speech engines live in asymmetric, hard-to-extend places: - -- Upstream `whisper.cpp` sits at the repo **root**, interleaved with our build glue, org workflows, and patches — there is no boundary between "upstream" and "ours". -- `parakeet-cpp/` and `tts-cpp/` are isolated sibling folders with their own conventions, not built or tested by anything in this repo's CI. -- Upstream now ships **its own `parakeet`** (`src/parakeet.cpp`, `include/parakeet.h`, C API `parakeet_*`) as of upstream PR #3735 / v1.9.1 — the root tree is no longer even purely "whisper", and it name-collides conceptually with our `parakeet-cpp` (C++ `namespace parakeet`). -- Upstream syncs are a manual squashed re-apply of the whole tree (commit `cb91a378`, single parent). Every sync re-resolves *all* of our divergence by hand instead of only the files we actually touch. -- There is no clean home for future engines (`qwen-asr`). -- **No CI in this repo exercises our engines.** The active workflows are upstream's build matrix (partially adapted in QVAC-19386) plus org-wide `check-approvals` / `security-baseline`. Real verification of parakeet/tts happens three repos downstream in `tetherto/qvac` (`on-pr-tts-ggml`), behind a registry pin bump and a `verified` label — a multi-day loop for changes that a `ctest` run would catch in minutes. - -## Audit findings - -Facts verified against the repo on 2026-07-17 that correct assumptions in the original draft: - -1. **The root tree is a fork, not a vendored copy.** Diff vs the upstream `v1.9.1` tag on upstream-owned paths: `src/whisper.cpp` +205 lines (vocab-logits slice, decoder QKV fusion — QVAC-21623), `include/whisper.h` +4, `src/whisper-logits-slice.h` (new), `ggml/src/ggml-backend-reg.cpp` +91, `ggml/src/ggml-vulkan/ggml-vulkan.cpp` +44, plus CMake glue — ~374 lines total. The v1.9.1 sync commit itself (`cb91a378`) carried ~278 of these forward. Any "never edit `third_party/`" rule is dead on arrival unless these patches get an explicit home. -2. **Canonical ggml is not in this repo.** Production builds consume the `ggml-speech` vcpkg port, built from the `qvac-ext-ggml` repo's `speech` branch. `tts-cpp` already *requires* system ggml in-tree (`TTS_CPP_USE_SYSTEM_GGML=ON`, bundled path rejected at configure time). The in-repo `ggml/` patches therefore only affect standalone dev builds — they duplicate (and can skew from) `qvac-ext-ggml/speech`. -3. **`git subtree add` cannot be applied to the existing tree directly** — the upstream files already exist at root with local modifications, and `git subtree pull` requires prior subtree metadata. The migration needs an explicit conversion step (recipe below). -4. **Both engines already have real, CI-ready test suites**: `parakeet-cpp/test` (19 harnesses: parity, streaming, determinism, perf regression) and `tts-cpp/test` (17+ harnesses), wired into `ctest` with **labels separating GPU and perf tests from the rest** (`ctest -LE 'gpu|perf'` is the hosted-runner lane). Fixtures are small (13 MB + 40 KB); tests whose model/reference files are absent auto-register as `DISABLED`, so a model-free run is still green. -5. Upstream's `.github/workflows` currently run on our repo. Moving the upstream tree under `third_party/` makes them inert automatically (GitHub only reads the root `.github/`) — a benefit, but it means we **must** ship replacement CI in the same change, or we lose the whisper build coverage `build.yml` provides today. -6. Minor: an `upstream` remote *is* configured in working clones; what's missing is scripted/documented sync, not the remote. - -## Decision - -Adopt **Model B (symmetric layout, upstream as git subtree)** with the amendments below. - -### Target layout - -``` -qvac-ext-lib-whisper.cpp/ (rename deferred — see Out of scope) - CMakeLists.txt # umbrella superbuild, feature-gated; ours - cmake/ # shared toolchain/helper modules; ours - .github/workflows/ # OUR CI only (upstream's becomes inert under third_party/) - docs/ - third_party/ - whisper.cpp/ # upstream via git subtree; minimally divergent (see policy) - PATCHES.md # manifest of every QVAC delta vs the pinned upstream tag - engines/ - whisper/ # thin adapter/glue over third_party (see Open decisions) - parakeet/ # git mv from parakeet-cpp/ - tts/ # git mv from tts-cpp/ (chatterbox + supertonic + lavasr) - qwen-asr/ # future -``` - -### Divergence policy for `third_party/whisper.cpp` (amendment) - -*Upstream-tracking, minimally divergent* — not "pristine": - -- Upstream lands via `git subtree pull --prefix third_party/whisper.cpp upstream --squash`. Subtree does a real 3-way merge, so conflicts occur **only on the handful of files we touch** (today: `src/whisper.cpp`, `src/CMakeLists.txt`, `include/whisper.h`), instead of today's whole-tree re-apply. -- Every QVAC change inside the prefix must be listed in `third_party/whisper.cpp/PATCHES.md` (file, ticket, rationale) and marked in code with `// QVAC:` comments where practical. -- **A CI guard job diffs the subtree against the pinned upstream tag and fails if any file outside the manifest differs.** This is what actually keeps divergence honest — not a convention in a doc. -- **ggml divergence is banned in this repo.** All ggml patches go to `qvac-ext-ggml` (`speech` branch), which feeds the `ggml-speech` port. The umbrella build forces system ggml (`WHISPER_USE_SYSTEM_GGML=ON` and the engines' equivalents), so the vendored `ggml/` is never compiled in our builds. The existing in-tree `ggml-backend-reg.cpp` / `ggml-vulkan.cpp` deltas must be confirmed present in `qvac-ext-ggml/speech` (or ported there) during migration, then dropped from the subtree. -- Whisper-core patches should be considered for upstreaming when generic; QVAC-specific ones (logits slice, QKV fusion) stay in the manifest. -- Upstream's `parakeet` (C API `parakeet_*`) is **not built** by the umbrella (feature-gated off) to avoid confusion with `engines/parakeet` (C++ `namespace parakeet`). Documented in `PATCHES.md` prose. - -### Umbrella build - -Root `CMakeLists.txt` (ours, from scratch — the current root one is upstream's with edits): - -```cmake -option(SPEECH_BUILD_WHISPER "Build the whisper engine" ON) -option(SPEECH_BUILD_PARAKEET "Build the parakeet engine" ON) -option(SPEECH_BUILD_TTS "Build the TTS engines" ON) -option(SPEECH_BUILD_TESTS "Build engine test harnesses" OFF) -``` - -- One `find_package(ggml CONFIG REQUIRED)` resolved from the `ggml-speech` port; all engines link the same ggml (already validated for whisper + parakeet). -- Each engine remains independently configurable standalone (their own `CMakeLists.txt` keep working) — the umbrella is additive, so per-engine vcpkg ports keep functioning until the umbrella port (Ticket 4) replaces them. - -## Migration plan - -Ordered to de-risk: CI first (so the moves are protected), then pure renames (reviewable as renames), then the vendor conversion. - -**PR 0 — CI scaffold (do now, before any reorg).** See [CI & testing](#ci--testing). Lands against current paths (`parakeet-cpp/`, `tts-cpp/`); the path updates in later PRs are one-line changes. - -**PR 1 — engine moves (rename-only).** -- `git mv parakeet-cpp engines/parakeet` and `git mv tts-cpp engines/tts` in a commit containing *no content changes*, so Git records pure renames and `git log --follow` / blame survive. Any path-string fixups (docs, scripts, CI paths) go in a separate follow-up commit in the same PR. -- Coordinate with the registry: the `parakeet-cpp` / `tts-cpp` vcpkg ports reference these paths, so the next pin bump after this PR must carry the port-side path updates (normal 3-PR propagation). - -**PR 2 — vendor conversion.** `git subtree add` can't target a prefix whose files already exist, so the conversion is: -1. `git rm -r` the upstream-owned root paths (`src/ include/ ggml/ examples/ bindings/ ci/ models/ samples/ grammars/ tests/ scripts/ Makefile …`). -2. `git subtree add --prefix third_party/whisper.cpp upstream v1.9.1 --squash` — creates proper subtree metadata so future `git subtree pull` works. -3. Re-apply our whisper delta as **one commit** ("QVAC patches on vendored whisper.cpp", cherry-picked from the pre-conversion tree) + commit `PATCHES.md`. One auditable divergence commit; the ggml deltas are *not* re-applied (routed to `qvac-ext-ggml` instead, verified first). -4. Add the new root umbrella `CMakeLists.txt` + prune root `.github/workflows` down to our own. -- Trade-off, stated plainly: blame *inside* the vendored tree points at the squash commit rather than per-line upstream history (acceptable for vendored code — upstream history lives upstream); our delta stays visible as its own commit + manifest. - -**PR 3 — sync docs + guard.** `docs/UPSTREAM-SYNC.md` (the subtree pull runbook: remote setup, `git subtree pull … --squash`, expected conflict files, post-pull checklist incl. re-verifying `PATCHES.md`), plus the CI divergence-guard job. - -**Freeze window:** PRs 1–2 rewrite most paths; land them back-to-back with open feature branches rebased immediately after (renames make `git rebase` handle it mostly automatically, but coordinate in the team channel). - -## CI & testing - -### What we can stand up now (PR 0, pre-reorg) - -Everything below runs against the engines as they exist today; the reorg only changes path filters. - -**`parakeet-ci.yml` / `tts-ci.yml`** — per-PR, path-filtered, no third-party actions beyond `actions/checkout` + `actions/cache`. *Validated end-to-end locally (macOS arm64): both engines build against a CPU-only system ggml and the test lanes pass — tts 68/68, parakeet 1 runnable (rest auto-`DISABLED`, see below).* - -| Job | Runner | What it does | -|---|---|---| -| `parakeet build-test` | `ubuntu-24.04`, `macos-14` | Build `qvac-ext-ggml@speech` (CPU-only, shared cache keyed by branch SHA) → configure `PARAKEET_USE_SYSTEM_GGML=ON` + `PARAKEET_BUILD_TESTS=ON` → build → `ctest -LE 'gpu\|perf'` | -| `tts build-test` | same | Same ggml install → `TTS_CPP_BUILD_TESTS=ON` (system ggml already mandatory in-tree) → `ctest -LE 'gpu\|perf'` — 68 tests pass model-free today | -| `gpu` (both files) | `[self-hosted, gpu]` | Stub behind `workflow_dispatch` input until runners exist; runs `ctest -L gpu` | - -- **Test filter:** the suites label tests `unit`/`fixture`/`cpu`/`gpu`/`perf`/`mtl-*`; the CI lane runs `-LE 'gpu|perf'` (GPU absent on hosted runners, perf gates meaningless on shared ones). -- **Path filters:** `parakeet-cpp/**` and `tts-cpp/**` respectively (post-reorg: `engines/parakeet/**`, `engines/tts/**`; `third_party/**` → all). -- **ggml provisioning:** both repos are public, so CI builds `qvac-ext-ggml@speech` directly (shallow clone, `actions/cache` on the install dir keyed by the branch tip SHA) — no vcpkg/registry auth in the loop. This *is* the production ggml source (`ggml-speech` port ships the same branch). The vcpkg overlay-pin variant moves to the port-smoke follow-up. -- **Models/fixtures:** committed fixtures are tiny (13 MB parakeet, 40 KB tts) and drive the lane above. The parity suites need converted GGUFs — `download-all-models.sh` pulls **~14.5 GiB of `.nemo` checkpoints requiring Python conversion**, which is not CI-viable. Both harnesses already accept pre-staged fixture roots (`PARAKEET_TEST_{MODEL,REF}_DIR` cache paths) and auto-`DISABLE` (→ "Not Run") when files are absent, so the enablement path is clear: host the small q8_0 GGUFs + `.npy` reference dumps on HF/S3 and restore them via `actions/cache` (follow-up, not PR 0). - -**`port-smoke.yml`** (follow-up to PR 0 — needs the registry portfiles as input) — packages repo HEAD as a vcpkg source tarball (codeload-style) into overlay ports for `parakeet-cpp`/`tts-cpp` and builds a minimal consumer. Catches "the port will break" *before* the registry PR, removing the most common failure of the 3-PR chain. - -**Whisper build job** — deferred to PR 2: upstream's (adapted) `build.yml` still runs at root today, so adding another whisper build now would duplicate it. PR 2 replaces it with a targeted build + `whisper-cli` smoke job when the upstream workflows go inert. - -**GPU lane (deferred, documented):** `ctest -L gpu` (`test_vk_vs_cpu`, `test_metal_ops`, Adreno/Mali suites) needs self-hosted runners with real GPUs. Scaffold the job behind a `workflow_dispatch` + `runs-on: [self-hosted, gpu]` label now, leave it manual until runners exist. Hosted `macos-14` runners do expose Metal, so `ctest -L gpu` on the macOS jobs can be trialled cheaply first. - -### What the reorg adds (PR 2/3) - -- **Umbrella job:** configure the root superbuild with all engines ON — proves the "one ggml, all engines" invariant on every PR that touches shared surface. -- **Divergence guard:** checks out the pinned upstream tag, diffs against `third_party/whisper.cpp`, fails if files outside `PATCHES.md` differ. Runs only when `third_party/**` changes. -- **Upstream CI noise gone:** upstream's workflows move under `third_party/` and stop executing; root `.github/workflows` contains only ours + org baselines. - -### What stays downstream - -`tetherto/qvac` e2e (`on-pr-tts-ggml`) remains the integration gate — this QIP doesn't replace it, it front-loads the failures that today only surface there. - -## Alternatives considered - -1. **Keep separate folders/repos + per-engine ports** — perpetuates version skew (whisper@one commit vs parakeet@another) and the asymmetry this QIP exists to remove. -2. **`git submodule` for upstream** — incompatible with vcpkg (`vcpkg_from_github` uses source tarballs, which exclude submodule content). Subtree content is baked into the tarball. -3. **Plain `git merge -X subtree=…` of upstream into the prefix** — works mechanically but leaves no subtree metadata and makes the pin implicit; `git subtree --squash` gives an explicit, greppable pin commit per sync. -4. **Truly pristine subtree + patch files applied at build time** (`engines/whisper/patches/*.patch`) — keeps the vendored tree byte-identical, but wrecks day-to-day DX (IDE navigation, debugging, blame all see un-patched sources), complicates the vcpkg port, and turns every upstream sync into patch-fuzz whack-a-mole. Rejected in favor of the minimally-divergent policy + CI guard. -5. **Pristine subtree + all our logic in an adapter layer** — impossible for the existing patches: QKV fusion and logits-slice modify whisper's internal graph construction; there is no seam an adapter could hook. - -## Consequences - -1. Symmetric engine layout; upstream pulls become 3-way merges touching ~3 known files instead of whole-tree re-applies; one in-repo upstream pin shared by all engines. -2. Engine regressions surface on the PR in minutes (`ctest -L cpu`) instead of days later in `qvac` e2e. -3. Divergence from upstream is explicit (manifest + guard) instead of implicit (scattered through a root tree that looks upstream-owned). -4. ggml patching gets a single home (`qvac-ext-ggml/speech`), removing today's silent two-copy skew. -5. Costs: blame inside the vendored tree coarsens to the squash/sync commits; a one-time freeze window for the moves; registry ports need a coordinated path bump; the team must learn one rule — *"don't touch `third_party/` outside a sync or manifest PR"* — with CI enforcing it. - -## Out of scope - -1. Repo rename to `qvac-fabric-speech.cpp` (tracked separately). -2. The umbrella vcpkg port (Ticket 4) — enabled by this reorg, delivered separately. -3. `transcription-ggml` NPM package + SDK changes (Ticket 2). -4. GPU self-hosted runner procurement (scaffolded, not delivered). - -## Open decisions - -1. **`engines/whisper/` adapter vs consuming `third_party/` directly.** Recommendation: create `engines/whisper/` now but keep it *thin* — the umbrella-facing CMake target, QVAC-side glue/headers, and the natural future home for whisper-adjacent code that would otherwise grow the `PATCHES.md`. Core patches stay in the subtree. -2. **`engines/qwen-asr/` scaffolding now vs at implementation time.** Recommendation: a README stub only; empty scaffolds rot. - -## Approvals - -| Reviewer | Role | Status | -|---|---|---| -| _TBD_ | Speech team lead | ☐ | -| _TBD_ | Infra/registry owner | ☐ | -| _TBD_ | Downstream (qvac) owner | ☐ | diff --git a/tts-cpp/CMakeLists.txt b/tts-cpp/CMakeLists.txt index 23d047cc99b..c0947de4d10 100644 --- a/tts-cpp/CMakeLists.txt +++ b/tts-cpp/CMakeLists.txt @@ -589,7 +589,8 @@ if (TTS_CPP_BUILD_TESTS) add_executable(test-campplus test/test_campplus.cpp - src/campplus.cpp) + src/campplus.cpp + src/backend_selection.cpp) target_link_libraries(test-campplus PRIVATE ggml) target_include_directories(test-campplus PRIVATE ggml/include src) if (OpenMP_CXX_FOUND) @@ -1165,7 +1166,8 @@ if (TTS_CPP_BUILD_TESTS) add_executable(test-campplus-backward-parity test/test_campplus_backward_parity.cpp src/campplus_backward.cpp - src/campplus.cpp) + src/campplus.cpp + src/backend_selection.cpp) target_link_libraries(test-campplus-backward-parity PRIVATE ggml) target_include_directories(test-campplus-backward-parity PRIVATE ggml/include src) if (OpenMP_CXX_FOUND) From e39334b1ebefa22efcee40f1da6781bb940636e4 Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Fri, 17 Jul 2026 10:09:14 +0100 Subject: [PATCH 03/10] ci: export LD_LIBRARY_PATH for the ctest step (transitive ggml .so loads) On ubuntu the test binaries resolve libqvac-speech-ggml.so via their build RUNPATH, but RUNPATH is not consulted for that library's own transitive dependencies (libqvac-speech-ggml-cpu.so.0 et al), so 35 tts tests failed at exec with "cannot open shared object file". macOS is unaffected (@rpath resolution walks the executable's rpath stack for the whole load chain). Point LD_LIBRARY_PATH at the ggml install dir for the ctest step in both lanes. Co-Authored-By: Claude Fable 5 --- .github/workflows/parakeet-ci.yml | 6 ++++++ .github/workflows/tts-ci.yml | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/parakeet-ci.yml b/.github/workflows/parakeet-ci.yml index 311e93b3fcd..b84d15f1446 100644 --- a/.github/workflows/parakeet-ci.yml +++ b/.github/workflows/parakeet-ci.yml @@ -103,7 +103,13 @@ jobs: # Excludes gpu (no GPU on hosted runners) and perf (timing gates are # meaningless on shared runners). Model-dependent tests are DISABLED # at configure time when fixtures are absent and report as "Not Run". + # LD_LIBRARY_PATH: the ggml install ships libqvac-speech-ggml.so whose + # own dependency on the ggml-cpu/base siblings is resolved transitively + # — Linux RUNPATH doesn't apply to transitive loads, so the loader + # needs the directory explicitly (macOS @rpath chains handle it). - name: Test (non-GPU) + env: + LD_LIBRARY_PATH: ${{ github.workspace }}/ggml-install/lib run: ctest --test-dir build -LE 'gpu|perf' --output-on-failure --timeout 600 # GPU lane stub: opt-in until self-hosted GPU runners exist. Trial note: diff --git a/.github/workflows/tts-ci.yml b/.github/workflows/tts-ci.yml index 9293dc938af..9b9f98e5cfb 100644 --- a/.github/workflows/tts-ci.yml +++ b/.github/workflows/tts-ci.yml @@ -103,7 +103,13 @@ jobs: # Excludes gpu (no GPU on hosted runners) and perf (timing gates are # meaningless on shared runners). Model-dependent tests are DISABLED # at configure time when fixtures are absent and report as "Not Run". + # LD_LIBRARY_PATH: the ggml install ships libqvac-speech-ggml.so whose + # own dependency on the ggml-cpu/base siblings is resolved transitively + # — Linux RUNPATH doesn't apply to transitive loads, so the loader + # needs the directory explicitly (macOS @rpath chains handle it). - name: Test (non-GPU) + env: + LD_LIBRARY_PATH: ${{ github.workspace }}/ggml-install/lib run: ctest --test-dir build -LE 'gpu|perf' --output-on-failure --timeout 600 # GPU lane stub: opt-in until self-hosted GPU runners exist. Trial note: From 176336f1b0356984cab1f90c2101d6e6f37dcd6a Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Fri, 17 Jul 2026 10:30:30 +0100 Subject: [PATCH 04/10] ci: add Windows build+test and Android/iOS compile-smoke lanes for the engines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit engines-cross-ci.yml: engine x platform matrix complementing the linux/mac lanes — - windows-2022: MSVC, static system ggml, full build + non-GPU ctest - android: NDK arm64-v8a compile smoke (no device to run tests on) - ios: device arm64 compile smoke, Metal embedded (flags mirror build-xcframework.sh) iOS recipe validated locally (ggml + both engines compile clean against the iphoneos 26.2 SDK). On-device e2e remains downstream in tetherto/qvac; these lanes front-load cross-compile/link breaks ahead of the repo-reorg moves (QIP #94). Co-Authored-By: Claude Fable 5 --- .github/workflows/engines-cross-ci.yml | 215 +++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 .github/workflows/engines-cross-ci.yml diff --git a/.github/workflows/engines-cross-ci.yml b/.github/workflows/engines-cross-ci.yml new file mode 100644 index 00000000000..ba3afd8791b --- /dev/null +++ b/.github/workflows/engines-cross-ci.yml @@ -0,0 +1,215 @@ +# Cross-platform lanes for the engines (parakeet-cpp/, tts-cpp/ — engines/* +# after the repo reorg QIP; update the path filters + SRC map when it lands). +# +# Complements parakeet-ci.yml / tts-ci.yml (linux+mac build+test): +# - windows: full build + non-GPU ctest (MSVC, static ggml) +# - android: compile smoke, arm64-v8a via NDK (no device to run tests on) +# - ios: compile smoke, arm64 device slice, Metal embedded (flags +# mirror build-xcframework.sh) +# On-device e2e stays downstream in tetherto/qvac; these lanes exist to +# catch cross-compile/link breaks *before* the registry pin chain. +name: engines cross CI + +on: + push: + branches: [master] + paths: + - 'parakeet-cpp/**' + - 'tts-cpp/**' + - '.github/workflows/engines-cross-ci.yml' + pull_request: + paths: + - 'parakeet-cpp/**' + - 'tts-cpp/**' + - '.github/workflows/engines-cross-ci.yml' + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: engines-cross-ci-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +env: + GGML_REPO: https://github.com/tetherto/qvac-ext-ggml.git + GGML_BRANCH: speech # single ggml pin shared with parakeet-ci.yml / tts-ci.yml + +jobs: + windows: + strategy: + fail-fast: false + matrix: + engine: [parakeet, tts] + include: + - engine: parakeet + src: parakeet-cpp + cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=ON + - engine: tts + src: tts-cpp + cmake_flags: -DTTS_CPP_BUILD_TESTS=ON + runs-on: windows-2022 + timeout-minutes: 90 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + + - name: Resolve ggml pin (tip of ${{ env.GGML_BRANCH }}) + id: ggml + run: echo "sha=$(git ls-remote "$GGML_REPO" "refs/heads/$GGML_BRANCH" | cut -f1)" >> "$GITHUB_OUTPUT" + + - name: Cache ggml install + id: ggml-cache + uses: actions/cache@v4 + with: + path: ggml-install + key: ggml-install-windows-2022-msvc-static-${{ steps.ggml.outputs.sha }} + + # Static ggml on Windows sidesteps DLL discovery for the test exes. + - name: Build ggml (MSVC, static, CPU-only) + if: steps.ggml-cache.outputs.cache-hit != 'true' + run: | + git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + cmake -S ggml-src -B ggml-src/build -A x64 \ + -DBUILD_SHARED_LIBS=OFF \ + -DGGML_BUILD_TESTS=OFF \ + -DGGML_BUILD_EXAMPLES=OFF \ + -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" + cmake --build ggml-src/build --config Release -j4 + cmake --install ggml-src/build --config Release + + - name: Configure + run: | + cmake -S ${{ matrix.src }} -B build -A x64 \ + ${{ matrix.cmake_flags }} \ + -DCMAKE_PREFIX_PATH="$PWD/ggml-install" + + - name: Build + run: cmake --build build --config Release -j4 + + - name: Test (non-GPU) + run: ctest --test-dir build -C Release -LE 'gpu|perf' --output-on-failure --timeout 600 + + android: + strategy: + fail-fast: false + matrix: + engine: [parakeet, tts] + include: + - engine: parakeet + src: parakeet-cpp + cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=OFF + - engine: tts + src: tts-cpp + cmake_flags: -DTTS_CPP_BUILD_TESTS=OFF + runs-on: ubuntu-24.04 + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + + - name: Resolve ggml pin (tip of ${{ env.GGML_BRANCH }}) + id: ggml + run: echo "sha=$(git ls-remote "$GGML_REPO" "refs/heads/$GGML_BRANCH" | cut -f1)" >> "$GITHUB_OUTPUT" + + - name: Cache ggml install + id: ggml-cache + uses: actions/cache@v4 + with: + path: ggml-install + key: ggml-install-android-arm64-${{ steps.ggml.outputs.sha }} + + - name: Build ggml (NDK arm64-v8a, static, CPU-only) + if: steps.ggml-cache.outputs.cache-hit != 'true' + run: | + git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + cmake -S ggml-src -B ggml-src/build \ + -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake" \ + -DANDROID_ABI=arm64-v8a \ + -DANDROID_PLATFORM=android-28 \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DGGML_OPENMP=OFF \ + -DGGML_BUILD_TESTS=OFF \ + -DGGML_BUILD_EXAMPLES=OFF \ + -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" + cmake --build ggml-src/build -j4 + cmake --install ggml-src/build + + # Compile smoke only: hosted runners can't execute arm64 Android + # binaries. CMAKE_FIND_ROOT_PATH (not PREFIX_PATH) because the NDK + # toolchain restricts find_package() to the find-root. + - name: Configure + build engine (compile smoke) + run: | + cmake -S ${{ matrix.src }} -B build \ + -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake" \ + -DANDROID_ABI=arm64-v8a \ + -DANDROID_PLATFORM=android-28 \ + -DCMAKE_BUILD_TYPE=Release \ + ${{ matrix.cmake_flags }} \ + -DCMAKE_FIND_ROOT_PATH="$PWD/ggml-install" + cmake --build build -j4 + + ios: + strategy: + fail-fast: false + matrix: + engine: [parakeet, tts] + include: + - engine: parakeet + src: parakeet-cpp + cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=OFF + - engine: tts + src: tts-cpp + cmake_flags: -DTTS_CPP_BUILD_TESTS=OFF + runs-on: macos-14 + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + + - name: Resolve ggml pin (tip of ${{ env.GGML_BRANCH }}) + id: ggml + run: echo "sha=$(git ls-remote "$GGML_REPO" "refs/heads/$GGML_BRANCH" | cut -f1)" >> "$GITHUB_OUTPUT" + + - name: Cache ggml install + id: ggml-cache + uses: actions/cache@v4 + with: + path: ggml-install + key: ggml-install-ios-arm64-${{ steps.ggml.outputs.sha }} + + # Flags mirror build-xcframework.sh's iOS-device slice (Metal embedded). + - name: Build ggml (iOS device arm64, static, Metal embedded) + if: steps.ggml-cache.outputs.cache-hit != 'true' + run: | + git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + cmake -S ggml-src -B ggml-src/build \ + -DCMAKE_SYSTEM_NAME=iOS \ + -DCMAKE_OSX_SYSROOT=iphoneos \ + -DCMAKE_OSX_ARCHITECTURES=arm64 \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=16.4 \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DGGML_METAL=ON \ + -DGGML_METAL_EMBED_LIBRARY=ON \ + -DGGML_METAL_USE_BF16=ON \ + -DGGML_OPENMP=OFF \ + -DGGML_BUILD_TESTS=OFF \ + -DGGML_BUILD_EXAMPLES=OFF \ + -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" + cmake --build ggml-src/build -j4 + cmake --install ggml-src/build + + # Compile smoke only (no iOS device on hosted runners). + - name: Configure + build engine (compile smoke) + run: | + cmake -S ${{ matrix.src }} -B build \ + -DCMAKE_SYSTEM_NAME=iOS \ + -DCMAKE_OSX_SYSROOT=iphoneos \ + -DCMAKE_OSX_ARCHITECTURES=arm64 \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=16.4 \ + -DCMAKE_BUILD_TYPE=Release \ + ${{ matrix.cmake_flags }} \ + -DCMAKE_FIND_ROOT_PATH="$PWD/ggml-install" + cmake --build build -j4 From ed1c88da7fa921ea57e7c5fb5c98e4e612539752 Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Fri, 17 Jul 2026 10:31:09 +0100 Subject: [PATCH 05/10] refactor: move parakeet-cpp -> engines/parakeet, tts-cpp -> engines/tts (rename-only) Pure `git mv` with zero content changes so Git records 100% renames and `git log --follow` / blame survive. Establishes the symmetric engines/ layout from the repo-reorg QIP (#94, PR 1); path fixups follow in the next commit. Co-Authored-By: Claude Fable 5 --- {parakeet-cpp => engines/parakeet}/.gitignore | 0 {parakeet-cpp => engines/parakeet}/CMakeLists.txt | 0 {parakeet-cpp => engines/parakeet}/LICENSE | 0 {parakeet-cpp => engines/parakeet}/NOTICE | 0 {parakeet-cpp => engines/parakeet}/PROGRESS.md | 0 {parakeet-cpp => engines/parakeet}/README.md | 0 .../parakeet}/cmake/parakeet-cppConfig.cmake.in | 0 .../parakeet}/examples/live-mic-attributed.cpp | 0 .../parakeet}/examples/live-mic.cpp | 0 .../parakeet}/examples/miniaudio.h | 0 .../parakeet}/examples/miniaudio_impl.cpp | 0 .../parakeet}/include/parakeet/attributed.h | 0 .../parakeet}/include/parakeet/cli.h | 0 .../parakeet}/include/parakeet/diarization.h | 0 .../parakeet}/include/parakeet/engine.h | 0 .../parakeet}/include/parakeet/export.h | 0 .../parakeet}/include/parakeet/log.h | 0 .../parakeet}/include/parakeet/parakeet.h | 0 .../parakeet}/include/parakeet/streaming.h | 0 .../parakeet}/scripts/convert-nemo-to-gguf.py | 0 .../parakeet}/scripts/download-all-models.sh | 0 .../parakeet}/scripts/dump-ctc-reference.py | 0 .../parakeet}/scripts/dump-eou-reference.py | 0 .../parakeet}/scripts/dump-sortformer-reference.py | 0 .../parakeet}/scripts/dump-tdt-reference.py | 0 .../parakeet}/scripts/ref-encoder-from-gguf.py | 0 .../parakeet}/scripts/setup-ggml.sh | 0 .../parakeet}/scripts/streaming-reference.py | 0 .../parakeet}/scripts/verify-gguf-roundtrip.py | 0 .../parakeet}/src/backend_util.h | 0 {parakeet-cpp => engines/parakeet}/src/cli_main.cpp | 0 {parakeet-cpp => engines/parakeet}/src/dr_wav.h | 0 .../parakeet}/src/energy_vad.cpp | 0 {parakeet-cpp => engines/parakeet}/src/energy_vad.h | 0 {parakeet-cpp => engines/parakeet}/src/main.cpp | 0 .../parakeet}/src/mel_preprocess.cpp | 0 .../parakeet}/src/mel_preprocess.h | 0 .../parakeet}/src/parakeet_ctc.cpp | 0 .../parakeet}/src/parakeet_ctc.h | 0 .../parakeet}/src/parakeet_engine.cpp | 0 .../parakeet}/src/parakeet_eou.cpp | 0 .../parakeet}/src/parakeet_eou.h | 0 .../parakeet}/src/parakeet_log.cpp | 0 .../parakeet}/src/parakeet_log.h | 0 .../parakeet}/src/parakeet_sortformer.cpp | 0 .../parakeet}/src/parakeet_sortformer.h | 0 .../parakeet}/src/parakeet_tdt.cpp | 0 .../parakeet}/src/parakeet_tdt.h | 0 .../parakeet}/src/sentencepiece_bpe.cpp | 0 .../parakeet}/src/sentencepiece_bpe.h | 0 .../parakeet}/test/samples/abcba.rttm | 0 .../parakeet}/test/samples/abcba.wav | Bin .../parakeet}/test/samples/abcdba.rttm | 0 .../parakeet}/test/samples/abcdba.wav | Bin .../test/samples/diarization-sample-16k.wav | Bin .../parakeet}/test/samples/fr-multipiece-16k.wav | Bin .../parakeet}/test/samples/jfk.wav | Bin .../parakeet}/test/samples/sample-16k.wav | Bin .../parakeet}/test/test_ctc.cpp | 0 .../parakeet}/test/test_decoder_determinism.cpp | 0 .../parakeet}/test/test_encoder.cpp | 0 .../parakeet}/test/test_encoder_capture_parity.cpp | 0 .../parakeet}/test/test_eou_decoder_parity.cpp | 0 .../parakeet}/test/test_eou_streaming.cpp | 0 .../parakeet}/test/test_mel.cpp | 0 .../parakeet}/test/test_mel_fft_parity.cpp | 0 .../parakeet}/test/test_perf_regression.cpp | 0 .../parakeet}/test/test_sched_diarize_lifecycle.cpp | 0 .../test/test_sched_encoder_determinism.cpp | 0 .../test/test_sortformer_aosc_speakers.cpp | 0 .../parakeet}/test/test_sortformer_parity.cpp | 0 .../parakeet}/test/test_sortformer_streaming.cpp | 0 .../parakeet}/test/test_streaming.cpp | 0 .../parakeet}/test/test_tdt_decoder_parity.cpp | 0 .../parakeet}/test/test_tdt_encoder_parity.cpp | 0 .../parakeet}/test/test_utils.h | 0 .../parakeet}/test/test_vk_vs_cpu.cpp | 0 {tts-cpp => engines/tts}/.gitignore | 0 {tts-cpp => engines/tts}/CMakeLists.txt | 0 {tts-cpp => engines/tts}/LICENSE | 0 {tts-cpp => engines/tts}/MEMORY.md | 0 {tts-cpp => engines/tts}/NOTICE | 0 {tts-cpp => engines/tts}/PROGRESS.md | 0 {tts-cpp => engines/tts}/PROGRESS_SUPERTONIC.md | 0 {tts-cpp => engines/tts}/README.md | 0 .../tts}/cmake/tts-cppConfig.cmake.in | 0 .../tts}/docs/voiceclone-backward-campplus.md | 0 .../tts}/docs/voiceclone-backward-gap-matrix.md | 0 {tts-cpp => engines/tts}/include/tts-cpp/backend.h | 0 .../tts}/include/tts-cpp/chatterbox/engine.h | 0 .../include/tts-cpp/chatterbox/s3gen_pipeline.h | 0 {tts-cpp => engines/tts}/include/tts-cpp/export.h | 0 .../tts}/include/tts-cpp/lavasr/denoiser.h | 0 .../tts}/include/tts-cpp/lavasr/enhancer.h | 0 {tts-cpp => engines/tts}/include/tts-cpp/log.h | 0 .../tts}/include/tts-cpp/supertonic/engine.h | 0 {tts-cpp => engines/tts}/include/tts-cpp/tts-cpp.h | 0 .../tts}/scripts/bench-m4-validation.sh | 0 .../tts}/scripts/bench-supertonic-onnx.py | 0 .../tts}/scripts/build_cangjie_tsv.py | 0 .../tts}/scripts/build_mecab_dict.py | 0 .../tts}/scripts/compare-tokenizer.py | 0 .../tts}/scripts/convert-lavasr-denoiser-to-gguf.py | 0 .../tts}/scripts/convert-lavasr-enhancer-to-gguf.py | 0 .../tts}/scripts/convert-s3gen-to-gguf.py | 0 .../tts}/scripts/convert-supertonic2-to-gguf.py | 0 .../tts}/scripts/convert-t3-mtl-to-gguf.py | 0 .../tts}/scripts/convert-t3-turbo-to-gguf.py | 0 .../tts}/scripts/dump-campplus-reference.py | 0 .../tts}/scripts/dump-lavasr-denoiser-fixtures.py | 0 .../dump-lavasr-denoiser-pipeline-fixtures.py | 0 .../tts}/scripts/dump-lavasr-enhancer-fixtures.py | 0 .../tts}/scripts/dump-s3gen-reference.py | 0 .../tts}/scripts/dump-s3tokenizer-reference.py | 0 .../tts}/scripts/dump-streaming-reference.py | 0 .../tts}/scripts/dump-supertonic-reference.py | 0 .../tts}/scripts/dump-t3-mtl-reference.py | 0 .../tts}/scripts/dump-voiceclone-fixtures.py | 0 {tts-cpp => engines/tts}/scripts/extract-voice.py | 0 {tts-cpp => engines/tts}/scripts/gen-nfkd-table.py | 0 .../tts}/scripts/reference-t3-turbo.py | 0 {tts-cpp => engines/tts}/scripts/requantize-gguf.py | 0 {tts-cpp => engines/tts}/scripts/setup-ggml.sh | 0 .../tts}/scripts/setup-supertonic2.sh | 0 {tts-cpp => engines/tts}/scripts/synthesize.sh | 0 .../tts}/scripts/validate-precision-parity.sh | 0 {tts-cpp => engines/tts}/src/backend_selection.cpp | 0 {tts-cpp => engines/tts}/src/backend_selection.h | 0 {tts-cpp => engines/tts}/src/backend_util.h | 0 {tts-cpp => engines/tts}/src/campplus.cpp | 0 {tts-cpp => engines/tts}/src/campplus.h | 0 {tts-cpp => engines/tts}/src/campplus_backward.cpp | 0 {tts-cpp => engines/tts}/src/campplus_backward.h | 0 {tts-cpp => engines/tts}/src/campplus_forward.inc | 0 {tts-cpp => engines/tts}/src/chatterbox_cli.cpp | 0 {tts-cpp => engines/tts}/src/chatterbox_engine.cpp | 0 .../tts}/src/chatterbox_t3_internal.h | 0 {tts-cpp => engines/tts}/src/chatterbox_tts.cpp | 0 .../tts}/src/chatterbox_tts_test_hooks.h | 0 {tts-cpp => engines/tts}/src/cli_main.cpp | 0 {tts-cpp => engines/tts}/src/dr_wav.h | 0 {tts-cpp => engines/tts}/src/gguf_stream.h | 0 {tts-cpp => engines/tts}/src/gpt2_bpe.cpp | 0 {tts-cpp => engines/tts}/src/gpt2_bpe.h | 0 {tts-cpp => engines/tts}/src/json.hpp | 0 {tts-cpp => engines/tts}/src/lavasr/denoiser.cpp | 0 {tts-cpp => engines/tts}/src/lavasr/denoiser.h | 0 .../tts}/src/lavasr/denoiser_api.cpp | 0 .../tts}/src/lavasr/denoiser_core.cpp | 0 {tts-cpp => engines/tts}/src/lavasr/denoiser_core.h | 0 .../tts}/src/lavasr/denoiser_ggml.cpp | 0 {tts-cpp => engines/tts}/src/lavasr/denoiser_ggml.h | 0 .../tts}/src/lavasr/denoiser_gguf.cpp | 0 {tts-cpp => engines/tts}/src/lavasr/denoiser_gguf.h | 0 .../tts}/src/lavasr/dsp/dsp_constants.h | 0 .../tts}/src/lavasr/dsp/fastlr_merge.cpp | 0 .../tts}/src/lavasr/dsp/fastlr_merge.h | 0 .../tts}/src/lavasr/dsp/mel_filterbank.cpp | 0 .../tts}/src/lavasr/dsp/mel_filterbank.h | 0 .../tts}/src/lavasr/dsp/overlap_add.cpp | 0 .../tts}/src/lavasr/dsp/overlap_add.h | 0 .../tts}/src/lavasr/dsp/resampler.cpp | 0 {tts-cpp => engines/tts}/src/lavasr/dsp/resampler.h | 0 .../tts}/src/lavasr/dsp/stft_processor.cpp | 0 .../tts}/src/lavasr/dsp/stft_processor.h | 0 {tts-cpp => engines/tts}/src/lavasr/enhancer.cpp | 0 {tts-cpp => engines/tts}/src/lavasr/enhancer.h | 0 .../tts}/src/lavasr/enhancer_api.cpp | 0 .../tts}/src/lavasr/enhancer_core.cpp | 0 {tts-cpp => engines/tts}/src/lavasr/enhancer_core.h | 0 .../tts}/src/lavasr/enhancer_ggml.cpp | 0 {tts-cpp => engines/tts}/src/lavasr/enhancer_ggml.h | 0 .../tts}/src/lavasr/enhancer_gguf.cpp | 0 {tts-cpp => engines/tts}/src/lavasr/enhancer_gguf.h | 0 .../tts}/src/lavasr/lavasr_bench.cpp | 0 {tts-cpp => engines/tts}/src/log.cpp | 0 {tts-cpp => engines/tts}/src/main.cpp | 0 {tts-cpp => engines/tts}/src/mel2wav.cpp | 0 {tts-cpp => engines/tts}/src/mel_extract_stft.cpp | 0 {tts-cpp => engines/tts}/src/mtl_tokenizer.cpp | 0 {tts-cpp => engines/tts}/src/mtl_tokenizer.h | 0 {tts-cpp => engines/tts}/src/mtl_unicode_tables.inc | 0 {tts-cpp => engines/tts}/src/npy.h | 0 {tts-cpp => engines/tts}/src/s3tokenizer.cpp | 0 {tts-cpp => engines/tts}/src/s3tokenizer.h | 0 {tts-cpp => engines/tts}/src/sched_dispatch.cpp | 0 {tts-cpp => engines/tts}/src/sched_dispatch.h | 0 {tts-cpp => engines/tts}/src/supertonic_bench.cpp | 0 {tts-cpp => engines/tts}/src/supertonic_chunker.cpp | 0 {tts-cpp => engines/tts}/src/supertonic_chunker.h | 0 {tts-cpp => engines/tts}/src/supertonic_cli.cpp | 0 .../tts}/src/supertonic_duration.cpp | 0 {tts-cpp => engines/tts}/src/supertonic_engine.cpp | 0 {tts-cpp => engines/tts}/src/supertonic_gguf.cpp | 0 {tts-cpp => engines/tts}/src/supertonic_internal.h | 0 .../tts}/src/supertonic_preprocess.cpp | 0 .../tts}/src/supertonic_text_encoder.cpp | 0 .../tts}/src/supertonic_text_encoder_backward.cpp | 0 .../tts}/src/supertonic_text_encoder_backward.h | 0 .../tts}/src/supertonic_vector_estimator.cpp | 0 .../src/supertonic_vector_estimator_backward.cpp | 0 .../tts}/src/supertonic_vector_estimator_backward.h | 0 {tts-cpp => engines/tts}/src/supertonic_vocoder.cpp | 0 .../tts}/src/supertonic_voice_json.cpp | 0 .../tts}/src/supertonic_voice_json.h | 0 .../tts}/src/t3_alignment_analyzer.cpp | 0 .../tts}/src/t3_alignment_analyzer.h | 0 {tts-cpp => engines/tts}/src/t3_mtl.cpp | 0 {tts-cpp => engines/tts}/src/t3_mtl.h | 0 {tts-cpp => engines/tts}/src/t3_stop_controller.cpp | 0 {tts-cpp => engines/tts}/src/t3_stop_controller.h | 0 {tts-cpp => engines/tts}/src/text_preprocess.cpp | 0 {tts-cpp => engines/tts}/src/text_preprocess.h | 0 {tts-cpp => engines/tts}/src/voice_encoder.cpp | 0 {tts-cpp => engines/tts}/src/voice_encoder.h | 0 {tts-cpp => engines/tts}/src/voice_features.cpp | 0 {tts-cpp => engines/tts}/src/voice_features.h | 0 .../tts}/src/voiceclone_gradcheck.cpp | 0 {tts-cpp => engines/tts}/src/voiceclone_gradcheck.h | 0 {tts-cpp => engines/tts}/src/voiceclone_metrics.cpp | 0 {tts-cpp => engines/tts}/src/voiceclone_metrics.h | 0 .../tts}/test/fixtures/voiceclone/v1/README.md | 0 .../tts}/test/fixtures/voiceclone/v1/embed_a.npy | Bin .../tts}/test/fixtures/voiceclone/v1/embed_b.npy | Bin .../test/fixtures/voiceclone/v1/expected_cosine.npy | Bin .../fixtures/voiceclone/v1/expected_style_loss.npy | Bin .../test/fixtures/voiceclone/v1/expected_wer.npy | Bin .../tts}/test/fixtures/voiceclone/v1/hidden_ref.npy | Bin .../test/fixtures/voiceclone/v1/hidden_target.npy | Bin .../tts}/test/fixtures/voiceclone/v1/wer_hyp.txt | 0 .../tts}/test/fixtures/voiceclone/v1/wer_ref.txt | 0 {tts-cpp => engines/tts}/test/test_campplus.cpp | 0 .../tts}/test/test_campplus_backward.cpp | 0 .../tts}/test/test_campplus_backward_parity.cpp | 0 .../tts}/test/test_chatterbox_engine_stream.cpp | 0 {tts-cpp => engines/tts}/test/test_cpu_caches.cpp | 0 .../tts}/test/test_eos_roundtrip.cpp | 0 {tts-cpp => engines/tts}/test/test_fbank.cpp | 0 {tts-cpp => engines/tts}/test/test_gguf_stream.cpp | 0 .../tts}/test/test_kv_cache_type.cpp | 0 .../tts}/test/test_lavasr_denoiser_ggml.cpp | 0 .../tts}/test/test_lavasr_denoiser_gguf.cpp | 0 {tts-cpp => engines/tts}/test/test_lavasr_dsp.cpp | 0 .../tts}/test/test_lavasr_enhancer_core.cpp | 0 .../tts}/test/test_lavasr_enhancer_ggml.cpp | 0 .../tts}/test/test_lavasr_enhancer_gguf.cpp | 0 {tts-cpp => engines/tts}/test/test_metal_ops.cpp | 0 {tts-cpp => engines/tts}/test/test_mtl_sampler.cpp | 0 .../tts}/test/test_mtl_tokenizer.cpp | 0 .../tts}/test/test_multilingual_asr.cpp | 0 .../tts}/test/test_multilingual_synth.cpp | 0 .../tts}/test/test_output_sample_rate.cpp | 0 .../test/test_output_sample_rate_supertonic.cpp | 0 {tts-cpp => engines/tts}/test/test_resample.cpp | 0 {tts-cpp => engines/tts}/test/test_s3gen.cpp | 0 .../tts}/test/test_s3gen_cfg_rate.cpp | 0 .../tts}/test/test_s3gen_sched_equivalence.cpp | 0 {tts-cpp => engines/tts}/test/test_s3tokenizer.cpp | 0 {tts-cpp => engines/tts}/test/test_streaming.cpp | 0 .../tts}/test/test_streaming_loudness.cpp | 0 .../tts}/test/test_supertonic_audit3_caches.cpp | 0 .../tts}/test/test_supertonic_backend_dispatch.cpp | 0 .../tts}/test/test_supertonic_capability_cache.cpp | 0 .../test/test_supertonic_convnext_block_fused.cpp | 0 .../tts}/test/test_supertonic_duration.cpp | 0 .../tts}/test/test_supertonic_duration_trace.cpp | 0 .../tts}/test/test_supertonic_engine_cycle.cpp | 0 .../tts}/test/test_supertonic_external_voice.cpp | 0 .../tts}/test/test_supertonic_f16_attn_parity.cpp | 0 .../tts}/test/test_supertonic_f16_deny_list_api.cpp | 0 .../tts}/test/test_supertonic_f16_weights.cpp | 0 .../tts}/test/test_supertonic_graph_rewrites.cpp | 0 .../test/test_supertonic_graph_to_graph_blit.cpp | 0 .../test/test_supertonic_in_graph_transpose.cpp | 0 .../tts}/test/test_supertonic_input_scratchpad.cpp | 0 .../tts}/test/test_supertonic_kv_attn_type.cpp | 0 .../tts}/test/test_supertonic_kv_attn_type_api.cpp | 0 .../tts}/test/test_supertonic_languages.cpp | 0 .../tts}/test/test_supertonic_load_caches.cpp | 0 .../test/test_supertonic_pinned_host_buffer.cpp | 0 .../tts}/test/test_supertonic_pipeline.cpp | 0 .../tts}/test/test_supertonic_portable_ops.cpp | 0 .../tts}/test/test_supertonic_preprocess.cpp | 0 .../tts}/test/test_supertonic_profile_csv.cpp | 0 .../tts}/test/test_supertonic_rope_in_graph.cpp | 0 .../tts}/test/test_supertonic_rope_packed_qk.cpp | 0 .../tts}/test/test_supertonic_sched_equivalence.cpp | 0 .../tts}/test/test_supertonic_text_encoder.cpp | 0 .../test/test_supertonic_text_encoder_backward.cpp | 0 .../test/test_supertonic_text_encoder_caches.cpp | 0 .../test_supertonic_text_encoder_gpu_bridge.cpp | 0 .../test/test_supertonic_text_encoder_trace.cpp | 0 .../test/test_supertonic_upload_skip_tracker.cpp | 0 .../tts}/test/test_supertonic_vector.cpp | 0 .../test_supertonic_vector_estimator_backward.cpp | 0 .../tts}/test/test_supertonic_vector_trace.cpp | 0 .../tts}/test/test_supertonic_vocoder.cpp | 0 .../tts}/test/test_supertonic_vocoder_pointwise.cpp | 0 .../tts}/test/test_supertonic_vocoder_trace.cpp | 0 .../tts}/test/test_supertonic_voice_host_cache.cpp | 0 .../test/test_supertonic_vulkan_device_select.cpp | 0 .../tts}/test/test_supertonic_vulkan_dispatch.cpp | 0 .../test/test_supertonic_vulkan_env_overrides.cpp | 0 .../tts}/test/test_supertonic_warm_up_api.cpp | 0 .../tts}/test/test_t3_alignment_analyzer.cpp | 0 {tts-cpp => engines/tts}/test/test_t3_caches.cpp | 0 {tts-cpp => engines/tts}/test/test_t3_mtl.cpp | 0 .../tts}/test/test_t3_mtl_stages.cpp | 0 .../tts}/test/test_t3_sched_dispatch.cpp | 0 .../tts}/test/test_t3_sched_equivalence.cpp | 0 .../tts}/test/test_t3_sched_migration.cpp | 0 .../tts}/test/test_t3_stop_controller.cpp | 0 {tts-cpp => engines/tts}/test/test_text_split.cpp | 0 .../tts}/test/test_voice_embedding.cpp | 0 .../tts}/test/test_voice_encoder.cpp | 0 .../tts}/test/test_voice_features.cpp | 0 .../tts}/test/test_voiceclone_gradcheck.cpp | 0 .../tts}/test/test_voiceclone_metrics.cpp | 0 318 files changed, 0 insertions(+), 0 deletions(-) rename {parakeet-cpp => engines/parakeet}/.gitignore (100%) rename {parakeet-cpp => engines/parakeet}/CMakeLists.txt (100%) rename {parakeet-cpp => engines/parakeet}/LICENSE (100%) rename {parakeet-cpp => engines/parakeet}/NOTICE (100%) rename {parakeet-cpp => engines/parakeet}/PROGRESS.md (100%) rename {parakeet-cpp => engines/parakeet}/README.md (100%) rename {parakeet-cpp => engines/parakeet}/cmake/parakeet-cppConfig.cmake.in (100%) rename {parakeet-cpp => engines/parakeet}/examples/live-mic-attributed.cpp (100%) rename {parakeet-cpp => engines/parakeet}/examples/live-mic.cpp (100%) rename {parakeet-cpp => engines/parakeet}/examples/miniaudio.h (100%) rename {parakeet-cpp => engines/parakeet}/examples/miniaudio_impl.cpp (100%) rename {parakeet-cpp => engines/parakeet}/include/parakeet/attributed.h (100%) rename {parakeet-cpp => engines/parakeet}/include/parakeet/cli.h (100%) rename {parakeet-cpp => engines/parakeet}/include/parakeet/diarization.h (100%) rename {parakeet-cpp => engines/parakeet}/include/parakeet/engine.h (100%) rename {parakeet-cpp => engines/parakeet}/include/parakeet/export.h (100%) rename {parakeet-cpp => engines/parakeet}/include/parakeet/log.h (100%) rename {parakeet-cpp => engines/parakeet}/include/parakeet/parakeet.h (100%) rename {parakeet-cpp => engines/parakeet}/include/parakeet/streaming.h (100%) rename {parakeet-cpp => engines/parakeet}/scripts/convert-nemo-to-gguf.py (100%) rename {parakeet-cpp => engines/parakeet}/scripts/download-all-models.sh (100%) rename {parakeet-cpp => engines/parakeet}/scripts/dump-ctc-reference.py (100%) rename {parakeet-cpp => engines/parakeet}/scripts/dump-eou-reference.py (100%) rename {parakeet-cpp => engines/parakeet}/scripts/dump-sortformer-reference.py (100%) rename {parakeet-cpp => engines/parakeet}/scripts/dump-tdt-reference.py (100%) rename {parakeet-cpp => engines/parakeet}/scripts/ref-encoder-from-gguf.py (100%) rename {parakeet-cpp => engines/parakeet}/scripts/setup-ggml.sh (100%) rename {parakeet-cpp => engines/parakeet}/scripts/streaming-reference.py (100%) rename {parakeet-cpp => engines/parakeet}/scripts/verify-gguf-roundtrip.py (100%) rename {parakeet-cpp => engines/parakeet}/src/backend_util.h (100%) rename {parakeet-cpp => engines/parakeet}/src/cli_main.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/dr_wav.h (100%) rename {parakeet-cpp => engines/parakeet}/src/energy_vad.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/energy_vad.h (100%) rename {parakeet-cpp => engines/parakeet}/src/main.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/mel_preprocess.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/mel_preprocess.h (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_ctc.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_ctc.h (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_engine.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_eou.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_eou.h (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_log.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_log.h (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_sortformer.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_sortformer.h (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_tdt.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/parakeet_tdt.h (100%) rename {parakeet-cpp => engines/parakeet}/src/sentencepiece_bpe.cpp (100%) rename {parakeet-cpp => engines/parakeet}/src/sentencepiece_bpe.h (100%) rename {parakeet-cpp => engines/parakeet}/test/samples/abcba.rttm (100%) rename {parakeet-cpp => engines/parakeet}/test/samples/abcba.wav (100%) rename {parakeet-cpp => engines/parakeet}/test/samples/abcdba.rttm (100%) rename {parakeet-cpp => engines/parakeet}/test/samples/abcdba.wav (100%) rename {parakeet-cpp => engines/parakeet}/test/samples/diarization-sample-16k.wav (100%) rename {parakeet-cpp => engines/parakeet}/test/samples/fr-multipiece-16k.wav (100%) rename {parakeet-cpp => engines/parakeet}/test/samples/jfk.wav (100%) rename {parakeet-cpp => engines/parakeet}/test/samples/sample-16k.wav (100%) rename {parakeet-cpp => engines/parakeet}/test/test_ctc.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_decoder_determinism.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_encoder.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_encoder_capture_parity.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_eou_decoder_parity.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_eou_streaming.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_mel.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_mel_fft_parity.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_perf_regression.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_sched_diarize_lifecycle.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_sched_encoder_determinism.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_sortformer_aosc_speakers.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_sortformer_parity.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_sortformer_streaming.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_streaming.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_tdt_decoder_parity.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_tdt_encoder_parity.cpp (100%) rename {parakeet-cpp => engines/parakeet}/test/test_utils.h (100%) rename {parakeet-cpp => engines/parakeet}/test/test_vk_vs_cpu.cpp (100%) rename {tts-cpp => engines/tts}/.gitignore (100%) rename {tts-cpp => engines/tts}/CMakeLists.txt (100%) rename {tts-cpp => engines/tts}/LICENSE (100%) rename {tts-cpp => engines/tts}/MEMORY.md (100%) rename {tts-cpp => engines/tts}/NOTICE (100%) rename {tts-cpp => engines/tts}/PROGRESS.md (100%) rename {tts-cpp => engines/tts}/PROGRESS_SUPERTONIC.md (100%) rename {tts-cpp => engines/tts}/README.md (100%) rename {tts-cpp => engines/tts}/cmake/tts-cppConfig.cmake.in (100%) rename {tts-cpp => engines/tts}/docs/voiceclone-backward-campplus.md (100%) rename {tts-cpp => engines/tts}/docs/voiceclone-backward-gap-matrix.md (100%) rename {tts-cpp => engines/tts}/include/tts-cpp/backend.h (100%) rename {tts-cpp => engines/tts}/include/tts-cpp/chatterbox/engine.h (100%) rename {tts-cpp => engines/tts}/include/tts-cpp/chatterbox/s3gen_pipeline.h (100%) rename {tts-cpp => engines/tts}/include/tts-cpp/export.h (100%) rename {tts-cpp => engines/tts}/include/tts-cpp/lavasr/denoiser.h (100%) rename {tts-cpp => engines/tts}/include/tts-cpp/lavasr/enhancer.h (100%) rename {tts-cpp => engines/tts}/include/tts-cpp/log.h (100%) rename {tts-cpp => engines/tts}/include/tts-cpp/supertonic/engine.h (100%) rename {tts-cpp => engines/tts}/include/tts-cpp/tts-cpp.h (100%) rename {tts-cpp => engines/tts}/scripts/bench-m4-validation.sh (100%) rename {tts-cpp => engines/tts}/scripts/bench-supertonic-onnx.py (100%) rename {tts-cpp => engines/tts}/scripts/build_cangjie_tsv.py (100%) rename {tts-cpp => engines/tts}/scripts/build_mecab_dict.py (100%) rename {tts-cpp => engines/tts}/scripts/compare-tokenizer.py (100%) rename {tts-cpp => engines/tts}/scripts/convert-lavasr-denoiser-to-gguf.py (100%) rename {tts-cpp => engines/tts}/scripts/convert-lavasr-enhancer-to-gguf.py (100%) rename {tts-cpp => engines/tts}/scripts/convert-s3gen-to-gguf.py (100%) rename {tts-cpp => engines/tts}/scripts/convert-supertonic2-to-gguf.py (100%) rename {tts-cpp => engines/tts}/scripts/convert-t3-mtl-to-gguf.py (100%) rename {tts-cpp => engines/tts}/scripts/convert-t3-turbo-to-gguf.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-campplus-reference.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-lavasr-denoiser-fixtures.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-lavasr-denoiser-pipeline-fixtures.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-lavasr-enhancer-fixtures.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-s3gen-reference.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-s3tokenizer-reference.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-streaming-reference.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-supertonic-reference.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-t3-mtl-reference.py (100%) rename {tts-cpp => engines/tts}/scripts/dump-voiceclone-fixtures.py (100%) rename {tts-cpp => engines/tts}/scripts/extract-voice.py (100%) rename {tts-cpp => engines/tts}/scripts/gen-nfkd-table.py (100%) rename {tts-cpp => engines/tts}/scripts/reference-t3-turbo.py (100%) rename {tts-cpp => engines/tts}/scripts/requantize-gguf.py (100%) rename {tts-cpp => engines/tts}/scripts/setup-ggml.sh (100%) rename {tts-cpp => engines/tts}/scripts/setup-supertonic2.sh (100%) rename {tts-cpp => engines/tts}/scripts/synthesize.sh (100%) rename {tts-cpp => engines/tts}/scripts/validate-precision-parity.sh (100%) rename {tts-cpp => engines/tts}/src/backend_selection.cpp (100%) rename {tts-cpp => engines/tts}/src/backend_selection.h (100%) rename {tts-cpp => engines/tts}/src/backend_util.h (100%) rename {tts-cpp => engines/tts}/src/campplus.cpp (100%) rename {tts-cpp => engines/tts}/src/campplus.h (100%) rename {tts-cpp => engines/tts}/src/campplus_backward.cpp (100%) rename {tts-cpp => engines/tts}/src/campplus_backward.h (100%) rename {tts-cpp => engines/tts}/src/campplus_forward.inc (100%) rename {tts-cpp => engines/tts}/src/chatterbox_cli.cpp (100%) rename {tts-cpp => engines/tts}/src/chatterbox_engine.cpp (100%) rename {tts-cpp => engines/tts}/src/chatterbox_t3_internal.h (100%) rename {tts-cpp => engines/tts}/src/chatterbox_tts.cpp (100%) rename {tts-cpp => engines/tts}/src/chatterbox_tts_test_hooks.h (100%) rename {tts-cpp => engines/tts}/src/cli_main.cpp (100%) rename {tts-cpp => engines/tts}/src/dr_wav.h (100%) rename {tts-cpp => engines/tts}/src/gguf_stream.h (100%) rename {tts-cpp => engines/tts}/src/gpt2_bpe.cpp (100%) rename {tts-cpp => engines/tts}/src/gpt2_bpe.h (100%) rename {tts-cpp => engines/tts}/src/json.hpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/denoiser.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/denoiser.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/denoiser_api.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/denoiser_core.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/denoiser_core.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/denoiser_ggml.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/denoiser_ggml.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/denoiser_gguf.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/denoiser_gguf.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/dsp_constants.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/fastlr_merge.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/fastlr_merge.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/mel_filterbank.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/mel_filterbank.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/overlap_add.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/overlap_add.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/resampler.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/resampler.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/stft_processor.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/dsp/stft_processor.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/enhancer.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/enhancer.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/enhancer_api.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/enhancer_core.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/enhancer_core.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/enhancer_ggml.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/enhancer_ggml.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/enhancer_gguf.cpp (100%) rename {tts-cpp => engines/tts}/src/lavasr/enhancer_gguf.h (100%) rename {tts-cpp => engines/tts}/src/lavasr/lavasr_bench.cpp (100%) rename {tts-cpp => engines/tts}/src/log.cpp (100%) rename {tts-cpp => engines/tts}/src/main.cpp (100%) rename {tts-cpp => engines/tts}/src/mel2wav.cpp (100%) rename {tts-cpp => engines/tts}/src/mel_extract_stft.cpp (100%) rename {tts-cpp => engines/tts}/src/mtl_tokenizer.cpp (100%) rename {tts-cpp => engines/tts}/src/mtl_tokenizer.h (100%) rename {tts-cpp => engines/tts}/src/mtl_unicode_tables.inc (100%) rename {tts-cpp => engines/tts}/src/npy.h (100%) rename {tts-cpp => engines/tts}/src/s3tokenizer.cpp (100%) rename {tts-cpp => engines/tts}/src/s3tokenizer.h (100%) rename {tts-cpp => engines/tts}/src/sched_dispatch.cpp (100%) rename {tts-cpp => engines/tts}/src/sched_dispatch.h (100%) rename {tts-cpp => engines/tts}/src/supertonic_bench.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_chunker.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_chunker.h (100%) rename {tts-cpp => engines/tts}/src/supertonic_cli.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_duration.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_engine.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_gguf.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_internal.h (100%) rename {tts-cpp => engines/tts}/src/supertonic_preprocess.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_text_encoder.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_text_encoder_backward.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_text_encoder_backward.h (100%) rename {tts-cpp => engines/tts}/src/supertonic_vector_estimator.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_vector_estimator_backward.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_vector_estimator_backward.h (100%) rename {tts-cpp => engines/tts}/src/supertonic_vocoder.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_voice_json.cpp (100%) rename {tts-cpp => engines/tts}/src/supertonic_voice_json.h (100%) rename {tts-cpp => engines/tts}/src/t3_alignment_analyzer.cpp (100%) rename {tts-cpp => engines/tts}/src/t3_alignment_analyzer.h (100%) rename {tts-cpp => engines/tts}/src/t3_mtl.cpp (100%) rename {tts-cpp => engines/tts}/src/t3_mtl.h (100%) rename {tts-cpp => engines/tts}/src/t3_stop_controller.cpp (100%) rename {tts-cpp => engines/tts}/src/t3_stop_controller.h (100%) rename {tts-cpp => engines/tts}/src/text_preprocess.cpp (100%) rename {tts-cpp => engines/tts}/src/text_preprocess.h (100%) rename {tts-cpp => engines/tts}/src/voice_encoder.cpp (100%) rename {tts-cpp => engines/tts}/src/voice_encoder.h (100%) rename {tts-cpp => engines/tts}/src/voice_features.cpp (100%) rename {tts-cpp => engines/tts}/src/voice_features.h (100%) rename {tts-cpp => engines/tts}/src/voiceclone_gradcheck.cpp (100%) rename {tts-cpp => engines/tts}/src/voiceclone_gradcheck.h (100%) rename {tts-cpp => engines/tts}/src/voiceclone_metrics.cpp (100%) rename {tts-cpp => engines/tts}/src/voiceclone_metrics.h (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/README.md (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/embed_a.npy (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/embed_b.npy (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/expected_cosine.npy (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/expected_style_loss.npy (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/expected_wer.npy (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/hidden_ref.npy (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/hidden_target.npy (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/wer_hyp.txt (100%) rename {tts-cpp => engines/tts}/test/fixtures/voiceclone/v1/wer_ref.txt (100%) rename {tts-cpp => engines/tts}/test/test_campplus.cpp (100%) rename {tts-cpp => engines/tts}/test/test_campplus_backward.cpp (100%) rename {tts-cpp => engines/tts}/test/test_campplus_backward_parity.cpp (100%) rename {tts-cpp => engines/tts}/test/test_chatterbox_engine_stream.cpp (100%) rename {tts-cpp => engines/tts}/test/test_cpu_caches.cpp (100%) rename {tts-cpp => engines/tts}/test/test_eos_roundtrip.cpp (100%) rename {tts-cpp => engines/tts}/test/test_fbank.cpp (100%) rename {tts-cpp => engines/tts}/test/test_gguf_stream.cpp (100%) rename {tts-cpp => engines/tts}/test/test_kv_cache_type.cpp (100%) rename {tts-cpp => engines/tts}/test/test_lavasr_denoiser_ggml.cpp (100%) rename {tts-cpp => engines/tts}/test/test_lavasr_denoiser_gguf.cpp (100%) rename {tts-cpp => engines/tts}/test/test_lavasr_dsp.cpp (100%) rename {tts-cpp => engines/tts}/test/test_lavasr_enhancer_core.cpp (100%) rename {tts-cpp => engines/tts}/test/test_lavasr_enhancer_ggml.cpp (100%) rename {tts-cpp => engines/tts}/test/test_lavasr_enhancer_gguf.cpp (100%) rename {tts-cpp => engines/tts}/test/test_metal_ops.cpp (100%) rename {tts-cpp => engines/tts}/test/test_mtl_sampler.cpp (100%) rename {tts-cpp => engines/tts}/test/test_mtl_tokenizer.cpp (100%) rename {tts-cpp => engines/tts}/test/test_multilingual_asr.cpp (100%) rename {tts-cpp => engines/tts}/test/test_multilingual_synth.cpp (100%) rename {tts-cpp => engines/tts}/test/test_output_sample_rate.cpp (100%) rename {tts-cpp => engines/tts}/test/test_output_sample_rate_supertonic.cpp (100%) rename {tts-cpp => engines/tts}/test/test_resample.cpp (100%) rename {tts-cpp => engines/tts}/test/test_s3gen.cpp (100%) rename {tts-cpp => engines/tts}/test/test_s3gen_cfg_rate.cpp (100%) rename {tts-cpp => engines/tts}/test/test_s3gen_sched_equivalence.cpp (100%) rename {tts-cpp => engines/tts}/test/test_s3tokenizer.cpp (100%) rename {tts-cpp => engines/tts}/test/test_streaming.cpp (100%) rename {tts-cpp => engines/tts}/test/test_streaming_loudness.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_audit3_caches.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_backend_dispatch.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_capability_cache.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_convnext_block_fused.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_duration.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_duration_trace.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_engine_cycle.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_external_voice.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_f16_attn_parity.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_f16_deny_list_api.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_f16_weights.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_graph_rewrites.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_graph_to_graph_blit.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_in_graph_transpose.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_input_scratchpad.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_kv_attn_type.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_kv_attn_type_api.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_languages.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_load_caches.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_pinned_host_buffer.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_pipeline.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_portable_ops.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_preprocess.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_profile_csv.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_rope_in_graph.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_rope_packed_qk.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_sched_equivalence.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_text_encoder.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_text_encoder_backward.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_text_encoder_caches.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_text_encoder_gpu_bridge.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_text_encoder_trace.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_upload_skip_tracker.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_vector.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_vector_estimator_backward.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_vector_trace.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_vocoder.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_vocoder_pointwise.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_vocoder_trace.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_voice_host_cache.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_vulkan_device_select.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_vulkan_dispatch.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_vulkan_env_overrides.cpp (100%) rename {tts-cpp => engines/tts}/test/test_supertonic_warm_up_api.cpp (100%) rename {tts-cpp => engines/tts}/test/test_t3_alignment_analyzer.cpp (100%) rename {tts-cpp => engines/tts}/test/test_t3_caches.cpp (100%) rename {tts-cpp => engines/tts}/test/test_t3_mtl.cpp (100%) rename {tts-cpp => engines/tts}/test/test_t3_mtl_stages.cpp (100%) rename {tts-cpp => engines/tts}/test/test_t3_sched_dispatch.cpp (100%) rename {tts-cpp => engines/tts}/test/test_t3_sched_equivalence.cpp (100%) rename {tts-cpp => engines/tts}/test/test_t3_sched_migration.cpp (100%) rename {tts-cpp => engines/tts}/test/test_t3_stop_controller.cpp (100%) rename {tts-cpp => engines/tts}/test/test_text_split.cpp (100%) rename {tts-cpp => engines/tts}/test/test_voice_embedding.cpp (100%) rename {tts-cpp => engines/tts}/test/test_voice_encoder.cpp (100%) rename {tts-cpp => engines/tts}/test/test_voice_features.cpp (100%) rename {tts-cpp => engines/tts}/test/test_voiceclone_gradcheck.cpp (100%) rename {tts-cpp => engines/tts}/test/test_voiceclone_metrics.cpp (100%) diff --git a/parakeet-cpp/.gitignore b/engines/parakeet/.gitignore similarity index 100% rename from parakeet-cpp/.gitignore rename to engines/parakeet/.gitignore diff --git a/parakeet-cpp/CMakeLists.txt b/engines/parakeet/CMakeLists.txt similarity index 100% rename from parakeet-cpp/CMakeLists.txt rename to engines/parakeet/CMakeLists.txt diff --git a/parakeet-cpp/LICENSE b/engines/parakeet/LICENSE similarity index 100% rename from parakeet-cpp/LICENSE rename to engines/parakeet/LICENSE diff --git a/parakeet-cpp/NOTICE b/engines/parakeet/NOTICE similarity index 100% rename from parakeet-cpp/NOTICE rename to engines/parakeet/NOTICE diff --git a/parakeet-cpp/PROGRESS.md b/engines/parakeet/PROGRESS.md similarity index 100% rename from parakeet-cpp/PROGRESS.md rename to engines/parakeet/PROGRESS.md diff --git a/parakeet-cpp/README.md b/engines/parakeet/README.md similarity index 100% rename from parakeet-cpp/README.md rename to engines/parakeet/README.md diff --git a/parakeet-cpp/cmake/parakeet-cppConfig.cmake.in b/engines/parakeet/cmake/parakeet-cppConfig.cmake.in similarity index 100% rename from parakeet-cpp/cmake/parakeet-cppConfig.cmake.in rename to engines/parakeet/cmake/parakeet-cppConfig.cmake.in diff --git a/parakeet-cpp/examples/live-mic-attributed.cpp b/engines/parakeet/examples/live-mic-attributed.cpp similarity index 100% rename from parakeet-cpp/examples/live-mic-attributed.cpp rename to engines/parakeet/examples/live-mic-attributed.cpp diff --git a/parakeet-cpp/examples/live-mic.cpp b/engines/parakeet/examples/live-mic.cpp similarity index 100% rename from parakeet-cpp/examples/live-mic.cpp rename to engines/parakeet/examples/live-mic.cpp diff --git a/parakeet-cpp/examples/miniaudio.h b/engines/parakeet/examples/miniaudio.h similarity index 100% rename from parakeet-cpp/examples/miniaudio.h rename to engines/parakeet/examples/miniaudio.h diff --git a/parakeet-cpp/examples/miniaudio_impl.cpp b/engines/parakeet/examples/miniaudio_impl.cpp similarity index 100% rename from parakeet-cpp/examples/miniaudio_impl.cpp rename to engines/parakeet/examples/miniaudio_impl.cpp diff --git a/parakeet-cpp/include/parakeet/attributed.h b/engines/parakeet/include/parakeet/attributed.h similarity index 100% rename from parakeet-cpp/include/parakeet/attributed.h rename to engines/parakeet/include/parakeet/attributed.h diff --git a/parakeet-cpp/include/parakeet/cli.h b/engines/parakeet/include/parakeet/cli.h similarity index 100% rename from parakeet-cpp/include/parakeet/cli.h rename to engines/parakeet/include/parakeet/cli.h diff --git a/parakeet-cpp/include/parakeet/diarization.h b/engines/parakeet/include/parakeet/diarization.h similarity index 100% rename from parakeet-cpp/include/parakeet/diarization.h rename to engines/parakeet/include/parakeet/diarization.h diff --git a/parakeet-cpp/include/parakeet/engine.h b/engines/parakeet/include/parakeet/engine.h similarity index 100% rename from parakeet-cpp/include/parakeet/engine.h rename to engines/parakeet/include/parakeet/engine.h diff --git a/parakeet-cpp/include/parakeet/export.h b/engines/parakeet/include/parakeet/export.h similarity index 100% rename from parakeet-cpp/include/parakeet/export.h rename to engines/parakeet/include/parakeet/export.h diff --git a/parakeet-cpp/include/parakeet/log.h b/engines/parakeet/include/parakeet/log.h similarity index 100% rename from parakeet-cpp/include/parakeet/log.h rename to engines/parakeet/include/parakeet/log.h diff --git a/parakeet-cpp/include/parakeet/parakeet.h b/engines/parakeet/include/parakeet/parakeet.h similarity index 100% rename from parakeet-cpp/include/parakeet/parakeet.h rename to engines/parakeet/include/parakeet/parakeet.h diff --git a/parakeet-cpp/include/parakeet/streaming.h b/engines/parakeet/include/parakeet/streaming.h similarity index 100% rename from parakeet-cpp/include/parakeet/streaming.h rename to engines/parakeet/include/parakeet/streaming.h diff --git a/parakeet-cpp/scripts/convert-nemo-to-gguf.py b/engines/parakeet/scripts/convert-nemo-to-gguf.py similarity index 100% rename from parakeet-cpp/scripts/convert-nemo-to-gguf.py rename to engines/parakeet/scripts/convert-nemo-to-gguf.py diff --git a/parakeet-cpp/scripts/download-all-models.sh b/engines/parakeet/scripts/download-all-models.sh similarity index 100% rename from parakeet-cpp/scripts/download-all-models.sh rename to engines/parakeet/scripts/download-all-models.sh diff --git a/parakeet-cpp/scripts/dump-ctc-reference.py b/engines/parakeet/scripts/dump-ctc-reference.py similarity index 100% rename from parakeet-cpp/scripts/dump-ctc-reference.py rename to engines/parakeet/scripts/dump-ctc-reference.py diff --git a/parakeet-cpp/scripts/dump-eou-reference.py b/engines/parakeet/scripts/dump-eou-reference.py similarity index 100% rename from parakeet-cpp/scripts/dump-eou-reference.py rename to engines/parakeet/scripts/dump-eou-reference.py diff --git a/parakeet-cpp/scripts/dump-sortformer-reference.py b/engines/parakeet/scripts/dump-sortformer-reference.py similarity index 100% rename from parakeet-cpp/scripts/dump-sortformer-reference.py rename to engines/parakeet/scripts/dump-sortformer-reference.py diff --git a/parakeet-cpp/scripts/dump-tdt-reference.py b/engines/parakeet/scripts/dump-tdt-reference.py similarity index 100% rename from parakeet-cpp/scripts/dump-tdt-reference.py rename to engines/parakeet/scripts/dump-tdt-reference.py diff --git a/parakeet-cpp/scripts/ref-encoder-from-gguf.py b/engines/parakeet/scripts/ref-encoder-from-gguf.py similarity index 100% rename from parakeet-cpp/scripts/ref-encoder-from-gguf.py rename to engines/parakeet/scripts/ref-encoder-from-gguf.py diff --git a/parakeet-cpp/scripts/setup-ggml.sh b/engines/parakeet/scripts/setup-ggml.sh similarity index 100% rename from parakeet-cpp/scripts/setup-ggml.sh rename to engines/parakeet/scripts/setup-ggml.sh diff --git a/parakeet-cpp/scripts/streaming-reference.py b/engines/parakeet/scripts/streaming-reference.py similarity index 100% rename from parakeet-cpp/scripts/streaming-reference.py rename to engines/parakeet/scripts/streaming-reference.py diff --git a/parakeet-cpp/scripts/verify-gguf-roundtrip.py b/engines/parakeet/scripts/verify-gguf-roundtrip.py similarity index 100% rename from parakeet-cpp/scripts/verify-gguf-roundtrip.py rename to engines/parakeet/scripts/verify-gguf-roundtrip.py diff --git a/parakeet-cpp/src/backend_util.h b/engines/parakeet/src/backend_util.h similarity index 100% rename from parakeet-cpp/src/backend_util.h rename to engines/parakeet/src/backend_util.h diff --git a/parakeet-cpp/src/cli_main.cpp b/engines/parakeet/src/cli_main.cpp similarity index 100% rename from parakeet-cpp/src/cli_main.cpp rename to engines/parakeet/src/cli_main.cpp diff --git a/parakeet-cpp/src/dr_wav.h b/engines/parakeet/src/dr_wav.h similarity index 100% rename from parakeet-cpp/src/dr_wav.h rename to engines/parakeet/src/dr_wav.h diff --git a/parakeet-cpp/src/energy_vad.cpp b/engines/parakeet/src/energy_vad.cpp similarity index 100% rename from parakeet-cpp/src/energy_vad.cpp rename to engines/parakeet/src/energy_vad.cpp diff --git a/parakeet-cpp/src/energy_vad.h b/engines/parakeet/src/energy_vad.h similarity index 100% rename from parakeet-cpp/src/energy_vad.h rename to engines/parakeet/src/energy_vad.h diff --git a/parakeet-cpp/src/main.cpp b/engines/parakeet/src/main.cpp similarity index 100% rename from parakeet-cpp/src/main.cpp rename to engines/parakeet/src/main.cpp diff --git a/parakeet-cpp/src/mel_preprocess.cpp b/engines/parakeet/src/mel_preprocess.cpp similarity index 100% rename from parakeet-cpp/src/mel_preprocess.cpp rename to engines/parakeet/src/mel_preprocess.cpp diff --git a/parakeet-cpp/src/mel_preprocess.h b/engines/parakeet/src/mel_preprocess.h similarity index 100% rename from parakeet-cpp/src/mel_preprocess.h rename to engines/parakeet/src/mel_preprocess.h diff --git a/parakeet-cpp/src/parakeet_ctc.cpp b/engines/parakeet/src/parakeet_ctc.cpp similarity index 100% rename from parakeet-cpp/src/parakeet_ctc.cpp rename to engines/parakeet/src/parakeet_ctc.cpp diff --git a/parakeet-cpp/src/parakeet_ctc.h b/engines/parakeet/src/parakeet_ctc.h similarity index 100% rename from parakeet-cpp/src/parakeet_ctc.h rename to engines/parakeet/src/parakeet_ctc.h diff --git a/parakeet-cpp/src/parakeet_engine.cpp b/engines/parakeet/src/parakeet_engine.cpp similarity index 100% rename from parakeet-cpp/src/parakeet_engine.cpp rename to engines/parakeet/src/parakeet_engine.cpp diff --git a/parakeet-cpp/src/parakeet_eou.cpp b/engines/parakeet/src/parakeet_eou.cpp similarity index 100% rename from parakeet-cpp/src/parakeet_eou.cpp rename to engines/parakeet/src/parakeet_eou.cpp diff --git a/parakeet-cpp/src/parakeet_eou.h b/engines/parakeet/src/parakeet_eou.h similarity index 100% rename from parakeet-cpp/src/parakeet_eou.h rename to engines/parakeet/src/parakeet_eou.h diff --git a/parakeet-cpp/src/parakeet_log.cpp b/engines/parakeet/src/parakeet_log.cpp similarity index 100% rename from parakeet-cpp/src/parakeet_log.cpp rename to engines/parakeet/src/parakeet_log.cpp diff --git a/parakeet-cpp/src/parakeet_log.h b/engines/parakeet/src/parakeet_log.h similarity index 100% rename from parakeet-cpp/src/parakeet_log.h rename to engines/parakeet/src/parakeet_log.h diff --git a/parakeet-cpp/src/parakeet_sortformer.cpp b/engines/parakeet/src/parakeet_sortformer.cpp similarity index 100% rename from parakeet-cpp/src/parakeet_sortformer.cpp rename to engines/parakeet/src/parakeet_sortformer.cpp diff --git a/parakeet-cpp/src/parakeet_sortformer.h b/engines/parakeet/src/parakeet_sortformer.h similarity index 100% rename from parakeet-cpp/src/parakeet_sortformer.h rename to engines/parakeet/src/parakeet_sortformer.h diff --git a/parakeet-cpp/src/parakeet_tdt.cpp b/engines/parakeet/src/parakeet_tdt.cpp similarity index 100% rename from parakeet-cpp/src/parakeet_tdt.cpp rename to engines/parakeet/src/parakeet_tdt.cpp diff --git a/parakeet-cpp/src/parakeet_tdt.h b/engines/parakeet/src/parakeet_tdt.h similarity index 100% rename from parakeet-cpp/src/parakeet_tdt.h rename to engines/parakeet/src/parakeet_tdt.h diff --git a/parakeet-cpp/src/sentencepiece_bpe.cpp b/engines/parakeet/src/sentencepiece_bpe.cpp similarity index 100% rename from parakeet-cpp/src/sentencepiece_bpe.cpp rename to engines/parakeet/src/sentencepiece_bpe.cpp diff --git a/parakeet-cpp/src/sentencepiece_bpe.h b/engines/parakeet/src/sentencepiece_bpe.h similarity index 100% rename from parakeet-cpp/src/sentencepiece_bpe.h rename to engines/parakeet/src/sentencepiece_bpe.h diff --git a/parakeet-cpp/test/samples/abcba.rttm b/engines/parakeet/test/samples/abcba.rttm similarity index 100% rename from parakeet-cpp/test/samples/abcba.rttm rename to engines/parakeet/test/samples/abcba.rttm diff --git a/parakeet-cpp/test/samples/abcba.wav b/engines/parakeet/test/samples/abcba.wav similarity index 100% rename from parakeet-cpp/test/samples/abcba.wav rename to engines/parakeet/test/samples/abcba.wav diff --git a/parakeet-cpp/test/samples/abcdba.rttm b/engines/parakeet/test/samples/abcdba.rttm similarity index 100% rename from parakeet-cpp/test/samples/abcdba.rttm rename to engines/parakeet/test/samples/abcdba.rttm diff --git a/parakeet-cpp/test/samples/abcdba.wav b/engines/parakeet/test/samples/abcdba.wav similarity index 100% rename from parakeet-cpp/test/samples/abcdba.wav rename to engines/parakeet/test/samples/abcdba.wav diff --git a/parakeet-cpp/test/samples/diarization-sample-16k.wav b/engines/parakeet/test/samples/diarization-sample-16k.wav similarity index 100% rename from parakeet-cpp/test/samples/diarization-sample-16k.wav rename to engines/parakeet/test/samples/diarization-sample-16k.wav diff --git a/parakeet-cpp/test/samples/fr-multipiece-16k.wav b/engines/parakeet/test/samples/fr-multipiece-16k.wav similarity index 100% rename from parakeet-cpp/test/samples/fr-multipiece-16k.wav rename to engines/parakeet/test/samples/fr-multipiece-16k.wav diff --git a/parakeet-cpp/test/samples/jfk.wav b/engines/parakeet/test/samples/jfk.wav similarity index 100% rename from parakeet-cpp/test/samples/jfk.wav rename to engines/parakeet/test/samples/jfk.wav diff --git a/parakeet-cpp/test/samples/sample-16k.wav b/engines/parakeet/test/samples/sample-16k.wav similarity index 100% rename from parakeet-cpp/test/samples/sample-16k.wav rename to engines/parakeet/test/samples/sample-16k.wav diff --git a/parakeet-cpp/test/test_ctc.cpp b/engines/parakeet/test/test_ctc.cpp similarity index 100% rename from parakeet-cpp/test/test_ctc.cpp rename to engines/parakeet/test/test_ctc.cpp diff --git a/parakeet-cpp/test/test_decoder_determinism.cpp b/engines/parakeet/test/test_decoder_determinism.cpp similarity index 100% rename from parakeet-cpp/test/test_decoder_determinism.cpp rename to engines/parakeet/test/test_decoder_determinism.cpp diff --git a/parakeet-cpp/test/test_encoder.cpp b/engines/parakeet/test/test_encoder.cpp similarity index 100% rename from parakeet-cpp/test/test_encoder.cpp rename to engines/parakeet/test/test_encoder.cpp diff --git a/parakeet-cpp/test/test_encoder_capture_parity.cpp b/engines/parakeet/test/test_encoder_capture_parity.cpp similarity index 100% rename from parakeet-cpp/test/test_encoder_capture_parity.cpp rename to engines/parakeet/test/test_encoder_capture_parity.cpp diff --git a/parakeet-cpp/test/test_eou_decoder_parity.cpp b/engines/parakeet/test/test_eou_decoder_parity.cpp similarity index 100% rename from parakeet-cpp/test/test_eou_decoder_parity.cpp rename to engines/parakeet/test/test_eou_decoder_parity.cpp diff --git a/parakeet-cpp/test/test_eou_streaming.cpp b/engines/parakeet/test/test_eou_streaming.cpp similarity index 100% rename from parakeet-cpp/test/test_eou_streaming.cpp rename to engines/parakeet/test/test_eou_streaming.cpp diff --git a/parakeet-cpp/test/test_mel.cpp b/engines/parakeet/test/test_mel.cpp similarity index 100% rename from parakeet-cpp/test/test_mel.cpp rename to engines/parakeet/test/test_mel.cpp diff --git a/parakeet-cpp/test/test_mel_fft_parity.cpp b/engines/parakeet/test/test_mel_fft_parity.cpp similarity index 100% rename from parakeet-cpp/test/test_mel_fft_parity.cpp rename to engines/parakeet/test/test_mel_fft_parity.cpp diff --git a/parakeet-cpp/test/test_perf_regression.cpp b/engines/parakeet/test/test_perf_regression.cpp similarity index 100% rename from parakeet-cpp/test/test_perf_regression.cpp rename to engines/parakeet/test/test_perf_regression.cpp diff --git a/parakeet-cpp/test/test_sched_diarize_lifecycle.cpp b/engines/parakeet/test/test_sched_diarize_lifecycle.cpp similarity index 100% rename from parakeet-cpp/test/test_sched_diarize_lifecycle.cpp rename to engines/parakeet/test/test_sched_diarize_lifecycle.cpp diff --git a/parakeet-cpp/test/test_sched_encoder_determinism.cpp b/engines/parakeet/test/test_sched_encoder_determinism.cpp similarity index 100% rename from parakeet-cpp/test/test_sched_encoder_determinism.cpp rename to engines/parakeet/test/test_sched_encoder_determinism.cpp diff --git a/parakeet-cpp/test/test_sortformer_aosc_speakers.cpp b/engines/parakeet/test/test_sortformer_aosc_speakers.cpp similarity index 100% rename from parakeet-cpp/test/test_sortformer_aosc_speakers.cpp rename to engines/parakeet/test/test_sortformer_aosc_speakers.cpp diff --git a/parakeet-cpp/test/test_sortformer_parity.cpp b/engines/parakeet/test/test_sortformer_parity.cpp similarity index 100% rename from parakeet-cpp/test/test_sortformer_parity.cpp rename to engines/parakeet/test/test_sortformer_parity.cpp diff --git a/parakeet-cpp/test/test_sortformer_streaming.cpp b/engines/parakeet/test/test_sortformer_streaming.cpp similarity index 100% rename from parakeet-cpp/test/test_sortformer_streaming.cpp rename to engines/parakeet/test/test_sortformer_streaming.cpp diff --git a/parakeet-cpp/test/test_streaming.cpp b/engines/parakeet/test/test_streaming.cpp similarity index 100% rename from parakeet-cpp/test/test_streaming.cpp rename to engines/parakeet/test/test_streaming.cpp diff --git a/parakeet-cpp/test/test_tdt_decoder_parity.cpp b/engines/parakeet/test/test_tdt_decoder_parity.cpp similarity index 100% rename from parakeet-cpp/test/test_tdt_decoder_parity.cpp rename to engines/parakeet/test/test_tdt_decoder_parity.cpp diff --git a/parakeet-cpp/test/test_tdt_encoder_parity.cpp b/engines/parakeet/test/test_tdt_encoder_parity.cpp similarity index 100% rename from parakeet-cpp/test/test_tdt_encoder_parity.cpp rename to engines/parakeet/test/test_tdt_encoder_parity.cpp diff --git a/parakeet-cpp/test/test_utils.h b/engines/parakeet/test/test_utils.h similarity index 100% rename from parakeet-cpp/test/test_utils.h rename to engines/parakeet/test/test_utils.h diff --git a/parakeet-cpp/test/test_vk_vs_cpu.cpp b/engines/parakeet/test/test_vk_vs_cpu.cpp similarity index 100% rename from parakeet-cpp/test/test_vk_vs_cpu.cpp rename to engines/parakeet/test/test_vk_vs_cpu.cpp diff --git a/tts-cpp/.gitignore b/engines/tts/.gitignore similarity index 100% rename from tts-cpp/.gitignore rename to engines/tts/.gitignore diff --git a/tts-cpp/CMakeLists.txt b/engines/tts/CMakeLists.txt similarity index 100% rename from tts-cpp/CMakeLists.txt rename to engines/tts/CMakeLists.txt diff --git a/tts-cpp/LICENSE b/engines/tts/LICENSE similarity index 100% rename from tts-cpp/LICENSE rename to engines/tts/LICENSE diff --git a/tts-cpp/MEMORY.md b/engines/tts/MEMORY.md similarity index 100% rename from tts-cpp/MEMORY.md rename to engines/tts/MEMORY.md diff --git a/tts-cpp/NOTICE b/engines/tts/NOTICE similarity index 100% rename from tts-cpp/NOTICE rename to engines/tts/NOTICE diff --git a/tts-cpp/PROGRESS.md b/engines/tts/PROGRESS.md similarity index 100% rename from tts-cpp/PROGRESS.md rename to engines/tts/PROGRESS.md diff --git a/tts-cpp/PROGRESS_SUPERTONIC.md b/engines/tts/PROGRESS_SUPERTONIC.md similarity index 100% rename from tts-cpp/PROGRESS_SUPERTONIC.md rename to engines/tts/PROGRESS_SUPERTONIC.md diff --git a/tts-cpp/README.md b/engines/tts/README.md similarity index 100% rename from tts-cpp/README.md rename to engines/tts/README.md diff --git a/tts-cpp/cmake/tts-cppConfig.cmake.in b/engines/tts/cmake/tts-cppConfig.cmake.in similarity index 100% rename from tts-cpp/cmake/tts-cppConfig.cmake.in rename to engines/tts/cmake/tts-cppConfig.cmake.in diff --git a/tts-cpp/docs/voiceclone-backward-campplus.md b/engines/tts/docs/voiceclone-backward-campplus.md similarity index 100% rename from tts-cpp/docs/voiceclone-backward-campplus.md rename to engines/tts/docs/voiceclone-backward-campplus.md diff --git a/tts-cpp/docs/voiceclone-backward-gap-matrix.md b/engines/tts/docs/voiceclone-backward-gap-matrix.md similarity index 100% rename from tts-cpp/docs/voiceclone-backward-gap-matrix.md rename to engines/tts/docs/voiceclone-backward-gap-matrix.md diff --git a/tts-cpp/include/tts-cpp/backend.h b/engines/tts/include/tts-cpp/backend.h similarity index 100% rename from tts-cpp/include/tts-cpp/backend.h rename to engines/tts/include/tts-cpp/backend.h diff --git a/tts-cpp/include/tts-cpp/chatterbox/engine.h b/engines/tts/include/tts-cpp/chatterbox/engine.h similarity index 100% rename from tts-cpp/include/tts-cpp/chatterbox/engine.h rename to engines/tts/include/tts-cpp/chatterbox/engine.h diff --git a/tts-cpp/include/tts-cpp/chatterbox/s3gen_pipeline.h b/engines/tts/include/tts-cpp/chatterbox/s3gen_pipeline.h similarity index 100% rename from tts-cpp/include/tts-cpp/chatterbox/s3gen_pipeline.h rename to engines/tts/include/tts-cpp/chatterbox/s3gen_pipeline.h diff --git a/tts-cpp/include/tts-cpp/export.h b/engines/tts/include/tts-cpp/export.h similarity index 100% rename from tts-cpp/include/tts-cpp/export.h rename to engines/tts/include/tts-cpp/export.h diff --git a/tts-cpp/include/tts-cpp/lavasr/denoiser.h b/engines/tts/include/tts-cpp/lavasr/denoiser.h similarity index 100% rename from tts-cpp/include/tts-cpp/lavasr/denoiser.h rename to engines/tts/include/tts-cpp/lavasr/denoiser.h diff --git a/tts-cpp/include/tts-cpp/lavasr/enhancer.h b/engines/tts/include/tts-cpp/lavasr/enhancer.h similarity index 100% rename from tts-cpp/include/tts-cpp/lavasr/enhancer.h rename to engines/tts/include/tts-cpp/lavasr/enhancer.h diff --git a/tts-cpp/include/tts-cpp/log.h b/engines/tts/include/tts-cpp/log.h similarity index 100% rename from tts-cpp/include/tts-cpp/log.h rename to engines/tts/include/tts-cpp/log.h diff --git a/tts-cpp/include/tts-cpp/supertonic/engine.h b/engines/tts/include/tts-cpp/supertonic/engine.h similarity index 100% rename from tts-cpp/include/tts-cpp/supertonic/engine.h rename to engines/tts/include/tts-cpp/supertonic/engine.h diff --git a/tts-cpp/include/tts-cpp/tts-cpp.h b/engines/tts/include/tts-cpp/tts-cpp.h similarity index 100% rename from tts-cpp/include/tts-cpp/tts-cpp.h rename to engines/tts/include/tts-cpp/tts-cpp.h diff --git a/tts-cpp/scripts/bench-m4-validation.sh b/engines/tts/scripts/bench-m4-validation.sh similarity index 100% rename from tts-cpp/scripts/bench-m4-validation.sh rename to engines/tts/scripts/bench-m4-validation.sh diff --git a/tts-cpp/scripts/bench-supertonic-onnx.py b/engines/tts/scripts/bench-supertonic-onnx.py similarity index 100% rename from tts-cpp/scripts/bench-supertonic-onnx.py rename to engines/tts/scripts/bench-supertonic-onnx.py diff --git a/tts-cpp/scripts/build_cangjie_tsv.py b/engines/tts/scripts/build_cangjie_tsv.py similarity index 100% rename from tts-cpp/scripts/build_cangjie_tsv.py rename to engines/tts/scripts/build_cangjie_tsv.py diff --git a/tts-cpp/scripts/build_mecab_dict.py b/engines/tts/scripts/build_mecab_dict.py similarity index 100% rename from tts-cpp/scripts/build_mecab_dict.py rename to engines/tts/scripts/build_mecab_dict.py diff --git a/tts-cpp/scripts/compare-tokenizer.py b/engines/tts/scripts/compare-tokenizer.py similarity index 100% rename from tts-cpp/scripts/compare-tokenizer.py rename to engines/tts/scripts/compare-tokenizer.py diff --git a/tts-cpp/scripts/convert-lavasr-denoiser-to-gguf.py b/engines/tts/scripts/convert-lavasr-denoiser-to-gguf.py similarity index 100% rename from tts-cpp/scripts/convert-lavasr-denoiser-to-gguf.py rename to engines/tts/scripts/convert-lavasr-denoiser-to-gguf.py diff --git a/tts-cpp/scripts/convert-lavasr-enhancer-to-gguf.py b/engines/tts/scripts/convert-lavasr-enhancer-to-gguf.py similarity index 100% rename from tts-cpp/scripts/convert-lavasr-enhancer-to-gguf.py rename to engines/tts/scripts/convert-lavasr-enhancer-to-gguf.py diff --git a/tts-cpp/scripts/convert-s3gen-to-gguf.py b/engines/tts/scripts/convert-s3gen-to-gguf.py similarity index 100% rename from tts-cpp/scripts/convert-s3gen-to-gguf.py rename to engines/tts/scripts/convert-s3gen-to-gguf.py diff --git a/tts-cpp/scripts/convert-supertonic2-to-gguf.py b/engines/tts/scripts/convert-supertonic2-to-gguf.py similarity index 100% rename from tts-cpp/scripts/convert-supertonic2-to-gguf.py rename to engines/tts/scripts/convert-supertonic2-to-gguf.py diff --git a/tts-cpp/scripts/convert-t3-mtl-to-gguf.py b/engines/tts/scripts/convert-t3-mtl-to-gguf.py similarity index 100% rename from tts-cpp/scripts/convert-t3-mtl-to-gguf.py rename to engines/tts/scripts/convert-t3-mtl-to-gguf.py diff --git a/tts-cpp/scripts/convert-t3-turbo-to-gguf.py b/engines/tts/scripts/convert-t3-turbo-to-gguf.py similarity index 100% rename from tts-cpp/scripts/convert-t3-turbo-to-gguf.py rename to engines/tts/scripts/convert-t3-turbo-to-gguf.py diff --git a/tts-cpp/scripts/dump-campplus-reference.py b/engines/tts/scripts/dump-campplus-reference.py similarity index 100% rename from tts-cpp/scripts/dump-campplus-reference.py rename to engines/tts/scripts/dump-campplus-reference.py diff --git a/tts-cpp/scripts/dump-lavasr-denoiser-fixtures.py b/engines/tts/scripts/dump-lavasr-denoiser-fixtures.py similarity index 100% rename from tts-cpp/scripts/dump-lavasr-denoiser-fixtures.py rename to engines/tts/scripts/dump-lavasr-denoiser-fixtures.py diff --git a/tts-cpp/scripts/dump-lavasr-denoiser-pipeline-fixtures.py b/engines/tts/scripts/dump-lavasr-denoiser-pipeline-fixtures.py similarity index 100% rename from tts-cpp/scripts/dump-lavasr-denoiser-pipeline-fixtures.py rename to engines/tts/scripts/dump-lavasr-denoiser-pipeline-fixtures.py diff --git a/tts-cpp/scripts/dump-lavasr-enhancer-fixtures.py b/engines/tts/scripts/dump-lavasr-enhancer-fixtures.py similarity index 100% rename from tts-cpp/scripts/dump-lavasr-enhancer-fixtures.py rename to engines/tts/scripts/dump-lavasr-enhancer-fixtures.py diff --git a/tts-cpp/scripts/dump-s3gen-reference.py b/engines/tts/scripts/dump-s3gen-reference.py similarity index 100% rename from tts-cpp/scripts/dump-s3gen-reference.py rename to engines/tts/scripts/dump-s3gen-reference.py diff --git a/tts-cpp/scripts/dump-s3tokenizer-reference.py b/engines/tts/scripts/dump-s3tokenizer-reference.py similarity index 100% rename from tts-cpp/scripts/dump-s3tokenizer-reference.py rename to engines/tts/scripts/dump-s3tokenizer-reference.py diff --git a/tts-cpp/scripts/dump-streaming-reference.py b/engines/tts/scripts/dump-streaming-reference.py similarity index 100% rename from tts-cpp/scripts/dump-streaming-reference.py rename to engines/tts/scripts/dump-streaming-reference.py diff --git a/tts-cpp/scripts/dump-supertonic-reference.py b/engines/tts/scripts/dump-supertonic-reference.py similarity index 100% rename from tts-cpp/scripts/dump-supertonic-reference.py rename to engines/tts/scripts/dump-supertonic-reference.py diff --git a/tts-cpp/scripts/dump-t3-mtl-reference.py b/engines/tts/scripts/dump-t3-mtl-reference.py similarity index 100% rename from tts-cpp/scripts/dump-t3-mtl-reference.py rename to engines/tts/scripts/dump-t3-mtl-reference.py diff --git a/tts-cpp/scripts/dump-voiceclone-fixtures.py b/engines/tts/scripts/dump-voiceclone-fixtures.py similarity index 100% rename from tts-cpp/scripts/dump-voiceclone-fixtures.py rename to engines/tts/scripts/dump-voiceclone-fixtures.py diff --git a/tts-cpp/scripts/extract-voice.py b/engines/tts/scripts/extract-voice.py similarity index 100% rename from tts-cpp/scripts/extract-voice.py rename to engines/tts/scripts/extract-voice.py diff --git a/tts-cpp/scripts/gen-nfkd-table.py b/engines/tts/scripts/gen-nfkd-table.py similarity index 100% rename from tts-cpp/scripts/gen-nfkd-table.py rename to engines/tts/scripts/gen-nfkd-table.py diff --git a/tts-cpp/scripts/reference-t3-turbo.py b/engines/tts/scripts/reference-t3-turbo.py similarity index 100% rename from tts-cpp/scripts/reference-t3-turbo.py rename to engines/tts/scripts/reference-t3-turbo.py diff --git a/tts-cpp/scripts/requantize-gguf.py b/engines/tts/scripts/requantize-gguf.py similarity index 100% rename from tts-cpp/scripts/requantize-gguf.py rename to engines/tts/scripts/requantize-gguf.py diff --git a/tts-cpp/scripts/setup-ggml.sh b/engines/tts/scripts/setup-ggml.sh similarity index 100% rename from tts-cpp/scripts/setup-ggml.sh rename to engines/tts/scripts/setup-ggml.sh diff --git a/tts-cpp/scripts/setup-supertonic2.sh b/engines/tts/scripts/setup-supertonic2.sh similarity index 100% rename from tts-cpp/scripts/setup-supertonic2.sh rename to engines/tts/scripts/setup-supertonic2.sh diff --git a/tts-cpp/scripts/synthesize.sh b/engines/tts/scripts/synthesize.sh similarity index 100% rename from tts-cpp/scripts/synthesize.sh rename to engines/tts/scripts/synthesize.sh diff --git a/tts-cpp/scripts/validate-precision-parity.sh b/engines/tts/scripts/validate-precision-parity.sh similarity index 100% rename from tts-cpp/scripts/validate-precision-parity.sh rename to engines/tts/scripts/validate-precision-parity.sh diff --git a/tts-cpp/src/backend_selection.cpp b/engines/tts/src/backend_selection.cpp similarity index 100% rename from tts-cpp/src/backend_selection.cpp rename to engines/tts/src/backend_selection.cpp diff --git a/tts-cpp/src/backend_selection.h b/engines/tts/src/backend_selection.h similarity index 100% rename from tts-cpp/src/backend_selection.h rename to engines/tts/src/backend_selection.h diff --git a/tts-cpp/src/backend_util.h b/engines/tts/src/backend_util.h similarity index 100% rename from tts-cpp/src/backend_util.h rename to engines/tts/src/backend_util.h diff --git a/tts-cpp/src/campplus.cpp b/engines/tts/src/campplus.cpp similarity index 100% rename from tts-cpp/src/campplus.cpp rename to engines/tts/src/campplus.cpp diff --git a/tts-cpp/src/campplus.h b/engines/tts/src/campplus.h similarity index 100% rename from tts-cpp/src/campplus.h rename to engines/tts/src/campplus.h diff --git a/tts-cpp/src/campplus_backward.cpp b/engines/tts/src/campplus_backward.cpp similarity index 100% rename from tts-cpp/src/campplus_backward.cpp rename to engines/tts/src/campplus_backward.cpp diff --git a/tts-cpp/src/campplus_backward.h b/engines/tts/src/campplus_backward.h similarity index 100% rename from tts-cpp/src/campplus_backward.h rename to engines/tts/src/campplus_backward.h diff --git a/tts-cpp/src/campplus_forward.inc b/engines/tts/src/campplus_forward.inc similarity index 100% rename from tts-cpp/src/campplus_forward.inc rename to engines/tts/src/campplus_forward.inc diff --git a/tts-cpp/src/chatterbox_cli.cpp b/engines/tts/src/chatterbox_cli.cpp similarity index 100% rename from tts-cpp/src/chatterbox_cli.cpp rename to engines/tts/src/chatterbox_cli.cpp diff --git a/tts-cpp/src/chatterbox_engine.cpp b/engines/tts/src/chatterbox_engine.cpp similarity index 100% rename from tts-cpp/src/chatterbox_engine.cpp rename to engines/tts/src/chatterbox_engine.cpp diff --git a/tts-cpp/src/chatterbox_t3_internal.h b/engines/tts/src/chatterbox_t3_internal.h similarity index 100% rename from tts-cpp/src/chatterbox_t3_internal.h rename to engines/tts/src/chatterbox_t3_internal.h diff --git a/tts-cpp/src/chatterbox_tts.cpp b/engines/tts/src/chatterbox_tts.cpp similarity index 100% rename from tts-cpp/src/chatterbox_tts.cpp rename to engines/tts/src/chatterbox_tts.cpp diff --git a/tts-cpp/src/chatterbox_tts_test_hooks.h b/engines/tts/src/chatterbox_tts_test_hooks.h similarity index 100% rename from tts-cpp/src/chatterbox_tts_test_hooks.h rename to engines/tts/src/chatterbox_tts_test_hooks.h diff --git a/tts-cpp/src/cli_main.cpp b/engines/tts/src/cli_main.cpp similarity index 100% rename from tts-cpp/src/cli_main.cpp rename to engines/tts/src/cli_main.cpp diff --git a/tts-cpp/src/dr_wav.h b/engines/tts/src/dr_wav.h similarity index 100% rename from tts-cpp/src/dr_wav.h rename to engines/tts/src/dr_wav.h diff --git a/tts-cpp/src/gguf_stream.h b/engines/tts/src/gguf_stream.h similarity index 100% rename from tts-cpp/src/gguf_stream.h rename to engines/tts/src/gguf_stream.h diff --git a/tts-cpp/src/gpt2_bpe.cpp b/engines/tts/src/gpt2_bpe.cpp similarity index 100% rename from tts-cpp/src/gpt2_bpe.cpp rename to engines/tts/src/gpt2_bpe.cpp diff --git a/tts-cpp/src/gpt2_bpe.h b/engines/tts/src/gpt2_bpe.h similarity index 100% rename from tts-cpp/src/gpt2_bpe.h rename to engines/tts/src/gpt2_bpe.h diff --git a/tts-cpp/src/json.hpp b/engines/tts/src/json.hpp similarity index 100% rename from tts-cpp/src/json.hpp rename to engines/tts/src/json.hpp diff --git a/tts-cpp/src/lavasr/denoiser.cpp b/engines/tts/src/lavasr/denoiser.cpp similarity index 100% rename from tts-cpp/src/lavasr/denoiser.cpp rename to engines/tts/src/lavasr/denoiser.cpp diff --git a/tts-cpp/src/lavasr/denoiser.h b/engines/tts/src/lavasr/denoiser.h similarity index 100% rename from tts-cpp/src/lavasr/denoiser.h rename to engines/tts/src/lavasr/denoiser.h diff --git a/tts-cpp/src/lavasr/denoiser_api.cpp b/engines/tts/src/lavasr/denoiser_api.cpp similarity index 100% rename from tts-cpp/src/lavasr/denoiser_api.cpp rename to engines/tts/src/lavasr/denoiser_api.cpp diff --git a/tts-cpp/src/lavasr/denoiser_core.cpp b/engines/tts/src/lavasr/denoiser_core.cpp similarity index 100% rename from tts-cpp/src/lavasr/denoiser_core.cpp rename to engines/tts/src/lavasr/denoiser_core.cpp diff --git a/tts-cpp/src/lavasr/denoiser_core.h b/engines/tts/src/lavasr/denoiser_core.h similarity index 100% rename from tts-cpp/src/lavasr/denoiser_core.h rename to engines/tts/src/lavasr/denoiser_core.h diff --git a/tts-cpp/src/lavasr/denoiser_ggml.cpp b/engines/tts/src/lavasr/denoiser_ggml.cpp similarity index 100% rename from tts-cpp/src/lavasr/denoiser_ggml.cpp rename to engines/tts/src/lavasr/denoiser_ggml.cpp diff --git a/tts-cpp/src/lavasr/denoiser_ggml.h b/engines/tts/src/lavasr/denoiser_ggml.h similarity index 100% rename from tts-cpp/src/lavasr/denoiser_ggml.h rename to engines/tts/src/lavasr/denoiser_ggml.h diff --git a/tts-cpp/src/lavasr/denoiser_gguf.cpp b/engines/tts/src/lavasr/denoiser_gguf.cpp similarity index 100% rename from tts-cpp/src/lavasr/denoiser_gguf.cpp rename to engines/tts/src/lavasr/denoiser_gguf.cpp diff --git a/tts-cpp/src/lavasr/denoiser_gguf.h b/engines/tts/src/lavasr/denoiser_gguf.h similarity index 100% rename from tts-cpp/src/lavasr/denoiser_gguf.h rename to engines/tts/src/lavasr/denoiser_gguf.h diff --git a/tts-cpp/src/lavasr/dsp/dsp_constants.h b/engines/tts/src/lavasr/dsp/dsp_constants.h similarity index 100% rename from tts-cpp/src/lavasr/dsp/dsp_constants.h rename to engines/tts/src/lavasr/dsp/dsp_constants.h diff --git a/tts-cpp/src/lavasr/dsp/fastlr_merge.cpp b/engines/tts/src/lavasr/dsp/fastlr_merge.cpp similarity index 100% rename from tts-cpp/src/lavasr/dsp/fastlr_merge.cpp rename to engines/tts/src/lavasr/dsp/fastlr_merge.cpp diff --git a/tts-cpp/src/lavasr/dsp/fastlr_merge.h b/engines/tts/src/lavasr/dsp/fastlr_merge.h similarity index 100% rename from tts-cpp/src/lavasr/dsp/fastlr_merge.h rename to engines/tts/src/lavasr/dsp/fastlr_merge.h diff --git a/tts-cpp/src/lavasr/dsp/mel_filterbank.cpp b/engines/tts/src/lavasr/dsp/mel_filterbank.cpp similarity index 100% rename from tts-cpp/src/lavasr/dsp/mel_filterbank.cpp rename to engines/tts/src/lavasr/dsp/mel_filterbank.cpp diff --git a/tts-cpp/src/lavasr/dsp/mel_filterbank.h b/engines/tts/src/lavasr/dsp/mel_filterbank.h similarity index 100% rename from tts-cpp/src/lavasr/dsp/mel_filterbank.h rename to engines/tts/src/lavasr/dsp/mel_filterbank.h diff --git a/tts-cpp/src/lavasr/dsp/overlap_add.cpp b/engines/tts/src/lavasr/dsp/overlap_add.cpp similarity index 100% rename from tts-cpp/src/lavasr/dsp/overlap_add.cpp rename to engines/tts/src/lavasr/dsp/overlap_add.cpp diff --git a/tts-cpp/src/lavasr/dsp/overlap_add.h b/engines/tts/src/lavasr/dsp/overlap_add.h similarity index 100% rename from tts-cpp/src/lavasr/dsp/overlap_add.h rename to engines/tts/src/lavasr/dsp/overlap_add.h diff --git a/tts-cpp/src/lavasr/dsp/resampler.cpp b/engines/tts/src/lavasr/dsp/resampler.cpp similarity index 100% rename from tts-cpp/src/lavasr/dsp/resampler.cpp rename to engines/tts/src/lavasr/dsp/resampler.cpp diff --git a/tts-cpp/src/lavasr/dsp/resampler.h b/engines/tts/src/lavasr/dsp/resampler.h similarity index 100% rename from tts-cpp/src/lavasr/dsp/resampler.h rename to engines/tts/src/lavasr/dsp/resampler.h diff --git a/tts-cpp/src/lavasr/dsp/stft_processor.cpp b/engines/tts/src/lavasr/dsp/stft_processor.cpp similarity index 100% rename from tts-cpp/src/lavasr/dsp/stft_processor.cpp rename to engines/tts/src/lavasr/dsp/stft_processor.cpp diff --git a/tts-cpp/src/lavasr/dsp/stft_processor.h b/engines/tts/src/lavasr/dsp/stft_processor.h similarity index 100% rename from tts-cpp/src/lavasr/dsp/stft_processor.h rename to engines/tts/src/lavasr/dsp/stft_processor.h diff --git a/tts-cpp/src/lavasr/enhancer.cpp b/engines/tts/src/lavasr/enhancer.cpp similarity index 100% rename from tts-cpp/src/lavasr/enhancer.cpp rename to engines/tts/src/lavasr/enhancer.cpp diff --git a/tts-cpp/src/lavasr/enhancer.h b/engines/tts/src/lavasr/enhancer.h similarity index 100% rename from tts-cpp/src/lavasr/enhancer.h rename to engines/tts/src/lavasr/enhancer.h diff --git a/tts-cpp/src/lavasr/enhancer_api.cpp b/engines/tts/src/lavasr/enhancer_api.cpp similarity index 100% rename from tts-cpp/src/lavasr/enhancer_api.cpp rename to engines/tts/src/lavasr/enhancer_api.cpp diff --git a/tts-cpp/src/lavasr/enhancer_core.cpp b/engines/tts/src/lavasr/enhancer_core.cpp similarity index 100% rename from tts-cpp/src/lavasr/enhancer_core.cpp rename to engines/tts/src/lavasr/enhancer_core.cpp diff --git a/tts-cpp/src/lavasr/enhancer_core.h b/engines/tts/src/lavasr/enhancer_core.h similarity index 100% rename from tts-cpp/src/lavasr/enhancer_core.h rename to engines/tts/src/lavasr/enhancer_core.h diff --git a/tts-cpp/src/lavasr/enhancer_ggml.cpp b/engines/tts/src/lavasr/enhancer_ggml.cpp similarity index 100% rename from tts-cpp/src/lavasr/enhancer_ggml.cpp rename to engines/tts/src/lavasr/enhancer_ggml.cpp diff --git a/tts-cpp/src/lavasr/enhancer_ggml.h b/engines/tts/src/lavasr/enhancer_ggml.h similarity index 100% rename from tts-cpp/src/lavasr/enhancer_ggml.h rename to engines/tts/src/lavasr/enhancer_ggml.h diff --git a/tts-cpp/src/lavasr/enhancer_gguf.cpp b/engines/tts/src/lavasr/enhancer_gguf.cpp similarity index 100% rename from tts-cpp/src/lavasr/enhancer_gguf.cpp rename to engines/tts/src/lavasr/enhancer_gguf.cpp diff --git a/tts-cpp/src/lavasr/enhancer_gguf.h b/engines/tts/src/lavasr/enhancer_gguf.h similarity index 100% rename from tts-cpp/src/lavasr/enhancer_gguf.h rename to engines/tts/src/lavasr/enhancer_gguf.h diff --git a/tts-cpp/src/lavasr/lavasr_bench.cpp b/engines/tts/src/lavasr/lavasr_bench.cpp similarity index 100% rename from tts-cpp/src/lavasr/lavasr_bench.cpp rename to engines/tts/src/lavasr/lavasr_bench.cpp diff --git a/tts-cpp/src/log.cpp b/engines/tts/src/log.cpp similarity index 100% rename from tts-cpp/src/log.cpp rename to engines/tts/src/log.cpp diff --git a/tts-cpp/src/main.cpp b/engines/tts/src/main.cpp similarity index 100% rename from tts-cpp/src/main.cpp rename to engines/tts/src/main.cpp diff --git a/tts-cpp/src/mel2wav.cpp b/engines/tts/src/mel2wav.cpp similarity index 100% rename from tts-cpp/src/mel2wav.cpp rename to engines/tts/src/mel2wav.cpp diff --git a/tts-cpp/src/mel_extract_stft.cpp b/engines/tts/src/mel_extract_stft.cpp similarity index 100% rename from tts-cpp/src/mel_extract_stft.cpp rename to engines/tts/src/mel_extract_stft.cpp diff --git a/tts-cpp/src/mtl_tokenizer.cpp b/engines/tts/src/mtl_tokenizer.cpp similarity index 100% rename from tts-cpp/src/mtl_tokenizer.cpp rename to engines/tts/src/mtl_tokenizer.cpp diff --git a/tts-cpp/src/mtl_tokenizer.h b/engines/tts/src/mtl_tokenizer.h similarity index 100% rename from tts-cpp/src/mtl_tokenizer.h rename to engines/tts/src/mtl_tokenizer.h diff --git a/tts-cpp/src/mtl_unicode_tables.inc b/engines/tts/src/mtl_unicode_tables.inc similarity index 100% rename from tts-cpp/src/mtl_unicode_tables.inc rename to engines/tts/src/mtl_unicode_tables.inc diff --git a/tts-cpp/src/npy.h b/engines/tts/src/npy.h similarity index 100% rename from tts-cpp/src/npy.h rename to engines/tts/src/npy.h diff --git a/tts-cpp/src/s3tokenizer.cpp b/engines/tts/src/s3tokenizer.cpp similarity index 100% rename from tts-cpp/src/s3tokenizer.cpp rename to engines/tts/src/s3tokenizer.cpp diff --git a/tts-cpp/src/s3tokenizer.h b/engines/tts/src/s3tokenizer.h similarity index 100% rename from tts-cpp/src/s3tokenizer.h rename to engines/tts/src/s3tokenizer.h diff --git a/tts-cpp/src/sched_dispatch.cpp b/engines/tts/src/sched_dispatch.cpp similarity index 100% rename from tts-cpp/src/sched_dispatch.cpp rename to engines/tts/src/sched_dispatch.cpp diff --git a/tts-cpp/src/sched_dispatch.h b/engines/tts/src/sched_dispatch.h similarity index 100% rename from tts-cpp/src/sched_dispatch.h rename to engines/tts/src/sched_dispatch.h diff --git a/tts-cpp/src/supertonic_bench.cpp b/engines/tts/src/supertonic_bench.cpp similarity index 100% rename from tts-cpp/src/supertonic_bench.cpp rename to engines/tts/src/supertonic_bench.cpp diff --git a/tts-cpp/src/supertonic_chunker.cpp b/engines/tts/src/supertonic_chunker.cpp similarity index 100% rename from tts-cpp/src/supertonic_chunker.cpp rename to engines/tts/src/supertonic_chunker.cpp diff --git a/tts-cpp/src/supertonic_chunker.h b/engines/tts/src/supertonic_chunker.h similarity index 100% rename from tts-cpp/src/supertonic_chunker.h rename to engines/tts/src/supertonic_chunker.h diff --git a/tts-cpp/src/supertonic_cli.cpp b/engines/tts/src/supertonic_cli.cpp similarity index 100% rename from tts-cpp/src/supertonic_cli.cpp rename to engines/tts/src/supertonic_cli.cpp diff --git a/tts-cpp/src/supertonic_duration.cpp b/engines/tts/src/supertonic_duration.cpp similarity index 100% rename from tts-cpp/src/supertonic_duration.cpp rename to engines/tts/src/supertonic_duration.cpp diff --git a/tts-cpp/src/supertonic_engine.cpp b/engines/tts/src/supertonic_engine.cpp similarity index 100% rename from tts-cpp/src/supertonic_engine.cpp rename to engines/tts/src/supertonic_engine.cpp diff --git a/tts-cpp/src/supertonic_gguf.cpp b/engines/tts/src/supertonic_gguf.cpp similarity index 100% rename from tts-cpp/src/supertonic_gguf.cpp rename to engines/tts/src/supertonic_gguf.cpp diff --git a/tts-cpp/src/supertonic_internal.h b/engines/tts/src/supertonic_internal.h similarity index 100% rename from tts-cpp/src/supertonic_internal.h rename to engines/tts/src/supertonic_internal.h diff --git a/tts-cpp/src/supertonic_preprocess.cpp b/engines/tts/src/supertonic_preprocess.cpp similarity index 100% rename from tts-cpp/src/supertonic_preprocess.cpp rename to engines/tts/src/supertonic_preprocess.cpp diff --git a/tts-cpp/src/supertonic_text_encoder.cpp b/engines/tts/src/supertonic_text_encoder.cpp similarity index 100% rename from tts-cpp/src/supertonic_text_encoder.cpp rename to engines/tts/src/supertonic_text_encoder.cpp diff --git a/tts-cpp/src/supertonic_text_encoder_backward.cpp b/engines/tts/src/supertonic_text_encoder_backward.cpp similarity index 100% rename from tts-cpp/src/supertonic_text_encoder_backward.cpp rename to engines/tts/src/supertonic_text_encoder_backward.cpp diff --git a/tts-cpp/src/supertonic_text_encoder_backward.h b/engines/tts/src/supertonic_text_encoder_backward.h similarity index 100% rename from tts-cpp/src/supertonic_text_encoder_backward.h rename to engines/tts/src/supertonic_text_encoder_backward.h diff --git a/tts-cpp/src/supertonic_vector_estimator.cpp b/engines/tts/src/supertonic_vector_estimator.cpp similarity index 100% rename from tts-cpp/src/supertonic_vector_estimator.cpp rename to engines/tts/src/supertonic_vector_estimator.cpp diff --git a/tts-cpp/src/supertonic_vector_estimator_backward.cpp b/engines/tts/src/supertonic_vector_estimator_backward.cpp similarity index 100% rename from tts-cpp/src/supertonic_vector_estimator_backward.cpp rename to engines/tts/src/supertonic_vector_estimator_backward.cpp diff --git a/tts-cpp/src/supertonic_vector_estimator_backward.h b/engines/tts/src/supertonic_vector_estimator_backward.h similarity index 100% rename from tts-cpp/src/supertonic_vector_estimator_backward.h rename to engines/tts/src/supertonic_vector_estimator_backward.h diff --git a/tts-cpp/src/supertonic_vocoder.cpp b/engines/tts/src/supertonic_vocoder.cpp similarity index 100% rename from tts-cpp/src/supertonic_vocoder.cpp rename to engines/tts/src/supertonic_vocoder.cpp diff --git a/tts-cpp/src/supertonic_voice_json.cpp b/engines/tts/src/supertonic_voice_json.cpp similarity index 100% rename from tts-cpp/src/supertonic_voice_json.cpp rename to engines/tts/src/supertonic_voice_json.cpp diff --git a/tts-cpp/src/supertonic_voice_json.h b/engines/tts/src/supertonic_voice_json.h similarity index 100% rename from tts-cpp/src/supertonic_voice_json.h rename to engines/tts/src/supertonic_voice_json.h diff --git a/tts-cpp/src/t3_alignment_analyzer.cpp b/engines/tts/src/t3_alignment_analyzer.cpp similarity index 100% rename from tts-cpp/src/t3_alignment_analyzer.cpp rename to engines/tts/src/t3_alignment_analyzer.cpp diff --git a/tts-cpp/src/t3_alignment_analyzer.h b/engines/tts/src/t3_alignment_analyzer.h similarity index 100% rename from tts-cpp/src/t3_alignment_analyzer.h rename to engines/tts/src/t3_alignment_analyzer.h diff --git a/tts-cpp/src/t3_mtl.cpp b/engines/tts/src/t3_mtl.cpp similarity index 100% rename from tts-cpp/src/t3_mtl.cpp rename to engines/tts/src/t3_mtl.cpp diff --git a/tts-cpp/src/t3_mtl.h b/engines/tts/src/t3_mtl.h similarity index 100% rename from tts-cpp/src/t3_mtl.h rename to engines/tts/src/t3_mtl.h diff --git a/tts-cpp/src/t3_stop_controller.cpp b/engines/tts/src/t3_stop_controller.cpp similarity index 100% rename from tts-cpp/src/t3_stop_controller.cpp rename to engines/tts/src/t3_stop_controller.cpp diff --git a/tts-cpp/src/t3_stop_controller.h b/engines/tts/src/t3_stop_controller.h similarity index 100% rename from tts-cpp/src/t3_stop_controller.h rename to engines/tts/src/t3_stop_controller.h diff --git a/tts-cpp/src/text_preprocess.cpp b/engines/tts/src/text_preprocess.cpp similarity index 100% rename from tts-cpp/src/text_preprocess.cpp rename to engines/tts/src/text_preprocess.cpp diff --git a/tts-cpp/src/text_preprocess.h b/engines/tts/src/text_preprocess.h similarity index 100% rename from tts-cpp/src/text_preprocess.h rename to engines/tts/src/text_preprocess.h diff --git a/tts-cpp/src/voice_encoder.cpp b/engines/tts/src/voice_encoder.cpp similarity index 100% rename from tts-cpp/src/voice_encoder.cpp rename to engines/tts/src/voice_encoder.cpp diff --git a/tts-cpp/src/voice_encoder.h b/engines/tts/src/voice_encoder.h similarity index 100% rename from tts-cpp/src/voice_encoder.h rename to engines/tts/src/voice_encoder.h diff --git a/tts-cpp/src/voice_features.cpp b/engines/tts/src/voice_features.cpp similarity index 100% rename from tts-cpp/src/voice_features.cpp rename to engines/tts/src/voice_features.cpp diff --git a/tts-cpp/src/voice_features.h b/engines/tts/src/voice_features.h similarity index 100% rename from tts-cpp/src/voice_features.h rename to engines/tts/src/voice_features.h diff --git a/tts-cpp/src/voiceclone_gradcheck.cpp b/engines/tts/src/voiceclone_gradcheck.cpp similarity index 100% rename from tts-cpp/src/voiceclone_gradcheck.cpp rename to engines/tts/src/voiceclone_gradcheck.cpp diff --git a/tts-cpp/src/voiceclone_gradcheck.h b/engines/tts/src/voiceclone_gradcheck.h similarity index 100% rename from tts-cpp/src/voiceclone_gradcheck.h rename to engines/tts/src/voiceclone_gradcheck.h diff --git a/tts-cpp/src/voiceclone_metrics.cpp b/engines/tts/src/voiceclone_metrics.cpp similarity index 100% rename from tts-cpp/src/voiceclone_metrics.cpp rename to engines/tts/src/voiceclone_metrics.cpp diff --git a/tts-cpp/src/voiceclone_metrics.h b/engines/tts/src/voiceclone_metrics.h similarity index 100% rename from tts-cpp/src/voiceclone_metrics.h rename to engines/tts/src/voiceclone_metrics.h diff --git a/tts-cpp/test/fixtures/voiceclone/v1/README.md b/engines/tts/test/fixtures/voiceclone/v1/README.md similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/README.md rename to engines/tts/test/fixtures/voiceclone/v1/README.md diff --git a/tts-cpp/test/fixtures/voiceclone/v1/embed_a.npy b/engines/tts/test/fixtures/voiceclone/v1/embed_a.npy similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/embed_a.npy rename to engines/tts/test/fixtures/voiceclone/v1/embed_a.npy diff --git a/tts-cpp/test/fixtures/voiceclone/v1/embed_b.npy b/engines/tts/test/fixtures/voiceclone/v1/embed_b.npy similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/embed_b.npy rename to engines/tts/test/fixtures/voiceclone/v1/embed_b.npy diff --git a/tts-cpp/test/fixtures/voiceclone/v1/expected_cosine.npy b/engines/tts/test/fixtures/voiceclone/v1/expected_cosine.npy similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/expected_cosine.npy rename to engines/tts/test/fixtures/voiceclone/v1/expected_cosine.npy diff --git a/tts-cpp/test/fixtures/voiceclone/v1/expected_style_loss.npy b/engines/tts/test/fixtures/voiceclone/v1/expected_style_loss.npy similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/expected_style_loss.npy rename to engines/tts/test/fixtures/voiceclone/v1/expected_style_loss.npy diff --git a/tts-cpp/test/fixtures/voiceclone/v1/expected_wer.npy b/engines/tts/test/fixtures/voiceclone/v1/expected_wer.npy similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/expected_wer.npy rename to engines/tts/test/fixtures/voiceclone/v1/expected_wer.npy diff --git a/tts-cpp/test/fixtures/voiceclone/v1/hidden_ref.npy b/engines/tts/test/fixtures/voiceclone/v1/hidden_ref.npy similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/hidden_ref.npy rename to engines/tts/test/fixtures/voiceclone/v1/hidden_ref.npy diff --git a/tts-cpp/test/fixtures/voiceclone/v1/hidden_target.npy b/engines/tts/test/fixtures/voiceclone/v1/hidden_target.npy similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/hidden_target.npy rename to engines/tts/test/fixtures/voiceclone/v1/hidden_target.npy diff --git a/tts-cpp/test/fixtures/voiceclone/v1/wer_hyp.txt b/engines/tts/test/fixtures/voiceclone/v1/wer_hyp.txt similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/wer_hyp.txt rename to engines/tts/test/fixtures/voiceclone/v1/wer_hyp.txt diff --git a/tts-cpp/test/fixtures/voiceclone/v1/wer_ref.txt b/engines/tts/test/fixtures/voiceclone/v1/wer_ref.txt similarity index 100% rename from tts-cpp/test/fixtures/voiceclone/v1/wer_ref.txt rename to engines/tts/test/fixtures/voiceclone/v1/wer_ref.txt diff --git a/tts-cpp/test/test_campplus.cpp b/engines/tts/test/test_campplus.cpp similarity index 100% rename from tts-cpp/test/test_campplus.cpp rename to engines/tts/test/test_campplus.cpp diff --git a/tts-cpp/test/test_campplus_backward.cpp b/engines/tts/test/test_campplus_backward.cpp similarity index 100% rename from tts-cpp/test/test_campplus_backward.cpp rename to engines/tts/test/test_campplus_backward.cpp diff --git a/tts-cpp/test/test_campplus_backward_parity.cpp b/engines/tts/test/test_campplus_backward_parity.cpp similarity index 100% rename from tts-cpp/test/test_campplus_backward_parity.cpp rename to engines/tts/test/test_campplus_backward_parity.cpp diff --git a/tts-cpp/test/test_chatterbox_engine_stream.cpp b/engines/tts/test/test_chatterbox_engine_stream.cpp similarity index 100% rename from tts-cpp/test/test_chatterbox_engine_stream.cpp rename to engines/tts/test/test_chatterbox_engine_stream.cpp diff --git a/tts-cpp/test/test_cpu_caches.cpp b/engines/tts/test/test_cpu_caches.cpp similarity index 100% rename from tts-cpp/test/test_cpu_caches.cpp rename to engines/tts/test/test_cpu_caches.cpp diff --git a/tts-cpp/test/test_eos_roundtrip.cpp b/engines/tts/test/test_eos_roundtrip.cpp similarity index 100% rename from tts-cpp/test/test_eos_roundtrip.cpp rename to engines/tts/test/test_eos_roundtrip.cpp diff --git a/tts-cpp/test/test_fbank.cpp b/engines/tts/test/test_fbank.cpp similarity index 100% rename from tts-cpp/test/test_fbank.cpp rename to engines/tts/test/test_fbank.cpp diff --git a/tts-cpp/test/test_gguf_stream.cpp b/engines/tts/test/test_gguf_stream.cpp similarity index 100% rename from tts-cpp/test/test_gguf_stream.cpp rename to engines/tts/test/test_gguf_stream.cpp diff --git a/tts-cpp/test/test_kv_cache_type.cpp b/engines/tts/test/test_kv_cache_type.cpp similarity index 100% rename from tts-cpp/test/test_kv_cache_type.cpp rename to engines/tts/test/test_kv_cache_type.cpp diff --git a/tts-cpp/test/test_lavasr_denoiser_ggml.cpp b/engines/tts/test/test_lavasr_denoiser_ggml.cpp similarity index 100% rename from tts-cpp/test/test_lavasr_denoiser_ggml.cpp rename to engines/tts/test/test_lavasr_denoiser_ggml.cpp diff --git a/tts-cpp/test/test_lavasr_denoiser_gguf.cpp b/engines/tts/test/test_lavasr_denoiser_gguf.cpp similarity index 100% rename from tts-cpp/test/test_lavasr_denoiser_gguf.cpp rename to engines/tts/test/test_lavasr_denoiser_gguf.cpp diff --git a/tts-cpp/test/test_lavasr_dsp.cpp b/engines/tts/test/test_lavasr_dsp.cpp similarity index 100% rename from tts-cpp/test/test_lavasr_dsp.cpp rename to engines/tts/test/test_lavasr_dsp.cpp diff --git a/tts-cpp/test/test_lavasr_enhancer_core.cpp b/engines/tts/test/test_lavasr_enhancer_core.cpp similarity index 100% rename from tts-cpp/test/test_lavasr_enhancer_core.cpp rename to engines/tts/test/test_lavasr_enhancer_core.cpp diff --git a/tts-cpp/test/test_lavasr_enhancer_ggml.cpp b/engines/tts/test/test_lavasr_enhancer_ggml.cpp similarity index 100% rename from tts-cpp/test/test_lavasr_enhancer_ggml.cpp rename to engines/tts/test/test_lavasr_enhancer_ggml.cpp diff --git a/tts-cpp/test/test_lavasr_enhancer_gguf.cpp b/engines/tts/test/test_lavasr_enhancer_gguf.cpp similarity index 100% rename from tts-cpp/test/test_lavasr_enhancer_gguf.cpp rename to engines/tts/test/test_lavasr_enhancer_gguf.cpp diff --git a/tts-cpp/test/test_metal_ops.cpp b/engines/tts/test/test_metal_ops.cpp similarity index 100% rename from tts-cpp/test/test_metal_ops.cpp rename to engines/tts/test/test_metal_ops.cpp diff --git a/tts-cpp/test/test_mtl_sampler.cpp b/engines/tts/test/test_mtl_sampler.cpp similarity index 100% rename from tts-cpp/test/test_mtl_sampler.cpp rename to engines/tts/test/test_mtl_sampler.cpp diff --git a/tts-cpp/test/test_mtl_tokenizer.cpp b/engines/tts/test/test_mtl_tokenizer.cpp similarity index 100% rename from tts-cpp/test/test_mtl_tokenizer.cpp rename to engines/tts/test/test_mtl_tokenizer.cpp diff --git a/tts-cpp/test/test_multilingual_asr.cpp b/engines/tts/test/test_multilingual_asr.cpp similarity index 100% rename from tts-cpp/test/test_multilingual_asr.cpp rename to engines/tts/test/test_multilingual_asr.cpp diff --git a/tts-cpp/test/test_multilingual_synth.cpp b/engines/tts/test/test_multilingual_synth.cpp similarity index 100% rename from tts-cpp/test/test_multilingual_synth.cpp rename to engines/tts/test/test_multilingual_synth.cpp diff --git a/tts-cpp/test/test_output_sample_rate.cpp b/engines/tts/test/test_output_sample_rate.cpp similarity index 100% rename from tts-cpp/test/test_output_sample_rate.cpp rename to engines/tts/test/test_output_sample_rate.cpp diff --git a/tts-cpp/test/test_output_sample_rate_supertonic.cpp b/engines/tts/test/test_output_sample_rate_supertonic.cpp similarity index 100% rename from tts-cpp/test/test_output_sample_rate_supertonic.cpp rename to engines/tts/test/test_output_sample_rate_supertonic.cpp diff --git a/tts-cpp/test/test_resample.cpp b/engines/tts/test/test_resample.cpp similarity index 100% rename from tts-cpp/test/test_resample.cpp rename to engines/tts/test/test_resample.cpp diff --git a/tts-cpp/test/test_s3gen.cpp b/engines/tts/test/test_s3gen.cpp similarity index 100% rename from tts-cpp/test/test_s3gen.cpp rename to engines/tts/test/test_s3gen.cpp diff --git a/tts-cpp/test/test_s3gen_cfg_rate.cpp b/engines/tts/test/test_s3gen_cfg_rate.cpp similarity index 100% rename from tts-cpp/test/test_s3gen_cfg_rate.cpp rename to engines/tts/test/test_s3gen_cfg_rate.cpp diff --git a/tts-cpp/test/test_s3gen_sched_equivalence.cpp b/engines/tts/test/test_s3gen_sched_equivalence.cpp similarity index 100% rename from tts-cpp/test/test_s3gen_sched_equivalence.cpp rename to engines/tts/test/test_s3gen_sched_equivalence.cpp diff --git a/tts-cpp/test/test_s3tokenizer.cpp b/engines/tts/test/test_s3tokenizer.cpp similarity index 100% rename from tts-cpp/test/test_s3tokenizer.cpp rename to engines/tts/test/test_s3tokenizer.cpp diff --git a/tts-cpp/test/test_streaming.cpp b/engines/tts/test/test_streaming.cpp similarity index 100% rename from tts-cpp/test/test_streaming.cpp rename to engines/tts/test/test_streaming.cpp diff --git a/tts-cpp/test/test_streaming_loudness.cpp b/engines/tts/test/test_streaming_loudness.cpp similarity index 100% rename from tts-cpp/test/test_streaming_loudness.cpp rename to engines/tts/test/test_streaming_loudness.cpp diff --git a/tts-cpp/test/test_supertonic_audit3_caches.cpp b/engines/tts/test/test_supertonic_audit3_caches.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_audit3_caches.cpp rename to engines/tts/test/test_supertonic_audit3_caches.cpp diff --git a/tts-cpp/test/test_supertonic_backend_dispatch.cpp b/engines/tts/test/test_supertonic_backend_dispatch.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_backend_dispatch.cpp rename to engines/tts/test/test_supertonic_backend_dispatch.cpp diff --git a/tts-cpp/test/test_supertonic_capability_cache.cpp b/engines/tts/test/test_supertonic_capability_cache.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_capability_cache.cpp rename to engines/tts/test/test_supertonic_capability_cache.cpp diff --git a/tts-cpp/test/test_supertonic_convnext_block_fused.cpp b/engines/tts/test/test_supertonic_convnext_block_fused.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_convnext_block_fused.cpp rename to engines/tts/test/test_supertonic_convnext_block_fused.cpp diff --git a/tts-cpp/test/test_supertonic_duration.cpp b/engines/tts/test/test_supertonic_duration.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_duration.cpp rename to engines/tts/test/test_supertonic_duration.cpp diff --git a/tts-cpp/test/test_supertonic_duration_trace.cpp b/engines/tts/test/test_supertonic_duration_trace.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_duration_trace.cpp rename to engines/tts/test/test_supertonic_duration_trace.cpp diff --git a/tts-cpp/test/test_supertonic_engine_cycle.cpp b/engines/tts/test/test_supertonic_engine_cycle.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_engine_cycle.cpp rename to engines/tts/test/test_supertonic_engine_cycle.cpp diff --git a/tts-cpp/test/test_supertonic_external_voice.cpp b/engines/tts/test/test_supertonic_external_voice.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_external_voice.cpp rename to engines/tts/test/test_supertonic_external_voice.cpp diff --git a/tts-cpp/test/test_supertonic_f16_attn_parity.cpp b/engines/tts/test/test_supertonic_f16_attn_parity.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_f16_attn_parity.cpp rename to engines/tts/test/test_supertonic_f16_attn_parity.cpp diff --git a/tts-cpp/test/test_supertonic_f16_deny_list_api.cpp b/engines/tts/test/test_supertonic_f16_deny_list_api.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_f16_deny_list_api.cpp rename to engines/tts/test/test_supertonic_f16_deny_list_api.cpp diff --git a/tts-cpp/test/test_supertonic_f16_weights.cpp b/engines/tts/test/test_supertonic_f16_weights.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_f16_weights.cpp rename to engines/tts/test/test_supertonic_f16_weights.cpp diff --git a/tts-cpp/test/test_supertonic_graph_rewrites.cpp b/engines/tts/test/test_supertonic_graph_rewrites.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_graph_rewrites.cpp rename to engines/tts/test/test_supertonic_graph_rewrites.cpp diff --git a/tts-cpp/test/test_supertonic_graph_to_graph_blit.cpp b/engines/tts/test/test_supertonic_graph_to_graph_blit.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_graph_to_graph_blit.cpp rename to engines/tts/test/test_supertonic_graph_to_graph_blit.cpp diff --git a/tts-cpp/test/test_supertonic_in_graph_transpose.cpp b/engines/tts/test/test_supertonic_in_graph_transpose.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_in_graph_transpose.cpp rename to engines/tts/test/test_supertonic_in_graph_transpose.cpp diff --git a/tts-cpp/test/test_supertonic_input_scratchpad.cpp b/engines/tts/test/test_supertonic_input_scratchpad.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_input_scratchpad.cpp rename to engines/tts/test/test_supertonic_input_scratchpad.cpp diff --git a/tts-cpp/test/test_supertonic_kv_attn_type.cpp b/engines/tts/test/test_supertonic_kv_attn_type.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_kv_attn_type.cpp rename to engines/tts/test/test_supertonic_kv_attn_type.cpp diff --git a/tts-cpp/test/test_supertonic_kv_attn_type_api.cpp b/engines/tts/test/test_supertonic_kv_attn_type_api.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_kv_attn_type_api.cpp rename to engines/tts/test/test_supertonic_kv_attn_type_api.cpp diff --git a/tts-cpp/test/test_supertonic_languages.cpp b/engines/tts/test/test_supertonic_languages.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_languages.cpp rename to engines/tts/test/test_supertonic_languages.cpp diff --git a/tts-cpp/test/test_supertonic_load_caches.cpp b/engines/tts/test/test_supertonic_load_caches.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_load_caches.cpp rename to engines/tts/test/test_supertonic_load_caches.cpp diff --git a/tts-cpp/test/test_supertonic_pinned_host_buffer.cpp b/engines/tts/test/test_supertonic_pinned_host_buffer.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_pinned_host_buffer.cpp rename to engines/tts/test/test_supertonic_pinned_host_buffer.cpp diff --git a/tts-cpp/test/test_supertonic_pipeline.cpp b/engines/tts/test/test_supertonic_pipeline.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_pipeline.cpp rename to engines/tts/test/test_supertonic_pipeline.cpp diff --git a/tts-cpp/test/test_supertonic_portable_ops.cpp b/engines/tts/test/test_supertonic_portable_ops.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_portable_ops.cpp rename to engines/tts/test/test_supertonic_portable_ops.cpp diff --git a/tts-cpp/test/test_supertonic_preprocess.cpp b/engines/tts/test/test_supertonic_preprocess.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_preprocess.cpp rename to engines/tts/test/test_supertonic_preprocess.cpp diff --git a/tts-cpp/test/test_supertonic_profile_csv.cpp b/engines/tts/test/test_supertonic_profile_csv.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_profile_csv.cpp rename to engines/tts/test/test_supertonic_profile_csv.cpp diff --git a/tts-cpp/test/test_supertonic_rope_in_graph.cpp b/engines/tts/test/test_supertonic_rope_in_graph.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_rope_in_graph.cpp rename to engines/tts/test/test_supertonic_rope_in_graph.cpp diff --git a/tts-cpp/test/test_supertonic_rope_packed_qk.cpp b/engines/tts/test/test_supertonic_rope_packed_qk.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_rope_packed_qk.cpp rename to engines/tts/test/test_supertonic_rope_packed_qk.cpp diff --git a/tts-cpp/test/test_supertonic_sched_equivalence.cpp b/engines/tts/test/test_supertonic_sched_equivalence.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_sched_equivalence.cpp rename to engines/tts/test/test_supertonic_sched_equivalence.cpp diff --git a/tts-cpp/test/test_supertonic_text_encoder.cpp b/engines/tts/test/test_supertonic_text_encoder.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_text_encoder.cpp rename to engines/tts/test/test_supertonic_text_encoder.cpp diff --git a/tts-cpp/test/test_supertonic_text_encoder_backward.cpp b/engines/tts/test/test_supertonic_text_encoder_backward.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_text_encoder_backward.cpp rename to engines/tts/test/test_supertonic_text_encoder_backward.cpp diff --git a/tts-cpp/test/test_supertonic_text_encoder_caches.cpp b/engines/tts/test/test_supertonic_text_encoder_caches.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_text_encoder_caches.cpp rename to engines/tts/test/test_supertonic_text_encoder_caches.cpp diff --git a/tts-cpp/test/test_supertonic_text_encoder_gpu_bridge.cpp b/engines/tts/test/test_supertonic_text_encoder_gpu_bridge.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_text_encoder_gpu_bridge.cpp rename to engines/tts/test/test_supertonic_text_encoder_gpu_bridge.cpp diff --git a/tts-cpp/test/test_supertonic_text_encoder_trace.cpp b/engines/tts/test/test_supertonic_text_encoder_trace.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_text_encoder_trace.cpp rename to engines/tts/test/test_supertonic_text_encoder_trace.cpp diff --git a/tts-cpp/test/test_supertonic_upload_skip_tracker.cpp b/engines/tts/test/test_supertonic_upload_skip_tracker.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_upload_skip_tracker.cpp rename to engines/tts/test/test_supertonic_upload_skip_tracker.cpp diff --git a/tts-cpp/test/test_supertonic_vector.cpp b/engines/tts/test/test_supertonic_vector.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_vector.cpp rename to engines/tts/test/test_supertonic_vector.cpp diff --git a/tts-cpp/test/test_supertonic_vector_estimator_backward.cpp b/engines/tts/test/test_supertonic_vector_estimator_backward.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_vector_estimator_backward.cpp rename to engines/tts/test/test_supertonic_vector_estimator_backward.cpp diff --git a/tts-cpp/test/test_supertonic_vector_trace.cpp b/engines/tts/test/test_supertonic_vector_trace.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_vector_trace.cpp rename to engines/tts/test/test_supertonic_vector_trace.cpp diff --git a/tts-cpp/test/test_supertonic_vocoder.cpp b/engines/tts/test/test_supertonic_vocoder.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_vocoder.cpp rename to engines/tts/test/test_supertonic_vocoder.cpp diff --git a/tts-cpp/test/test_supertonic_vocoder_pointwise.cpp b/engines/tts/test/test_supertonic_vocoder_pointwise.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_vocoder_pointwise.cpp rename to engines/tts/test/test_supertonic_vocoder_pointwise.cpp diff --git a/tts-cpp/test/test_supertonic_vocoder_trace.cpp b/engines/tts/test/test_supertonic_vocoder_trace.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_vocoder_trace.cpp rename to engines/tts/test/test_supertonic_vocoder_trace.cpp diff --git a/tts-cpp/test/test_supertonic_voice_host_cache.cpp b/engines/tts/test/test_supertonic_voice_host_cache.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_voice_host_cache.cpp rename to engines/tts/test/test_supertonic_voice_host_cache.cpp diff --git a/tts-cpp/test/test_supertonic_vulkan_device_select.cpp b/engines/tts/test/test_supertonic_vulkan_device_select.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_vulkan_device_select.cpp rename to engines/tts/test/test_supertonic_vulkan_device_select.cpp diff --git a/tts-cpp/test/test_supertonic_vulkan_dispatch.cpp b/engines/tts/test/test_supertonic_vulkan_dispatch.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_vulkan_dispatch.cpp rename to engines/tts/test/test_supertonic_vulkan_dispatch.cpp diff --git a/tts-cpp/test/test_supertonic_vulkan_env_overrides.cpp b/engines/tts/test/test_supertonic_vulkan_env_overrides.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_vulkan_env_overrides.cpp rename to engines/tts/test/test_supertonic_vulkan_env_overrides.cpp diff --git a/tts-cpp/test/test_supertonic_warm_up_api.cpp b/engines/tts/test/test_supertonic_warm_up_api.cpp similarity index 100% rename from tts-cpp/test/test_supertonic_warm_up_api.cpp rename to engines/tts/test/test_supertonic_warm_up_api.cpp diff --git a/tts-cpp/test/test_t3_alignment_analyzer.cpp b/engines/tts/test/test_t3_alignment_analyzer.cpp similarity index 100% rename from tts-cpp/test/test_t3_alignment_analyzer.cpp rename to engines/tts/test/test_t3_alignment_analyzer.cpp diff --git a/tts-cpp/test/test_t3_caches.cpp b/engines/tts/test/test_t3_caches.cpp similarity index 100% rename from tts-cpp/test/test_t3_caches.cpp rename to engines/tts/test/test_t3_caches.cpp diff --git a/tts-cpp/test/test_t3_mtl.cpp b/engines/tts/test/test_t3_mtl.cpp similarity index 100% rename from tts-cpp/test/test_t3_mtl.cpp rename to engines/tts/test/test_t3_mtl.cpp diff --git a/tts-cpp/test/test_t3_mtl_stages.cpp b/engines/tts/test/test_t3_mtl_stages.cpp similarity index 100% rename from tts-cpp/test/test_t3_mtl_stages.cpp rename to engines/tts/test/test_t3_mtl_stages.cpp diff --git a/tts-cpp/test/test_t3_sched_dispatch.cpp b/engines/tts/test/test_t3_sched_dispatch.cpp similarity index 100% rename from tts-cpp/test/test_t3_sched_dispatch.cpp rename to engines/tts/test/test_t3_sched_dispatch.cpp diff --git a/tts-cpp/test/test_t3_sched_equivalence.cpp b/engines/tts/test/test_t3_sched_equivalence.cpp similarity index 100% rename from tts-cpp/test/test_t3_sched_equivalence.cpp rename to engines/tts/test/test_t3_sched_equivalence.cpp diff --git a/tts-cpp/test/test_t3_sched_migration.cpp b/engines/tts/test/test_t3_sched_migration.cpp similarity index 100% rename from tts-cpp/test/test_t3_sched_migration.cpp rename to engines/tts/test/test_t3_sched_migration.cpp diff --git a/tts-cpp/test/test_t3_stop_controller.cpp b/engines/tts/test/test_t3_stop_controller.cpp similarity index 100% rename from tts-cpp/test/test_t3_stop_controller.cpp rename to engines/tts/test/test_t3_stop_controller.cpp diff --git a/tts-cpp/test/test_text_split.cpp b/engines/tts/test/test_text_split.cpp similarity index 100% rename from tts-cpp/test/test_text_split.cpp rename to engines/tts/test/test_text_split.cpp diff --git a/tts-cpp/test/test_voice_embedding.cpp b/engines/tts/test/test_voice_embedding.cpp similarity index 100% rename from tts-cpp/test/test_voice_embedding.cpp rename to engines/tts/test/test_voice_embedding.cpp diff --git a/tts-cpp/test/test_voice_encoder.cpp b/engines/tts/test/test_voice_encoder.cpp similarity index 100% rename from tts-cpp/test/test_voice_encoder.cpp rename to engines/tts/test/test_voice_encoder.cpp diff --git a/tts-cpp/test/test_voice_features.cpp b/engines/tts/test/test_voice_features.cpp similarity index 100% rename from tts-cpp/test/test_voice_features.cpp rename to engines/tts/test/test_voice_features.cpp diff --git a/tts-cpp/test/test_voiceclone_gradcheck.cpp b/engines/tts/test/test_voiceclone_gradcheck.cpp similarity index 100% rename from tts-cpp/test/test_voiceclone_gradcheck.cpp rename to engines/tts/test/test_voiceclone_gradcheck.cpp diff --git a/tts-cpp/test/test_voiceclone_metrics.cpp b/engines/tts/test/test_voiceclone_metrics.cpp similarity index 100% rename from tts-cpp/test/test_voiceclone_metrics.cpp rename to engines/tts/test/test_voiceclone_metrics.cpp From cb84e0c3dde2c8e1b46ed4198b305ff4bb9b8c94 Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Fri, 17 Jul 2026 10:32:37 +0100 Subject: [PATCH 06/10] ci: point workflows at engines/parakeet and engines/tts Path-filter and source-dir fixups for the rename-only move in the previous commit. No workflow logic changes. Co-Authored-By: Claude Fable 5 --- .github/workflows/engines-cross-ci.yml | 24 ++++++++++++------------ .github/workflows/parakeet-ci.yml | 14 +++++++------- .github/workflows/tts-ci.yml | 12 ++++++------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/engines-cross-ci.yml b/.github/workflows/engines-cross-ci.yml index ba3afd8791b..21c166f03fa 100644 --- a/.github/workflows/engines-cross-ci.yml +++ b/.github/workflows/engines-cross-ci.yml @@ -1,5 +1,5 @@ -# Cross-platform lanes for the engines (parakeet-cpp/, tts-cpp/ — engines/* -# after the repo reorg QIP; update the path filters + SRC map when it lands). +# Cross-platform lanes for the engines (engines/parakeet/, engines/tts/ — +# moved from parakeet-cpp/, tts-cpp/ by the repo reorg QIP, PR 1). # # Complements parakeet-ci.yml / tts-ci.yml (linux+mac build+test): # - windows: full build + non-GPU ctest (MSVC, static ggml) @@ -14,13 +14,13 @@ on: push: branches: [master] paths: - - 'parakeet-cpp/**' - - 'tts-cpp/**' + - 'engines/parakeet/**' + - 'engines/tts/**' - '.github/workflows/engines-cross-ci.yml' pull_request: paths: - - 'parakeet-cpp/**' - - 'tts-cpp/**' + - 'engines/parakeet/**' + - 'engines/tts/**' - '.github/workflows/engines-cross-ci.yml' workflow_dispatch: @@ -43,10 +43,10 @@ jobs: engine: [parakeet, tts] include: - engine: parakeet - src: parakeet-cpp + src: engines/parakeet cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=ON - engine: tts - src: tts-cpp + src: engines/tts cmake_flags: -DTTS_CPP_BUILD_TESTS=ON runs-on: windows-2022 timeout-minutes: 90 @@ -99,10 +99,10 @@ jobs: engine: [parakeet, tts] include: - engine: parakeet - src: parakeet-cpp + src: engines/parakeet cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=OFF - engine: tts - src: tts-cpp + src: engines/tts cmake_flags: -DTTS_CPP_BUILD_TESTS=OFF runs-on: ubuntu-24.04 timeout-minutes: 60 @@ -158,10 +158,10 @@ jobs: engine: [parakeet, tts] include: - engine: parakeet - src: parakeet-cpp + src: engines/parakeet cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=OFF - engine: tts - src: tts-cpp + src: engines/tts cmake_flags: -DTTS_CPP_BUILD_TESTS=OFF runs-on: macos-14 timeout-minutes: 60 diff --git a/.github/workflows/parakeet-ci.yml b/.github/workflows/parakeet-ci.yml index b84d15f1446..55574f0b326 100644 --- a/.github/workflows/parakeet-ci.yml +++ b/.github/workflows/parakeet-ci.yml @@ -1,5 +1,5 @@ -# CI for the parakeet engine (parakeet-cpp/ — engines/parakeet/ after the -# repo reorg QIP lands; update the path filters below when it does). +# CI for the parakeet engine (engines/parakeet/ — moved from parakeet-cpp/ +# by the repo reorg QIP, PR 1). # # Scope (QIP "PR 0" lane): build the engine + every test harness against # system ggml (qvac-ext-ggml @ speech, the same fork the ggml-speech vcpkg @@ -14,11 +14,11 @@ on: push: branches: [master] paths: - - 'parakeet-cpp/**' + - 'engines/parakeet/**' - '.github/workflows/parakeet-ci.yml' pull_request: paths: - - 'parakeet-cpp/**' + - 'engines/parakeet/**' - '.github/workflows/parakeet-ci.yml' workflow_dispatch: inputs: @@ -36,7 +36,7 @@ concurrency: env: GGML_REPO: https://github.com/tetherto/qvac-ext-ggml.git - GGML_BRANCH: speech # keep in sync with parakeet-cpp/scripts/setup-ggml.sh + GGML_BRANCH: speech # keep in sync with engines/parakeet/scripts/setup-ggml.sh jobs: build-test: @@ -91,7 +91,7 @@ jobs: - name: Configure run: | - cmake -S parakeet-cpp -B build \ + cmake -S engines/parakeet -B build \ -DCMAKE_BUILD_TYPE=Release \ -DPARAKEET_USE_SYSTEM_GGML=ON \ -DPARAKEET_BUILD_TESTS=ON \ @@ -127,7 +127,7 @@ jobs: cmake -S ggml-src -B ggml-src/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \ -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" cmake --build ggml-src/build -j && cmake --install ggml-src/build - cmake -S parakeet-cpp -B build -DCMAKE_BUILD_TYPE=Release \ + cmake -S engines/parakeet -B build -DCMAKE_BUILD_TYPE=Release \ -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=ON \ -DCMAKE_PREFIX_PATH="$PWD/ggml-install" cmake --build build -j diff --git a/.github/workflows/tts-ci.yml b/.github/workflows/tts-ci.yml index 9b9f98e5cfb..7c01e74df9c 100644 --- a/.github/workflows/tts-ci.yml +++ b/.github/workflows/tts-ci.yml @@ -1,5 +1,5 @@ -# CI for the TTS engines (tts-cpp/ — engines/tts/ after the repo reorg QIP -# lands; update the path filters below when it does). +# CI for the TTS engines (engines/tts/ — moved from tts-cpp/ by the repo +# reorg QIP, PR 1). # # Scope (QIP "PR 0" lane): build chatterbox + supertonic + lavasr and every # test harness against system ggml (qvac-ext-ggml @ speech — mandatory here: @@ -13,11 +13,11 @@ on: push: branches: [master] paths: - - 'tts-cpp/**' + - 'engines/tts/**' - '.github/workflows/tts-ci.yml' pull_request: paths: - - 'tts-cpp/**' + - 'engines/tts/**' - '.github/workflows/tts-ci.yml' workflow_dispatch: inputs: @@ -92,7 +92,7 @@ jobs: - name: Configure run: | - cmake -S tts-cpp -B build \ + cmake -S engines/tts -B build \ -DCMAKE_BUILD_TYPE=Release \ -DTTS_CPP_BUILD_TESTS=ON \ -DCMAKE_PREFIX_PATH="$PWD/ggml-install" @@ -127,7 +127,7 @@ jobs: cmake -S ggml-src -B ggml-src/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \ -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" cmake --build ggml-src/build -j && cmake --install ggml-src/build - cmake -S tts-cpp -B build -DCMAKE_BUILD_TYPE=Release \ + cmake -S engines/tts -B build -DCMAKE_BUILD_TYPE=Release \ -DTTS_CPP_BUILD_TESTS=ON \ -DCMAKE_PREFIX_PATH="$PWD/ggml-install" cmake --build build -j From 882c8149b65ea64acf2ff5381e4ee13e1e33d383 Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Fri, 17 Jul 2026 10:38:09 +0100 Subject: [PATCH 07/10] fix(tts): portable setenv/unsetenv shim for MSVC test builds; skip examples in cross lanes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new Windows lane's first run caught 9 test files calling POSIX setenv/unsetenv, which MSVC's CRT doesn't provide — add test/test_env_portable.h (same-named _putenv_s shims on _MSC_VER, plain elsewhere) and include it where used. Also -DPARAKEET_BUILD_EXAMPLES=OFF in the windows/android/ios lanes: the live-mic examples hand GCC-style warning flags to cl.exe and use mic-capture APIs that don't exist on the iOS device SDK; examples are dev conveniences, not part of the cross-platform surface. Co-Authored-By: Claude Fable 5 --- .github/workflows/engines-cross-ci.yml | 6 +++--- tts-cpp/test/test_env_portable.h | 13 +++++++++++++ tts-cpp/test/test_s3gen_sched_equivalence.cpp | 1 + tts-cpp/test/test_supertonic_profile_csv.cpp | 1 + tts-cpp/test/test_supertonic_sched_equivalence.cpp | 1 + .../test/test_supertonic_vulkan_env_overrides.cpp | 1 + tts-cpp/test/test_t3_alignment_analyzer.cpp | 1 + tts-cpp/test/test_t3_caches.cpp | 1 + tts-cpp/test/test_t3_sched_dispatch.cpp | 1 + tts-cpp/test/test_t3_sched_equivalence.cpp | 1 + tts-cpp/test/test_t3_stop_controller.cpp | 1 + 11 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 tts-cpp/test/test_env_portable.h diff --git a/.github/workflows/engines-cross-ci.yml b/.github/workflows/engines-cross-ci.yml index ba3afd8791b..278e0c490c6 100644 --- a/.github/workflows/engines-cross-ci.yml +++ b/.github/workflows/engines-cross-ci.yml @@ -44,7 +44,7 @@ jobs: include: - engine: parakeet src: parakeet-cpp - cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=ON + cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=ON -DPARAKEET_BUILD_EXAMPLES=OFF - engine: tts src: tts-cpp cmake_flags: -DTTS_CPP_BUILD_TESTS=ON @@ -100,7 +100,7 @@ jobs: include: - engine: parakeet src: parakeet-cpp - cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=OFF + cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=OFF -DPARAKEET_BUILD_EXAMPLES=OFF - engine: tts src: tts-cpp cmake_flags: -DTTS_CPP_BUILD_TESTS=OFF @@ -159,7 +159,7 @@ jobs: include: - engine: parakeet src: parakeet-cpp - cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=OFF + cmake_flags: -DPARAKEET_USE_SYSTEM_GGML=ON -DPARAKEET_BUILD_TESTS=OFF -DPARAKEET_BUILD_EXAMPLES=OFF - engine: tts src: tts-cpp cmake_flags: -DTTS_CPP_BUILD_TESTS=OFF diff --git a/tts-cpp/test/test_env_portable.h b/tts-cpp/test/test_env_portable.h new file mode 100644 index 00000000000..05edff52279 --- /dev/null +++ b/tts-cpp/test/test_env_portable.h @@ -0,0 +1,13 @@ +#pragma once +// Portable setenv/unsetenv for the test harnesses. MSVC's CRT has no +// POSIX setenv/unsetenv (only _putenv_s), so provide same-named shims +// there; every other platform gets the real functions from . +#include +#ifdef _MSC_VER +inline int setenv(const char * name, const char * value, int /*overwrite*/) { + return _putenv_s(name, value); +} +inline int unsetenv(const char * name) { + return _putenv_s(name, ""); // empty value removes the variable +} +#endif diff --git a/tts-cpp/test/test_s3gen_sched_equivalence.cpp b/tts-cpp/test/test_s3gen_sched_equivalence.cpp index 31b7dfb7c9a..90cf0a7102e 100644 --- a/tts-cpp/test/test_s3gen_sched_equivalence.cpp +++ b/tts-cpp/test/test_s3gen_sched_equivalence.cpp @@ -23,6 +23,7 @@ // // usage: test-s3gen-sched-equivalence MODEL.gguf [n_gpu_layers] +#include "test_env_portable.h" #include "tts-cpp/chatterbox/s3gen_pipeline.h" #include diff --git a/tts-cpp/test/test_supertonic_profile_csv.cpp b/tts-cpp/test/test_supertonic_profile_csv.cpp index 780fc376e76..d07565d8f18 100644 --- a/tts-cpp/test/test_supertonic_profile_csv.cpp +++ b/tts-cpp/test/test_supertonic_profile_csv.cpp @@ -37,6 +37,7 @@ // Registered with `LABEL "unit"` in CMakeLists.txt — no GGUF // required. +#include "test_env_portable.h" #include "supertonic_internal.h" #include diff --git a/tts-cpp/test/test_supertonic_sched_equivalence.cpp b/tts-cpp/test/test_supertonic_sched_equivalence.cpp index 169aa081c6e..918b490164e 100644 --- a/tts-cpp/test/test_supertonic_sched_equivalence.cpp +++ b/tts-cpp/test/test_supertonic_sched_equivalence.cpp @@ -25,6 +25,7 @@ // // usage: test-supertonic-sched-equivalence MODEL.gguf [n_gpu_layers] +#include "test_env_portable.h" #include "tts-cpp/supertonic/engine.h" #include diff --git a/tts-cpp/test/test_supertonic_vulkan_env_overrides.cpp b/tts-cpp/test/test_supertonic_vulkan_env_overrides.cpp index c578c096eab..516c94293ff 100644 --- a/tts-cpp/test/test_supertonic_vulkan_env_overrides.cpp +++ b/tts-cpp/test/test_supertonic_vulkan_env_overrides.cpp @@ -51,6 +51,7 @@ // Whole TU MUST fail to compile before the symbols are added, // then pass after. +#include "test_env_portable.h" #include "tts-cpp/supertonic/engine.h" #include "supertonic_internal.h" diff --git a/tts-cpp/test/test_t3_alignment_analyzer.cpp b/tts-cpp/test/test_t3_alignment_analyzer.cpp index af35ef36f76..65c18372e71 100644 --- a/tts-cpp/test/test_t3_alignment_analyzer.cpp +++ b/tts-cpp/test/test_t3_alignment_analyzer.cpp @@ -11,6 +11,7 @@ // - token repetition only forces EOS once complete (avoids #519/#587 early cut) // - short text / empty row / disabled => no force +#include "test_env_portable.h" #include "t3_alignment_analyzer.h" #include diff --git a/tts-cpp/test/test_t3_caches.cpp b/tts-cpp/test/test_t3_caches.cpp index ee079d4eb0b..85cb5f7ee02 100644 --- a/tts-cpp/test/test_t3_caches.cpp +++ b/tts-cpp/test/test_t3_caches.cpp @@ -28,6 +28,7 @@ // Without arguments, runs only the lightweight default-state // invariants (no model load required). +#include "test_env_portable.h" #include "chatterbox_t3_internal.h" #include "chatterbox_tts_test_hooks.h" diff --git a/tts-cpp/test/test_t3_sched_dispatch.cpp b/tts-cpp/test/test_t3_sched_dispatch.cpp index 5bc3119a0ea..ba242c19b5b 100644 --- a/tts-cpp/test/test_t3_sched_dispatch.cpp +++ b/tts-cpp/test/test_t3_sched_dispatch.cpp @@ -12,6 +12,7 @@ // Registered with `LABEL "unit"` in CMakeLists.txt so a fresh // checkout's `ctest` exercises this without needing any fixture. +#include "test_env_portable.h" #include "backend_selection.h" #include "sched_dispatch.h" diff --git a/tts-cpp/test/test_t3_sched_equivalence.cpp b/tts-cpp/test/test_t3_sched_equivalence.cpp index 9cdcdc98305..c19cd043f4a 100644 --- a/tts-cpp/test/test_t3_sched_equivalence.cpp +++ b/tts-cpp/test/test_t3_sched_equivalence.cpp @@ -23,6 +23,7 @@ // it, phase B must BYPASS the cached graphs, and phase A' proves they // were left intact. +#include "test_env_portable.h" #include "chatterbox_t3_internal.h" #include "ggml.h" diff --git a/tts-cpp/test/test_t3_stop_controller.cpp b/tts-cpp/test/test_t3_stop_controller.cpp index 55a28c44844..c0fdff90c45 100644 --- a/tts-cpp/test/test_t3_stop_controller.cpp +++ b/tts-cpp/test/test_t3_stop_controller.cpp @@ -16,6 +16,7 @@ // EOS, no post-check stop. // - make_mtl_stop_params budget scaling + env overrides. +#include "test_env_portable.h" #include "t3_stop_controller.h" #include From 50183e36a94262ad8423c03e3604adf8a4131315 Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Fri, 17 Jul 2026 10:46:22 +0100 Subject: [PATCH 08/10] fix(tts): portable temp-dir fallback for tests that write scratch GGUFs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test-gguf-stream and test-lavasr-enhancer-ggml consulted only TMPDIR with a hard "/tmp" fallback — Windows sets TEMP/TMP and has no /tmp, so both failed on the new Windows lane. Add test_tmpdir() to test_env_portable.h (TMPDIR -> TEMP -> TMP -> "/tmp") and use it. Co-Authored-By: Claude Fable 5 --- tts-cpp/test/test_env_portable.h | 12 ++++++++++++ tts-cpp/test/test_gguf_stream.cpp | 4 ++-- tts-cpp/test/test_lavasr_enhancer_ggml.cpp | 5 ++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/tts-cpp/test/test_env_portable.h b/tts-cpp/test/test_env_portable.h index 05edff52279..3e46cbd2414 100644 --- a/tts-cpp/test/test_env_portable.h +++ b/tts-cpp/test/test_env_portable.h @@ -3,6 +3,8 @@ // POSIX setenv/unsetenv (only _putenv_s), so provide same-named shims // there; every other platform gets the real functions from . #include +#include +#include #ifdef _MSC_VER inline int setenv(const char * name, const char * value, int /*overwrite*/) { return _putenv_s(name, value); @@ -11,3 +13,13 @@ inline int unsetenv(const char * name) { return _putenv_s(name, ""); // empty value removes the variable } #endif + +// Writable scratch directory for tests that emit temp fixtures. POSIX +// runners set TMPDIR; Windows sets TEMP/TMP and has no /tmp, so fall +// through the whole chain before defaulting. +inline std::string test_tmpdir() { + for (const char * var : { "TMPDIR", "TEMP", "TMP" }) { + if (const char * v = std::getenv(var); v && *v) return v; + } + return "/tmp"; +} diff --git a/tts-cpp/test/test_gguf_stream.cpp b/tts-cpp/test/test_gguf_stream.cpp index 1dd5f90f6db..113fea1a276 100644 --- a/tts-cpp/test/test_gguf_stream.cpp +++ b/tts-cpp/test/test_gguf_stream.cpp @@ -8,6 +8,7 @@ // chunk boundary) into a temp file, loads it through both paths, and // compares. +#include "test_env_portable.h" #include "ggml.h" #include "ggml-backend.h" #include "ggml-cpu.h" @@ -47,8 +48,7 @@ static const spec SPECS[] = { static const size_t N_SPECS = sizeof(SPECS) / sizeof(SPECS[0]); static std::string write_fixture() { - const char * tmpdir = getenv("TMPDIR"); - std::string path = std::string(tmpdir ? tmpdir : "/tmp") + "/test-gguf-stream-fixture.gguf"; + std::string path = test_tmpdir() + "/test-gguf-stream-fixture.gguf"; size_t total = 0; for (size_t i = 0; i < N_SPECS; ++i) { diff --git a/tts-cpp/test/test_lavasr_enhancer_ggml.cpp b/tts-cpp/test/test_lavasr_enhancer_ggml.cpp index a25cd443441..8eb962a586b 100644 --- a/tts-cpp/test/test_lavasr_enhancer_ggml.cpp +++ b/tts-cpp/test/test_lavasr_enhancer_ggml.cpp @@ -17,6 +17,7 @@ // is present it additionally compares the ggml forward against the onnxruntime // golden real/imag with the real model weights. +#include "test_env_portable.h" #include "backend_selection.h" #include "lavasr/enhancer.h" // scalar enhance() + enhance_with() #include "lavasr/enhancer_core.h" @@ -505,9 +506,7 @@ static std::string write_enhancer_gguf(const EnhancerWeights & w) { add_gguf_tensor(ctx, g, w, e.name, e.ne); } - const char * tmpdir = std::getenv("TMPDIR"); - std::string path = - std::string(tmpdir ? tmpdir : "/tmp") + "/test-lavasr-enhancer-load.gguf"; + std::string path = test_tmpdir() + "/test-lavasr-enhancer-load.gguf"; const bool ok = gguf_write_to_file(g, path.c_str(), /*only_meta=*/false); gguf_free(g); ggml_free(ctx); From 126d8b5438ab65032a48318325134a36e600f464 Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Fri, 17 Jul 2026 16:21:31 +0100 Subject: [PATCH 09/10] =?UTF-8?q?ci+fix:=20address=20#93=20review=20?= =?UTF-8?q?=E2=80=94=20exact-SHA=20ggml=20fetch,=20POSIX-faithful=20setenv?= =?UTF-8?q?=20shim,=20GPU=20flags=20in=20gpu=20stubs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - All ggml provisioning steps now fetch the exact SHA the cache key was derived from (git init + fetch --depth 1 + checkout FETCH_HEAD) instead of cloning the branch tip with a swallowed checkout — the tip advancing between ls-remote and clone could poison the cache with a commit the key never described. Applies to parakeet-ci, tts-ci and all three engines-cross-ci jobs. - test_env_portable.h: the MSVC setenv shim now honors overwrite=0 (existing variable left untouched, return 0) instead of silently diverging from POSIX. - GPU stub jobs: build ggml with -DGGML_VULKAN=ON (the backend the -L gpu suites target; Metal is default-on on Apple hosts) so a dispatch run can't falsely pass against a CPU-only ggml; flag set to be revisited when the runner fleet exists. Co-Authored-By: Claude Fable 5 --- .github/workflows/engines-cross-ci.yml | 21 ++++++++++++++++++--- .github/workflows/parakeet-ci.yml | 16 ++++++++++++++-- .github/workflows/tts-ci.yml | 16 ++++++++++++++-- tts-cpp/test/test_env_portable.h | 7 ++++++- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/.github/workflows/engines-cross-ci.yml b/.github/workflows/engines-cross-ci.yml index 278e0c490c6..1500d130bb5 100644 --- a/.github/workflows/engines-cross-ci.yml +++ b/.github/workflows/engines-cross-ci.yml @@ -71,7 +71,12 @@ jobs: - name: Build ggml (MSVC, static, CPU-only) if: steps.ggml-cache.outputs.cache-hit != 'true' run: | - git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + # Fetch the exact SHA the cache key was derived from (the branch + # tip may advance between ls-remote and this step). + git init -q ggml-src + git -C ggml-src remote add origin "$GGML_REPO" + git -C ggml-src fetch --depth 1 origin ${{ steps.ggml.outputs.sha }} + git -C ggml-src checkout -q FETCH_HEAD cmake -S ggml-src -B ggml-src/build -A x64 \ -DBUILD_SHARED_LIBS=OFF \ -DGGML_BUILD_TESTS=OFF \ @@ -123,7 +128,12 @@ jobs: - name: Build ggml (NDK arm64-v8a, static, CPU-only) if: steps.ggml-cache.outputs.cache-hit != 'true' run: | - git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + # Fetch the exact SHA the cache key was derived from (the branch + # tip may advance between ls-remote and this step). + git init -q ggml-src + git -C ggml-src remote add origin "$GGML_REPO" + git -C ggml-src fetch --depth 1 origin ${{ steps.ggml.outputs.sha }} + git -C ggml-src checkout -q FETCH_HEAD cmake -S ggml-src -B ggml-src/build \ -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake" \ -DANDROID_ABI=arm64-v8a \ @@ -183,7 +193,12 @@ jobs: - name: Build ggml (iOS device arm64, static, Metal embedded) if: steps.ggml-cache.outputs.cache-hit != 'true' run: | - git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src + # Fetch the exact SHA the cache key was derived from (the branch + # tip may advance between ls-remote and this step). + git init -q ggml-src + git -C ggml-src remote add origin "$GGML_REPO" + git -C ggml-src fetch --depth 1 origin ${{ steps.ggml.outputs.sha }} + git -C ggml-src checkout -q FETCH_HEAD cmake -S ggml-src -B ggml-src/build \ -DCMAKE_SYSTEM_NAME=iOS \ -DCMAKE_OSX_SYSROOT=iphoneos \ diff --git a/.github/workflows/parakeet-ci.yml b/.github/workflows/parakeet-ci.yml index b84d15f1446..02ce8ee9d49 100644 --- a/.github/workflows/parakeet-ci.yml +++ b/.github/workflows/parakeet-ci.yml @@ -77,8 +77,14 @@ jobs: - name: Build ggml (system ggml, qvac-ext-ggml@${{ env.GGML_BRANCH }}) if: steps.ggml-cache.outputs.cache-hit != 'true' run: | - git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src - git -C ggml-src checkout ${{ steps.ggml.outputs.sha }} || true + # Fetch the exact SHA the cache key was derived from — the branch + # tip may have advanced since the ls-remote resolution, and a + # tip-only shallow clone would then silently build (and cache) + # a different commit than the key claims. + git init -q ggml-src + git -C ggml-src remote add origin "$GGML_REPO" + git -C ggml-src fetch --depth 1 origin ${{ steps.ggml.outputs.sha }} + git -C ggml-src checkout -q FETCH_HEAD cmake -S ggml-src -B ggml-src/build \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SHARED_LIBS=ON \ @@ -121,10 +127,16 @@ jobs: timeout-minutes: 90 steps: - uses: actions/checkout@v4 + # GGML_VULKAN=ON is the backend the -L gpu suites primarily target + # (test_vk_vs_cpu et al); Metal is on by default on Apple hosts. + # Revisit the flag set (OpenCL? CUDA?) when the GPU runner fleet is + # provisioned — a CPU-only ggml here would skip or falsely pass the + # GPU suites. - name: Build ggml + engine (native backends) and run GPU suites run: | git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src cmake -S ggml-src -B ggml-src/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \ + -DGGML_VULKAN=ON \ -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" cmake --build ggml-src/build -j && cmake --install ggml-src/build cmake -S parakeet-cpp -B build -DCMAKE_BUILD_TYPE=Release \ diff --git a/.github/workflows/tts-ci.yml b/.github/workflows/tts-ci.yml index 9b9f98e5cfb..00234903010 100644 --- a/.github/workflows/tts-ci.yml +++ b/.github/workflows/tts-ci.yml @@ -78,8 +78,14 @@ jobs: - name: Build ggml (system ggml, qvac-ext-ggml@${{ env.GGML_BRANCH }}) if: steps.ggml-cache.outputs.cache-hit != 'true' run: | - git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src - git -C ggml-src checkout ${{ steps.ggml.outputs.sha }} || true + # Fetch the exact SHA the cache key was derived from — the branch + # tip may have advanced since the ls-remote resolution, and a + # tip-only shallow clone would then silently build (and cache) + # a different commit than the key claims. + git init -q ggml-src + git -C ggml-src remote add origin "$GGML_REPO" + git -C ggml-src fetch --depth 1 origin ${{ steps.ggml.outputs.sha }} + git -C ggml-src checkout -q FETCH_HEAD cmake -S ggml-src -B ggml-src/build \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SHARED_LIBS=ON \ @@ -121,10 +127,16 @@ jobs: timeout-minutes: 90 steps: - uses: actions/checkout@v4 + # GGML_VULKAN=ON is the backend the -L gpu suites primarily target + # (test_vk_vs_cpu et al); Metal is on by default on Apple hosts. + # Revisit the flag set (OpenCL? CUDA?) when the GPU runner fleet is + # provisioned — a CPU-only ggml here would skip or falsely pass the + # GPU suites. - name: Build ggml + engine (native backends) and run GPU suites run: | git clone --depth 1 --branch "$GGML_BRANCH" "$GGML_REPO" ggml-src cmake -S ggml-src -B ggml-src/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \ + -DGGML_VULKAN=ON \ -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" cmake --build ggml-src/build -j && cmake --install ggml-src/build cmake -S tts-cpp -B build -DCMAKE_BUILD_TYPE=Release \ diff --git a/tts-cpp/test/test_env_portable.h b/tts-cpp/test/test_env_portable.h index 3e46cbd2414..1eee6f3dfa6 100644 --- a/tts-cpp/test/test_env_portable.h +++ b/tts-cpp/test/test_env_portable.h @@ -6,7 +6,12 @@ #include #include #ifdef _MSC_VER -inline int setenv(const char * name, const char * value, int /*overwrite*/) { +inline int setenv(const char * name, const char * value, int overwrite) { + // POSIX: with overwrite=0 an existing variable must be left untouched + // (and 0 returned) — don't let the shim diverge from that silently. + if (!overwrite && std::getenv(name) != nullptr) { + return 0; + } return _putenv_s(name, value); } inline int unsetenv(const char * name) { From ad822099383b4bbc97a376573d5bd33119369e3a Mon Sep 17 00:00:00 2001 From: ogad-tether Date: Tue, 21 Jul 2026 10:48:37 +0100 Subject: [PATCH 10/10] ci+fix: portable ggml builds for hosted lanes; env shim for Parler sched test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First lane run against master's Parler merge caught two issues: - 19 tts tests SIGILL'd on ubuntu: the lanes built ggml with the default GGML_NATIVE=ON (-march=native) and cached the install keyed only by ggml SHA + OS — hosted runner fleets mix CPU generations, so a cache built on an AVX-512 machine crashes on one without. Build ggml with GGML_NATIVE=OFF in every hosted lane (gpu stubs on self-hosted machines keep native) and bust the possibly-poisoned caches with a -portable key prefix. - test/parler/test_sched_equivalence.cpp (new in #92, never built on Windows) uses POSIX setenv/unsetenv — include the existing test_env_portable.h shim. Co-Authored-By: Claude Fable 5 --- .github/workflows/engines-cross-ci.yml | 3 ++- .github/workflows/parakeet-ci.yml | 3 ++- .github/workflows/tts-ci.yml | 3 ++- engines/tts/test/parler/test_sched_equivalence.cpp | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/engines-cross-ci.yml b/.github/workflows/engines-cross-ci.yml index de1a7a70dea..b31f72f383d 100644 --- a/.github/workflows/engines-cross-ci.yml +++ b/.github/workflows/engines-cross-ci.yml @@ -65,7 +65,7 @@ jobs: uses: actions/cache@v4 with: path: ggml-install - key: ggml-install-windows-2022-msvc-static-${{ steps.ggml.outputs.sha }} + key: ggml-install-portable-windows-2022-msvc-static-${{ steps.ggml.outputs.sha }} # Static ggml on Windows sidesteps DLL discovery for the test exes. - name: Build ggml (MSVC, static, CPU-only) @@ -79,6 +79,7 @@ jobs: git -C ggml-src checkout -q FETCH_HEAD cmake -S ggml-src -B ggml-src/build -A x64 \ -DBUILD_SHARED_LIBS=OFF \ + -DGGML_NATIVE=OFF \ -DGGML_BUILD_TESTS=OFF \ -DGGML_BUILD_EXAMPLES=OFF \ -DCMAKE_INSTALL_PREFIX="$PWD/ggml-install" diff --git a/.github/workflows/parakeet-ci.yml b/.github/workflows/parakeet-ci.yml index 6df490baaec..ba0ff40680e 100644 --- a/.github/workflows/parakeet-ci.yml +++ b/.github/workflows/parakeet-ci.yml @@ -63,7 +63,7 @@ jobs: uses: actions/cache@v4 with: path: ggml-install - key: ggml-install-${{ matrix.os }}-${{ steps.ggml.outputs.sha }} + key: ggml-install-portable-${{ matrix.os }}-${{ steps.ggml.outputs.sha }} - name: Cache ccache uses: actions/cache@v4 @@ -88,6 +88,7 @@ jobs: cmake -S ggml-src -B ggml-src/build \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SHARED_LIBS=ON \ + -DGGML_NATIVE=OFF \ -DGGML_METAL=OFF \ -DGGML_BUILD_TESTS=OFF \ -DGGML_BUILD_EXAMPLES=OFF \ diff --git a/.github/workflows/tts-ci.yml b/.github/workflows/tts-ci.yml index df7e39c437c..5d59a1f65c3 100644 --- a/.github/workflows/tts-ci.yml +++ b/.github/workflows/tts-ci.yml @@ -62,7 +62,7 @@ jobs: uses: actions/cache@v4 with: path: ggml-install - key: ggml-install-${{ matrix.os }}-${{ steps.ggml.outputs.sha }} + key: ggml-install-portable-${{ matrix.os }}-${{ steps.ggml.outputs.sha }} - name: Cache ccache uses: actions/cache@v4 @@ -89,6 +89,7 @@ jobs: cmake -S ggml-src -B ggml-src/build \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SHARED_LIBS=ON \ + -DGGML_NATIVE=OFF \ -DGGML_METAL=OFF \ -DGGML_BUILD_TESTS=OFF \ -DGGML_BUILD_EXAMPLES=OFF \ diff --git a/engines/tts/test/parler/test_sched_equivalence.cpp b/engines/tts/test/parler/test_sched_equivalence.cpp index 8ca4511c609..58111ea5a88 100644 --- a/engines/tts/test/parler/test_sched_equivalence.cpp +++ b/engines/tts/test/parler/test_sched_equivalence.cpp @@ -2,6 +2,7 @@ // same greedy input as A (direct), B (TTS_CPP_FORCE_SCHED=1) and A' (direct // again); all three PCM buffers must be bit-identical. +#include "../test_env_portable.h" #include "tts-cpp/parler/engine.h" #include