cd /news/ai-tools/i-recorded-1180-tts-clips-to-find-ou… · home › topics › ai-tools › article
[ARTICLE · art-162755] src=dev.to ↗ pub= topic=ai-tools verified=true sentiment=↑ positive

I recorded 1,180 TTS clips to find out what voices misread in LLM output

A developer built speechready, an open-source text preprocessor that sits between an LLM and a text-to-speech engine to strip markdown, normalize numbers, dates, phone numbers and URLs, and emit provider-specific markup. Across 1,180 recordings spanning 145 English and Turkish lines and 16 voices from 7 providers, misread lines fell from 32% to 8% overall (English 29% to 7%, Turkish 37% to 10%), with every voice improving and control prose unchanged. A held-out run of 60 gpt-4.1-mini answers on four voices showed a smaller gain, 10% to 8%, with mean word error rate flat, and surfaced two bugs.

by read3 min views1 publishedNov 2, 2026

Every voice agent has the same seam: a language model writes text for a reader, and a text-to-speech model reads it for a listener. The two were never designed for each other. The model writes **Step 1:** run `npm install` and the voice says "asterisk asterisk step one". It writes 1,250 units and some voices say "one two five zero". It writes a Turkish phone number as 0532 123 45 67 and the voice reads it as a single number with the wrong suffix.

I kept patching these one at a time in prompts and regexes until I decided to do it properly. This post is about the result, and more about how I measured it, because the measuring turned out to be the hard part.

speechready runs between the LLM and the TTS. Four stages:

There is a Python package and a TypeScript package. Both pass the same 217 YAML fixtures and produce the same output for every one of them.

A text preprocessor is easy to make look good: pick an ugly input, show the tidy output. I wanted to know whether voices actually read the processed text correctly more often, so I built a loop that could tell me.

145 lines of English and Turkish: assistant answers with markdown, dates, phone numbers, prices, URLs, identifiers, and control prose that should pass through untouched. 16 voices across 7 providers. Each line synthesized twice, as written and after speechready. Both recordings transcribed back with gpt-4o-transcribe and scored against the intended words.

The scorer forgives the ways a transcription engine writes speech down: digits for spoken numbers, "21st" for "twenty-first", "NPM" for "en pi em". It only ever lowers the error, and it applies to both sides equally. A line counts as misread when more than a fifth of the words are wrong. Most of the 145 lines are the fixture inputs the rules were developed against, plus control prose and a handful of real assistant answers, so this is a go/no-go measurement on curated cases, not a held-out production sample.

Result, on the same 1,180 recordings:

As written With speechready
All 32% 8%
English 29% 7%
Turkish 37% 10%

Every voice improved. Control prose did not regress. The weakest result is Cartesia's Turkish, where the voice speaks with an English accent and the transcription model misses words that were rendered correctly.

Because most of those lines are the library's own test inputs, I also ran a held-out check: 60 answers that gpt-4.1-mini gave to typical voice-agent questions, generated after the rules were written, scored against a narration the same model wrote independently, on four voices. Misreads went from 10% to 8% and mean word error rate did not move. Concise assistant answers simply contain few of the things the library fixes; when they do contain markdown, prices, phone numbers or code, that is where the gain is. The held-out run also found two bugs, a dotted Turkish time with a suffix and a spaced minus read as a range, which is what held-out data is for.

You can listen to the pairs, with what the STT heard under each: https://berkerbatur.github.io/speechready/

25°C fine; others do not. The provider profiles are YAML, and this is where that knowledge lives.

pip install speechready        # Python 3.10+
npm install speechready        # Node 20+, 35 kB, no dependencies
python
from speechready import prepare
prepare("**Step 1:** run `npm install`. [ 1s]", provider="elevenlabs", model="eleven_multilingual_v2").text

For LiveKit Agents, speechready.integrations.livekit.text_transform(...) goes in tts_text_transforms. For Pipecat, speechready.integrations.pipecat.text_transform(...) goes in a TTS service's text_transforms. Neither imports the framework.

Playground, in the browser: https://berkerbatur.github.io/speechready/play/

English and Turkish for now. If you want another language, the fixtures show exactly what a locale has to cover, and the eval harness will tell you whether it worked.

── more in #ai-tools 4 stories · sorted by recency
── more on @speechready 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/i-recorded-1180-tts-…] indexed:0 read:3min 2026-11-02 · —