Skip to content

Add selectable TTS engine (Windows/Piper/Kokoro) with Kokoro neural voices - #406

Merged
kauffman12 merged 1 commit into
kauffman12:masterfrom
willk:master
Sep 4, 2026
Merged

Add selectable TTS engine (Windows/Piper/Kokoro) with Kokoro neural voices#406
kauffman12 merged 1 commit into
kauffman12:masterfrom
willk:master

Conversation

@willk

@willk willk commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

I felt that piper voices were a little harsh. I added Kokoro. I did use a robot to help since I don't have any experience in .net.

I've tried a bunch of other tools for EQL and nothing has been as good at alerting as EQLogParse.

Add selectable TTS engine (Windows / Piper / Kokoro), with working Kokoro neural voices

Changes

EQLogParser.Audio (audio engine)

  • AudioManager: replaced the implicit "first engine found wins" startup logic with an explicit, persisted engine preference (WindowsEngine / PiperEngine / KokoroEngine constants). Initialize() now takes a preferredEngine parameter; if unset it falls back to the previous auto-detect order (Piper → Kokoro → Windows) for existing installs.
  • Added AudioManager.GetAvailableEngines() — lists engines that can actually be selected right now (Windows always; Piper if its voice pack is present; Kokoro if the model has been downloaded).
  • Added AudioManager.GetActiveEngine() — reports which engine is actually running this session, so the UI can flag when a change needs a restart.
  • PiperTts: added IsVoicePackAvailable(), a side-effect-free check for the voice pack (previously the only way to check was calling Initialize(), which has side effects like setting the native DLL search path).
  • IAudioManager: added GetActiveEngine() to the public contract.

EQLogParser (app)

  • App.xaml.cs: reads the persisted "TtsEngine" setting and passes it into AudioManager.Initialize() at startup.
  • New TtsEngineWindow (replaces KokoroSetupWindow): adds a combo box to pick the active TTS engine from whatever's currently available, persists the choice, and shows a "restart required" hint when the selection differs from the active engine — alongside the existing Kokoro model download flow.
  • TriggersView: renamed the "Kokoro TTS" button to "TTS Engine" and pointed it at the new window.

Installer

  • EQLogParserInstall.iss: minor — installs the bundled Kokoro voices\* folder unconditionally (previously only Piper's voices were referenced).

Behavior after this change

  • Fresh/existing installs keep today's behavior by default (Piper wins if present).
  • Downloading Kokoro and explicitly selecting it in the new TTS Engine window makes it the active engine on next launch, regardless of whether Piper is also present.
  • Once Kokoro is active, the existing voice dropdowns (Triggers tab default voice, per-character voice in Manage Characters, WAV export) list its ~50 voices — that plumbing already existed and just needed Kokoro to actually get a turn.

Not covered

  • No automated tests added (none existed for AudioManager's engine selection previously).
  • Not manually verified end-to-end in a packaged installer build — tested via local dev build only.

@kauffman12

Copy link
Copy Markdown
Owner

Yeah this is a good idea. I wanted to add something better than piper at some point. I know it's not amazing but at least it's small and would run on anything. But I don't think anyone really likes it and having a few options would be good. I'll try this out.

@kauffman12

Copy link
Copy Markdown
Owner

So looking at this I may want to have piper work the same way and then make a lot of the voices optional to cut down on how much needs to get installed. Plus I'm not sure if the fp32 model might be overkill. For simple speech I don't know if anyone could tell the difference if it uses fp16 or something instead. Still a good idea just make take a little bit to integrate everything.

@kauffman12
kauffman12 merged commit 20bacf1 into kauffman12:master Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants