Research notes · Text to speech
The hunt for a voice worth hearing all day.
The bar: voices a listener would rate above eight out of ten, in as many languages as possible, running on your own machine.
This is the long version of the speech research behind Omalexia. Everything below was measured on one reference laptop, an Intel Core Ultra 7 255H (Arrow Lake) with an Intel Arc iGPU and no NVIDIA card, between 24 and 31 August 2026. Claims from vendors and blogs were re-verified against model cards, licences and papers before they were believed. The raw notes live in the repository.
Why this matters
For a dyslexic reader, the voice is the interface.
Text to speech is not a convenience feature here; it is how most text gets read. That splits the problem in two. The voice has to be instant, because a second of delay per press is a feature you stop using, and it has to be good, because a tiring voice is a voice you turn off by the afternoon. Latency turned out to be solvable in a week. Quality, in every language a household actually speaks, is the open hunt this page documents.
Dutch goes first, because it is the language the current open voices serve worst, then German, French, Spanish, Italian, Polish and the rest of Europe. Cloud voices are out of scope except as a quality reference: what you read stays on your machine.
24 August · Round one
Picking the everyday stack.
The beta ships Piper voices kept warm in a small daemon, so speech starts about a tenth of a second after the key press. That choice came from timing every installed voice, one sentence, synthesised after a warm-up pass:
| Voice | Load | First audio | Real-time factor |
|---|---|---|---|
| en_US-lessac-medium | 0.84 s | 0.32 s | 0.051 |
| en_US-lessac-high | 1.35 s | 3.46 s | 0.543 |
| en_GB-alba-medium | 1.44 s | 0.38 s | 0.058 |
| nl_NL-pim-medium | 1.34 s | 0.42 s | 0.055 |
| nl_NL-mls-medium | 1.41 s | 0.72 s | 0.069 |
| nl_BE-nathalie-medium | 1.24 s | 0.35 s | 0.063 |
A real-time factor below 1.0 means the engine synthesises faster than the audio plays. The detail that shaped everything after: Piper emits one chunk per sentence, so the wait before the first word is the cost of synthesising the whole first sentence. The 3.46 s worst case above is a deliberately long 24-word sentence through a "high" voice.
The first-sentence discovery
Synthesis and playback are pipelined: each sentence is handed to the audio system the moment it is ready. Timing a four-sentence paragraph through the richer lessac-high voice showed where the cost really sits. "Margin" is how long each chunk was ready before playback needed it:
| Sentence | Ready at | Audio length | Needed at | Margin |
|---|---|---|---|---|
| 1 | 0.93 s | 2.50 s | 0.00 s | -0.93 s |
| 2 | 2.15 s | 2.54 s | 2.50 s | +0.35 s |
| 3 | 3.35 s | 2.96 s | 5.04 s | +1.69 s |
| 4 | 4.67 s | 3.04 s | 8.00 s | +3.33 s |
The margin is negative exactly once, on the first sentence, and then grows without bound: at a real-time factor of 0.54 the buffer gains about half a second of slack per sentence spoken. A high voice never stutters on a long document; it just starts 0.7 s later. So richer voices were being rejected for the wrong reason, and the fixes are cheap: split the opening sentence at its first comma, speak sentence one with a fast voice and switch after it, or start synthesising on selection instead of on keypress. The same argument rehabilitates Kokoro-82M (real-time factor about 0.35), which a day later also turned out to speak eight languages, not one: only our own engine gate said "English only".
24 August · The NPU detour
The accelerator helps ears, not voices.
The laptop has an Intel NPU, so the obvious question got a day: can it make speech better? For dictation, yes. An OpenVINO build of the exact Parakeet model Omalexia configures runs at 25.7x real time on this NPU generation against 5 to 8x on CPU, at an identical 3.7% word error rate: three to five times the throughput at lower power.
For speech, no, twice over. Structurally, text to speech takes variable-length text and produces variable-length audio, the opposite of the fixed windows an NPU wants, and no tested Intel NPU path for a TTS decoder exists. And even if it worked, the default voices already synthesise twenty times faster than they need to; an NPU cannot make a voice sound better, only produce the same audio using less power. The ordering that fell out: solve quality first, and treat the NPU as the thing that makes the answer affordable afterwards, by moving dictation off the CPU to pay for a heavier voice.
30 August · The multilingual hunt
Trust no ranking: verify everything.
The starting frame was a widely shared "best TTS models of 2026" ranking of 24 local models. It is vendor content: the publisher's own model sits at number two, scored by the publisher. So every claim that mattered got re-verified from model cards, LICENSE files and papers. A sample of what that did:
- "OmniVoice by OpenVox, 646 languages, Apache, 8.4" is three-quarters wrong. The model is real and remarkable: k2-fsa OmniVoice, from the Next-gen Kaldi group, genuinely 646 languages with 2,264 hours of Dutch in training. But OpenVox did not make it, the 8.4 is their own self-published score, and the weights are CC-BY-NC; only the code is Apache.
- Qwen3-TTS is genuinely Apache-licensed, and supports ten languages. Dutch is not one of them.
- Higgs Audio "8.5, 100 languages": the version with that claim has no published language list, a research-only licence, and needs a 24 GB GPU.
- Fish Speech / OpenAudio lists Dutch on the model card, but the paper's own training-data description never mentions it, the weights are non-commercial, and the CPU path is broken in practice.
- CosyVoice 3: the model you can download is not the model the paper's quality numbers describe, and it has no Dutch either way.
Every Dutch-capable model, verified
| Model | Languages | Weights licence | Runs on this machine? | Verdict |
|---|---|---|---|---|
| Supertonic 3 | 31 | OpenRAIL-M, commercial OK | Yes: RTF 0.36 to 0.73 on CPU | Very good front-runner |
| OmniVoice (k2-fsa) | 646 | CC-BY-NC, code Apache | CPU hopeless; Arc iGPU yes | Very good needs the iGPU |
| Chatterbox Multilingual V3 | 23 | MIT | RTF 2.4 measured; fixable | Verdict open |
| VoxCPM2 (OpenBMB) | 30 | Apache-2.0 | No: RTF 36 to 93 | Rejected on sound |
| Piper nl (current stack) | ~45 | Permissive | Yes, instantly | The baseline to beat |
| OuteTTS 1.0 1B | 23 | CC-BY-NC-SA | Yes, via llama.cpp | Risky: altered words reported |
| OpenAudio S1-mini | 13 | CC-BY-NC-SA | Broken CPU path | Skip |
| ZONOS2 (Zyphra) | 34 | Sources conflict | No: NVIDIA only, 8B | Skip on this machine |
| XTTS v2 | 17 | Non-commercial, issuer defunct | Possible, slow | Benchmark reference only |
| Voxtral TTS 4B (Mistral) | 9 | CC-BY-NC | No: 16 GB GPU required | Quality reference |
| Parler mini multilingual | 8 | Apache-2.0 | Untested | Curiosity |
| MMS-TTS-nld (Meta) | 1107 | CC-BY-NC | Trivially | Quality too low |
Verified as having no Dutch, and ruled out for the goal regardless of quality: Kokoro, CosyVoice 3, Qwen3-TTS, Higgs Audio v2, IndexTTS, MeloTTS, Orpheus, MegaTTS3, F5-TTS (no Dutch finetune exists anywhere, a verified gap) and a dozen more. On the watch list: Kyutai Pocket TTS, 100M parameters, MIT, genuinely real time on two CPU cores, five languages added this spring and its training code open since 25 August 2026, so Dutch may well come, or be brought.
The uncomfortable finding
Dutch is the hard case, on the record.
No open-weight model has credible published evidence of 8/10 subjective quality in Dutch today. That is not a mood, it is what the sources say when you chase them:
- The arena rankings everyone cites are English-only by design, so every arena score in every blog says nothing about Dutch.
- The strongest controlled datapoint is Mistral's Voxtral TTS paper: blind native-speaker preference against ElevenLabs across nine languages. The open model wins Spanish with 87.8%, German with 72.0%, Italian and French narrowly. Dutch: 49.4%, the only language of the nine where the open model loses.
- One genuine Dutch head-to-head exists, buried in Supertonic's README: per-language word error rates. Dutch: OmniVoice 0.77, VoxCPM2 0.84, Supertonic 3 1.47. Intelligibility rather than naturalness, and self-published, but it says all three read Dutch accurately, which Piper's nl_NL demonstrably does not.
- The community record on Piper's Dutch is damning for the large-data nl_NL voices ("garbled", "unusable", 2023 through 2026), while the two Flemish voices trained on small curated recordings are consistently rated the best of the open Dutch bunch. Curation beats scale; remember that for the finetuning section.
31 August · Listening
Then a native listener decides.
Numbers shortlist; ears choose. The shortlisted engines each read the same Dutch texts, and a native listener in the household gave verdicts blind to the measurements:
| Engine | Verdict | Consequence |
|---|---|---|
| Supertonic 3 | Very good | Front-runner: also real time on a bare CPU |
| OmniVoice | Very good | Justifies the GPU work below |
| VoxCPM2 | Rejected | Out on sound alone; also 36 to 93x too slow |
| Piper nl_NL | Mid | The Flemish nl_BE voices are clearly better; they become the preferred Dutch fallback |
| Chatterbox | Verdict open | Samples rendered, listen pending; its acceleration work waits on this |
31 August · Measured here
The same texts, every engine, one machine.
Protocol: idle machine, one engine at a time, the same three Dutch texts (a short sentence, a medium one, a full paragraph), warm model unless noted. RTF is the real-time factor per text; below 1.0 is faster than the audio plays.
| Engine | Load | Peak RAM | RTF short / medium / paragraph |
|---|---|---|---|
| Piper nl_BE-nathalie | per call | 253 MB | 0.43 / 0.29 / 0.20 |
| Supertonic 3 | 1.0 s | 560 MB | 0.94 / 0.66 / 0.42 |
| Chatterbox q4 LM + fp32 decoder | 34 s | 2.0 GB | 3.19 / 2.81 / 2.46 |
| OmniVoice on CPU, 16 steps | 1.1 s | 2.9 GB | 40.4 / 45.0 / 13.8 |
| OmniVoice on Arc iGPU fp16, 16 steps | 2.2 s | 4.2 GB | 0.61 / 0.53 / 0.48 |
| OmniVoice on Arc iGPU fp16, 32 steps | 2.2 s | 4.2 GB | 1.04 / 1.00 / 0.86 |
| VoxCPM2 (bf16, torch) | 370 s first run | ~5.9 GB | 93 / 41 / 36 |
The breakthrough in that table: installing Intel's compute runtime let PyTorch's XPU backend see the Arc iGPU that ships inside this ordinary laptop CPU, and OmniVoice went from 40 to 70 times too slow to comfortably real time, 25 to 75x faster than CPU. A 646-language engine that a native listener rates very good, running in real time on an integrated GPU, is the single most consequential measurement of the whole hunt.
Piper stays the latency and footprint king: it is the only engine here that is instant from cold, which is why it remains the floor of the fallback ladder.
Acceleration notes
Making the heavy ones fast.
For Chatterbox, the measurements split the pipeline cleanly: its language model runs at RTF 0.45 (fine), and the flow-matching audio decoder at 1.9 (the whole blocker). Inspecting our ONNX export showed the 10-step solver unrolled inline, about 21,000 of the graph's 24,000 nodes; the repo ships variants with a 1-step decoder, which would cut roughly 85% of decoder compute and project the total to RTF 0.75, real time on CPU alone. Plan B is running that decoder on the iGPU through OpenVINO (a 2 to 4x win on this model class is documented; our graph's awkward operators are counted: one STFT, 58 ScatterND).
Two negative results worth keeping: INT8 quantisation of TTS audio decoders audibly distorts, so decoders stay FP16 while token models can quantise; and the NPU is a dead end for decoders on today's toolchains, confirmed rather than assumed.
Plan B
If nothing clears the bar: train one.
The Dutch data situation is decent and the recipe is proven at small scale. CML-TTS offers about 645 hours of Dutch under CC-BY, filtered and aligned specifically for TTS: the bulk-adaptation corpus. The cautionary tale sits right next to it: the Piper voice trained straight on 1,580 hours of raw audiobook narration became the worst-rated Dutch voice in the ecosystem. Scale without curation demonstrably fails.
The recipe that matches all the evidence: bulk-adapt a strong multilingual backbone on CML-TTS Dutch, then finish with a small finetune on one clean single-speaker set (several exist openly, 5 to 14 hours each). That two-stage split is precisely what separated the liked Flemish Piper voices from the disliked large-data ones. And the field is open: nobody anywhere has published a Dutch finetune of a modern flow-matching model, and no Dutch or Belgian research institute has published an open TTS model at all.
Where the stack stands
Instant today, beautiful next.
The beta you can install today speaks with warm Piper voices (instant, about 45 languages, mid quality) and optional Kokoro for eight languages. On a research branch, in testing before it reaches the installer: Supertonic 3 and OmniVoice wired into the daemon as first-class engines with a fallback ladder (OmniVoice, then Supertonic, then Piper), and omalexia voice advise, which reads your machine's CPU, RAM and GPU and recommends the best engines it can sustain, so a weaker laptop gets Supertonic and a GPU machine gets the 646-language engine.
Still open: the Chatterbox listening verdict, an ear-check of OmniVoice's faster 16-step setting, and then re-deciding the default voice per language. The changelog tracks what lands.