You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The RustTts integration layer is frozen at 2026-08-21 (e80eca2) — the moment floravox landed in rust-tts-wrapper (first commit 2026-08-20). Everything since (floravox engine, lexicon routing, measured boundaries, floravox-core 0.8.x fixes) is absent. There is also a latent ABI mismatch shipping today.
Reference state: VoiceGarden-SPD consumes rust-tts-wrapper v0.5.2 (floravox-core 0.8.4, moving to 0.8.5) directly from the tagged git dep with floravox-lexicons.
Our loader/thunk (updated in e80eca2) target the post-consolidation (rust-tts-wrapper#31) 7-arg callback: (word, charOffset, charLen, startS, endS, estimated, ud)
The 0.3.20 DLL exports the same symbol with the old 4-arg signature: (word, startS, endS, ud)
GetProcAddress succeeds (symbol name unchanged), so RustTtsLoader cannot detect it. The Rust side invokes the thunk with 4 args; charOffset / charLen / estimated are read from never-set registers → garbage offsets or crashes in the boundary lambda (TTSEngine.cpp:998)
Fix: bump NuGet to 0.5.0+ (consolidated signature verified) and add an ABI canary — e.g. resolve tts_set_on_mark (exists only ≥ 0.5.x) and refuse to load the DLL without it.
2. CI ships a nondeterministic DLL
.github/workflows/msbuild.yml:228 grabs Get-ChildItem ~/.nuget/packages/rustttswrapper.bindings -Recurse -Filter rust_tts_wrapper.dll | Select -First 1 — whichever cached version sorts first, decoupled from the csproj pin Fix: pin the exact runtimes/win-{x64,x86}/native path from the referenced package version.
3. The NuGet package has no floravox
rust-tts-wrapper publish.yml builds the Windows DLL with sapi,cloud,sherpaonnx only — no floravox, no floravox-lexicons. Even after a pin bump, SAPI cannot create a floravox engine.
Also NuGet stops at 0.5.0 while the wrapper is at v0.5.2 — releases aren't published consistently.
Fix (wrapper side, tracked separately): add floravox-lexicons to the Windows NuGet build matrix, tag, publish.
Floravox catch-up (SPD parity)
Gap
SPD has
SAPI needs
Local engine
floravox engine via rust-tts-wrapper v0.5.2
Route piper-family voices to engine id floravox (needs wrapper NuGet fix above)
Word boundaries
Measured (floravox duration tensor)
Currently estimated-only via sherpaonnx path; TTSEngine.cpp:998 receives but ignores the estimated flag — use it to gate wpm/silence compensation
Bookmarks
marks → SPD events
tts_set_on_mark not resolved in RustTtsLoader.cpp — map it to SPEI_TTSBOOKMARK
Port equivalent logic to the UI model installer for local voices
Version hygiene
pinned tag + bump discipline
Pin NuGet to wrapper releases, note the mapping in release notes
Code nits
RustTtsEngine.cpp:57-63 — hardcoded debug dump to C:\Users\WillWade\AppData\Local\Temp\vg_ssml_debug.txt on every SpeakSsml. Leftover debug; remove.
TTSEngine.cpp:1037 — m_rustTtsUseSsml = false always, making the SpeakSsml path (lines 336/366) dead code — despite the integration plan calling the C++ BuildSSML() "superior" and c322489 adding PUA-sentinel SSML normalization. Decide: pass SSML for engines that support it (floravox, Azure), or delete the dead path.
TTSEngine.cpp:1001 — boundaries with charOffset < 0 are dropped entirely; consider emitting audio-time-only events instead of losing them.
Suggested order
Remove debug file writes; fix CI DLL selection (trivial)
Bump NuGet 0.3.20 → 0.5.0+ and add the ABI canary in RustTtsLoader
Wrapper: Windows NuGet build with floravox-lexicons, tag, publish (blocks 4)
Route local voices through the floravox engine (measured boundaries + marks)
Port SPD installer hardening for local model sidecars
No architecture change required — the C-API-over-NuGet approach is correct for C++ (same reasoning as AVSynth's dylib). This is version rot plus a never-wired floravox path.
Summary
The RustTts integration layer is frozen at 2026-08-21 (
e80eca2) — the moment floravox landed in rust-tts-wrapper (first commit 2026-08-20). Everything since (floravox engine, lexicon routing, measured boundaries, floravox-core 0.8.x fixes) is absent. There is also a latent ABI mismatch shipping today.Reference state: VoiceGarden-SPD consumes rust-tts-wrapper v0.5.2 (floravox-core 0.8.4, moving to 0.8.5) directly from the tagged git dep with
floravox-lexicons.Critical
1. ABI mismatch on
tts_set_on_boundaryVoiceGarden.UI.csproj:23pinsRustTtsWrapper.Bindings0.3.20e80eca2) target the post-consolidation (rust-tts-wrapper#31) 7-arg callback:(word, charOffset, charLen, startS, endS, estimated, ud)(word, startS, endS, ud)GetProcAddresssucceeds (symbol name unchanged), soRustTtsLoadercannot detect it. The Rust side invokes the thunk with 4 args;charOffset/charLen/estimatedare read from never-set registers → garbage offsets or crashes in the boundary lambda (TTSEngine.cpp:998)Fix: bump NuGet to 0.5.0+ (consolidated signature verified) and add an ABI canary — e.g. resolve
tts_set_on_mark(exists only ≥ 0.5.x) and refuse to load the DLL without it.2. CI ships a nondeterministic DLL
.github/workflows/msbuild.yml:228grabsGet-ChildItem ~/.nuget/packages/rustttswrapper.bindings -Recurse -Filter rust_tts_wrapper.dll | Select -First 1— whichever cached version sorts first, decoupled from the csproj pinFix: pin the exact
runtimes/win-{x64,x86}/nativepath from the referenced package version.3. The NuGet package has no floravox
publish.ymlbuilds the Windows DLL withsapi,cloud,sherpaonnxonly — nofloravox, nofloravox-lexicons. Even after a pin bump, SAPI cannot create afloravoxengine.Fix (wrapper side, tracked separately): add
floravox-lexiconsto the Windows NuGet build matrix, tag, publish.Floravox catch-up (SPD parity)
floravoxengine via rust-tts-wrapper v0.5.2floravox(needs wrapper NuGet fix above)TTSEngine.cpp:998receives but ignores theestimatedflag — use it to gate wpm/silence compensationtts_set_on_marknot resolved inRustTtsLoader.cpp— map it toSPEI_TTSBOOKMARKgenerate_sidecar()re-run,phoneme_id_mapcasefold,language_codesidecar (floravox 0.8.5)Code nits
RustTtsEngine.cpp:57-63— hardcoded debug dump toC:\Users\WillWade\AppData\Local\Temp\vg_ssml_debug.txton everySpeakSsml. Leftover debug; remove.TTSEngine.cpp:1037—m_rustTtsUseSsml = falsealways, making theSpeakSsmlpath (lines 336/366) dead code — despite the integration plan calling the C++BuildSSML()"superior" andc322489adding PUA-sentinel SSML normalization. Decide: pass SSML for engines that support it (floravox, Azure), or delete the dead path.TTSEngine.cpp:1001— boundaries withcharOffset < 0are dropped entirely; consider emitting audio-time-only events instead of losing them.Suggested order
RustTtsLoaderfloravox-lexicons, tag, publish (blocks 4)No architecture change required — the C-API-over-NuGet approach is correct for C++ (same reasoning as AVSynth's dylib). This is version rot plus a never-wired floravox path.