TGSpeechBox 3.10 release candidate 4 — a full bug audit, clearer consonants, profiles that travel, and the engine in Python
This is the fourth release candidate for TGSpeechBox 3.10, after ten betas since 3.01 (April to September) and release candidates on September 29, October 26 and November 9. After the last one we audited the whole code base and fixed 53 of the 69 bugs it found, so this one changes more than a release candidate usually does. If you have 3.1, the first section below is everything that changed. If nothing serious turns up, it becomes 3.10, unchanged. 3.10 takes bug fixes only from here; new features and new voices go to the next version. Most of it came from you: reports in the issues, blind listening rounds, recordings and logs. The theme turned out to be clarity: consonants that land, vowels that sit where they should, and a voice that behaves the same on every platform.
Since release candidate 3.1: the bug audit
After 3.1 we stopped waiting for bug reports and went looking for them. The whole code base was audited, on every platform, and everything found was written up as a public issue with how to reproduce it: 69 issues, #157 to #225.
- 53 of them are fixed and closed in this release.
- 10 more are partly fixed here; the part that remains is still open and described on the issue.
- 6 wait for after 3.10, each with its reason.
- None of the ones marked must-fix is open.
That is 97 commits since 3.1. Every fix has a test, nearly all of them written to fail before the fix, and the suite that guards them is now about 9,900 Python tests and 246 C++ test cases.
Apart from the update check in the NVDA add-on, nothing below is a new feature. But some fixes change what you hear or how a setting behaves, so those come first.
What you may notice
- Pauses follow your speech rate. The pause after a comma or a full stop used to be one length at every rate; now it is a little longer when you listen slowly and a little shorter when you listen fast, on every platform. At the default rate nothing changes.
- NVDA volume: if you saved a volume in an NVDA configuration profile under 3.01, it plays quieter after upgrading. Set it once more and it stays (#198).
- NVDA year splitting: if you use an add-on that changes how numbers are read (Number Patterns, for example) and years sound wrong, turn off "Year splitting" in the TGSpeechBox settings.
- SAPI, top rates: rates above +5 are faster and clearer, the same as that speed in NVDA (#203). Rate boost now doubles the rate, as in NVDA and on Android; if you use it, take your rate down two or three steps (#209).
- SAPI, a fresh install sounds the way NVDA does: pressing OK in the settings app no longer changes the voice when you moved nothing (#205).
- SAPI, inflection scale: the stored value starts fresh. If you use the Classic or Fujisaki intonation mode on SAPI and the melody is flatter after upgrading, set the slider again.
- The inflection scale slider works in every intonation mode, on every platform (#177). Its normal position (29 in NVDA) changes nothing; lower is flatter, higher is livelier.
- Robert sounds the same everywhere: the phone apps no longer make him brighter than NVDA does. If you liked the brighter Robert on your phone, set the tilt slider to 37 or 38 (#200).
- Beth's vowels stay on her own voice all the way through, instead of sliding toward the default voice (#173).
- "!" and "?" in the other intonation modes (#155): in the Fujisaki, Klatt and Impulse modes an exclamation and a question now sound like one. In Fujisaki an exclamation falls at its end, a question rises on its last syllable at every rate, and accents keep their height when you listen fast; statements end a little lower. The Fujisaki and Classic commas are exactly as they were. The Classic mode's "?" is only partly better and stays on the list. The default and Arató modes are not touched. Spanish and Portuguese listeners who use these modes: tell us how it sounds.
- In the Classic and Fujisaki modes an inflection scale of 0 is now flat, as in the other modes; it used to mean full.
- Android and iOS, only if you ever used Import pack: files exported from earlier versions carried a few timing values that never did anything. They would be heard now (in English, a longer puff after p, t and k), so this update removes them from what the app stored, once, and your language sounds as it did. If you import such an old file again, "Reset All Overrides" in the language pack editor ("Reset All" on iOS) takes them out.
Reading numbers and text
- English: "1,234" is a number, not the year "twelve thirty-four" (#157). "08:15" is "eight fifteen", "10:00 AM" is "ten A M", and a time with seconds is left as it is (#166).
- A comma that cannot be a thousands separator is kept as a decimal comma: "0,125" and "3,14" (#167).
- Hungarian: a year at the start of a clause is no longer cut off as its own sentence (#159).
- Your dictionaries: entries match capitalised accented and non-Latin words (#164), an IPA entry replaces its own word when the text has accents (#165), a respelling for a word with a hyphen ("wi-fi") is used (#168), and an emoji with a variation selector finds its entry (#170). On Android and Linux, a letter typed as letter plus combining accent is found too (#169).
- Android and Linux: a no-break space is a space. "10:00 AM" the way clocks write it is "ten A M" there too, and "10 000 Ft", the way Hungarian, French, German, Polish and Czech group thousands, is ten thousand, not "ten, zero, zero, zero".
- A long text with many brackets no longer slows down (#171).
Languages
- Android, iOS and Linux now ask eSpeak NG for phonemes the same way NVDA does. This was a large part of "it sounds different on my phone": English "now", "how", "here", "there", "for" and "car", Danish stød, Polish cz and dż, Spanish ch, and Portuguese "avião" and "região" (which had lost their nasal ending on phones, #163) are now what NVDA plays (#189).
- Hungarian: "kilencszáz", "nyolcszor" and "narancssárga" keep their c (#179).
- English: the catch in the throat in "button" and "kitten" has its creak (#193). At fast rates a vowel before p, t, k or s is no longer stretched, so "rabbit" and "rabid" stay apart (also Turkish, #181).
- Canadian English: "my", "right" and "house" are one gliding vowel again, and "right" and "house" have the raised Canadian vowel (#188). No Canadian has listened yet; if you are one, tell us.
- Spanish: d, n, m and ch next to a single r are the Spanish sounds, not the English ones: "verde", "padre", "carne" (#187). Spanish listeners, tell us how these sound.
- Brazilian Portuguese: "oi" and "lh" are the versions Brazilian listeners chose in a blind round (#150, #152).
- Word joins: the first sound after a short word (the, a, to; Hungarian a, az) is no longer blended more slowly than after a long word (#182), and slow speech no longer doubles one kind of blend (#186). Small, in English, Hungarian, Turkish, German, Dutch, Swedish, Finnish, Polish, Russian, Ukrainian and Bulgarian.
NVDA add-on
- New button: "Check for Add-on Updates", in the TGSpeechBox category of NVDA's settings, looks on GitHub for a newer release. The "Update channel" choice beside it is Stable (full releases, release candidates included) or Prerelease (betas too). Nothing is checked until you press it, nothing is installed without asking, and it tells you plainly when there is nothing newer or why a check failed (#103, #33).
- Cancel in Voice settings takes back changes to the language-file settings too (#160).
- "Save Voice Profile Sliders to YAML" saves the voice you hear instead of neutral values (#195), keeps your language when it is on Auto (#194), and undoes the save if the result cannot be loaded.
- Rate, volume and inflection no longer save one step lower than you chose (#199), the inflection scale keeps what you set (#196), and a voice profile you turned off stays off through automatic language switches (#174).
- Speech you cancelled is no longer reported as finished (#197). The settings migration notice can be translated (#201).
- About twenty new messages are not translated yet in Spanish, Hungarian and Portuguese; they show in English.
SAPI
- A program that releases two TGSpeechBox voices no longer crashes (#202).
- Volume and rate markup inside the text combine with the program's own volume and rate instead of replacing them (#206).
- Text in a spell tag is read letter by letter (#207), skipping a sentence skips one sentence instead of stopping everything (#208), bookmarks arrive even when their text makes no sound (#204), and a built-in voice chosen after a profile voice is itself from the first word (#212).
- Settings app: "Use Language Default" for the pitch mode works again (#210), and "Enable logging" writes a log (#211).
Phoneme editor
- OK in Language settings changes only what you changed (#161), and OK in Edit Classes no longer erases the language's classes (#162). These two could damage a language pack on save.
- Saving keeps special coarticulation rules whole (#213), cross-word conditions (#214), an existing language copy's tuning (#215) and the file's comments (#217).
- Save to Profile saves and loads the chorus sliders (#219) and no longer doubles the inflection after Cancel (#220). Voicing Reset really resets (#218). Adding a word that is already in a dictionary replaces it (#221). Regional languages open the dictionary they speak from (#216).
- The timing settings for aspiration and diphthong endings in a language pack are now read (#172), and settings that never did anything are gone from the lists (#178, #183, #184, #185).
Linux
- The installer can be run while Orca is speaking through TGSpeechBox. It used to stop half way with "Text file busy", because it copied onto the running module.
Still open from the audit
16 audit issues are still open, 10 of them partly fixed above. The ones you might meet: a one-letter text like "É." is read as a letter name (#158), rate boost on the iOS system voice is still 1.35x (#209), and IPA without tie bars from another phonemizer misses some sounds (#163, #189).
In release candidate 3.1
- Portuguese (Brazil and Portugal): an r before a consonant no longer gets a vowel after it. "porta", "aguarde", "inferno", "português" and "verde" were said "pó-rə-ta", like a Japanese speaker would; now they sound the same whichever eSpeak version NVDA ships (#156).
Since the second release candidate (in the third release candidate)
- Brazilian Portuguese: "dois" is no longer "doois" ("oi" is one gliding vowel again, as short as before), and "carro" no longer sounds like "cavo" (the strong r is voiceless again, but keeps its lighter noise) (#150).
- Portuguese: "lh" (batalha, filho, trabalho) is a held palatal l instead of an "i" (#152).
- US English: "during", "duration", "jury", "tourist" and "barista" have one r, not two, so they no longer sound like two words.
- A single word before a comma no longer falls like a full stop in Spanish, Portuguese, French, Italian, Romanian, Finnish and Hungarian, in every intonation mode: "Inglés, Estados Unidos", "Igen, persze", the first item of a list (#155).
- NVDA: Year splitting and Thousands separator stay unchecked after NVDA restarts (#151). The settings category is now just "TGSpeechBox". The Spanish translation is up to date (Leonardo), the add-on's description is translated into Spanish and Hungarian, the Hungarian and Brazilian Portuguese translations load in full again, and no setting label shows up blank (#154).
- Phoneme editor: the User dictionary type edits your own -user.tsv instead of the shipped dictionary, a dictionary save keeps the notes at the top of the file, and the guide (README-phoneme-editor.md) is rewritten to cover everything the editor does, voice profiles and dictionaries included.
Why now
Honestly, 3.10 stretched on long enough. Some things we hoped for didn't make it in: a currency dictionary (#83), more Croatian testing and fixes, and the others listed under Next. They're well scoped for the next release, and it mattered more to put out a stable release for everyone. With iOS 27 out and a new Android release here too, we went ahead now rather than later.
The voice
- Consonants are clearer everywhere. /s/ no longer smears toward /z/ after a vowel, voiced fricatives like /z/ and /v/ have their buzz, and fricatives carry a little more presence.
- Vowels are looser and less "clenched" (wider first-formant bandwidths), checked in a blind round with native listeners.
- A presence lift on the output of every voice and platform, with slightly raised upper formants, takes away the muffled, sore-throat quality some of you described, and the speaker sounds a little closer.
- Slow rates no longer produce a phantom echo; formants glide instead of stepping.
- Word-final stops are audible ("let", "cat"), and the breath after a released stop fades out in a pause instead of hissing through it.
- Rolled r's start with a contact and end on the release, which tidies the trill in every language that uses one.
- A light breath floor on vowels takes a little of the buzz off without sounding breathy.
- Pauses land in the same places on every platform, and now also at dashes, around parentheses, and before Spanish ¿ and ¡ (#133). Colons and semicolons get a full pause everywhere, and web addresses like example.com no longer split.
- US English has a loudness contour: sounds rise and fall in level the way speech does, so it sounds less spliced.
Languages
- Spanish: /g/ and /d/ between vowels are real events rather than blurs ("digo" no longer sounds like "y hoy"); the vowel around a tap or trill copies its neighbour ("amor" ends in /o/); doubled consonants within a word collapse; "las semillas" no longer restarts its /s/; /sj/ and /ts/ no longer drift toward "sh", and "siguiente" is cleaner; Mexican and Castilian /s/ are brighter; the letter y is "i griega", and r is "ere".
- Brazilian Portuguese: "oi" (foi, boi, dois) is no longer the English "boy", the strong r (carro, resumo) is a light throat r instead of a breathy h, and k no longer sounds like t (casa, cume), all tuned by Cleverson, a native speaker.
- Brazilian and European Portuguese: -ão ends on a real glide (pão, não, coração), nasal vowels are actually nasal, "agora" no longer sounds like "agota", and the letter names are right, accents included (ê and ô as "ê circunflexo", õ as "ô til").
- Hungarian: gy and ty are real sounds between vowels and at the start of words ("fagyi"), doubled consonants across words are both spoken ("kis sas"), and "arra" is no longer "ah-ra".
- English (UK): word-final stop bursts are no longer too quiet. English (Australia): the vowels in "price" and "mouth" are Australian. US English: flaps have a little more thump.
- Danish: v is spoken again (it was being dropped), and p, t, k now carry Danish aspiration, which is what tells them from b, d, g ("pære" and "bære", "tale" and "dale"). Danish still has a way to go; this is a first step.
- Swedish: words ending in rt, rd and rn ("bort", "bord", "barn") no longer lose their last consonant.
- Italian has stronger stress, Dutch a uvular r, French a real nasal "an", Croatian released final stops, open-mid e and a "uvod" that is no longer silent, and Polish ś ź ć dź sit further from sz ż cz dż.
- Portuguese, Swedish and Polish changes were checked with instruments and the phonetics literature more than by native ears; if your language sounds off, tell us which word.
NVDA add-on
- Follows the page's language when NVDA's automatic language switching is on. Text in your own language keeps your own dialect (a Brazilian user on a page marked "pt" stays Brazilian, a UK user stays UK), and switching back to a language already spoken costs about what eSpeak's own voice change does.
- Old settings saved from the NV Speech Player days can no longer overwrite the language files: a leftover "stop closure mode: none" was removing the pause before t, d and b for some of you. If consonants still run together for you, set Stop closure mode back to "Vowel and cluster" once.
- NVDA used to drop Spanish ¿ and ¡ before speech reached any voice. The add-on now brings a small symbol dictionary (NVDA 2024.4 and later) that passes them through, so TGSpeechBox can pause where a question or exclamation opens. It applies to every voice while the add-on is installed; if you'd rather not have it, set "Send actual symbol to synthesizer" to "never" for ¿ and ¡ in NVDA's Punctuation/symbol pronunciation dialog.
- Word-final sounds are no longer cut short, the capital-letter beep lands on the letter, volume 100% means the same as everywhere else, a word read twice sounds the same twice, when you move on quickly, nothing of the item you left leaks into the next one, and words either side of a dash, ¿ or ¡ no longer run together into one.
SAPI
- Long text starts speaking right away (the engine streams while it renders), stopping speech takes effect at once, and an interrupted item no longer delays the next one.
- Words either side of a dash, ¿ or ¡ no longer run together into one.
- Built against eSpeak NG 1.53 from its latest source; defaults to 22050 Hz on a fresh install.
Android
- Speaks on the lock screen right after a restart (Direct Boot).
- Runs on Wear OS watches; Android 16 is the target.
- Fast navigation no longer falls silent, and each utterance starts quicker.
iOS and macOS
3.10 is on its way to the App Store. VoiceOver's speech volume rotor now changes TGSpeechBox's volume (#119; it had no effect before). VoiceOver's pauses are honoured (they were collapsed to almost nothing), stopping mid-sentence is reliable, there is a pause between VoiceOver's separate announcements on iOS 27 ("dock", "page 1 of 4"), scaled by your pause setting, and TGSpeechBox no longer latches onto the wrong eSpeak voice when languages switch quickly.
Linux
Adam's pitch is fixed, speech-dispatcher's default pitch is read correctly, and profiles apply their voice settings. x86_64 and aarch64 builds are attached as before.
Voice profiles and the phoneme editor
- A voice profile sounds the same on every platform. Your own sliders adjust it from there, and a slider back at its default gives you the profile as it was saved. Beth and Bobby use their own written settings everywhere.
- Profiles can set their own inflection, and now their own chorus (chorusDepth and chorusDetuneHz under voicingTone).
- In the phoneme editor, Save to Profile now asks for a name and keeps the pitch and formant shape of the voice you started from, and loading a profile no longer shows it empty (saving one could drop parts of Beth). Phonemes gain frication tilt and closure gap fields. The editor's neutral slider positions now match NVDA's.
- New pitch mode: Arató (BraiLab), a port of the intonation routine of the 1991 Hungarian BraiLab screen reader. Its melody keeps its shape at any pitch.
Letters
- Letter names are read on Android, iOS and Linux too, a lone letter next to punctuation is spelled as a letter, and capitals find their names.
New: the engine in Python
People asked about the DSP behind the voice, so here it is: a small Python package, tgspeechbox, with the same engine every platform runs. You give it IPA, and you get audio back, plus every frame and the frontend's trace of what each processing step did.
pip install tgspeechbox-3.10.0-py3-none-win_amd64.whl (the file for your platform)
python -m tgspeechbox --ipa "həˈloʊ wˈɜːld" --out hello.wav
Wheels for Windows (64- and 32-bit), macOS (Intel and Apple Silicon) and Linux (x86_64 and aarch64) are attached. The package is MIT licensed and contains no eSpeak NG (which is GPL), so it takes IPA rather than text. It will go on PyPI once it has proven itself.
Tests
3.10 is the first release with a test suite behind it: the engine, the language packs, and now the NVDA add-on and the SAPI voice themselves, driven the way NVDA and Windows drive them. Every fix since beta 10 came with a test that failed first.
Since the first release candidate (in the second release candidate)
- Spanish: "algunos", "algunas" and "alguien" no longer have an r in them, and "seguro" is no longer "seguto" (#149); the /s/ after r and in "zz" is the dialect's own (#143, #81); a "y" before a consonant at the start of a word is the vowel i ("Yndio", #145); all-caps words Spanish can pronounce are read as words, and "tw" is "tu" (#146).
- Brazilian Portuguese (Cleverson): "oi" is close o plus a glide; the strong r is a lighter throat r; k has a short puff and no longer sounds like t.
- Danish (Michael): v is spoken again; p, t, k are aspirated, b, d, g are not, and none are after s.
- English: no puff after s ("stop", "sky") and a lighter one in the middle of words like "happy" (#26); UK English "going" and "following" keep their last syllable (#142); the US and Australian flap keeps its shape at fast rates.
- Pauses: a closing parenthesis pauses even with a comma inside it, and numbered list items ("01.") pause after the number (#141).
- NVDA: a setting you change in the TGSpeechBox settings panel now stays changed instead of turning itself back on (#140), and NVDA+Ctrl+R takes back language-file settings you haven't saved.
- SAPI: the Arató pitch mode can be chosen in the settings (#148).
- Linux: Adam's pitch is the same as on every other platform (#144), and the installer no longer edits speechd.conf; Speech Dispatcher finds the module on its own.
- Phoneme editor: knows the two new aspiration settings.
Since beta 10 (in the first release candidate)
For beta testers, what changed since beta 10:
- Portuguese: ê, ô and õ are read with their accents (#130).
- iOS: VoiceOver's speech volume rotor works (#119).
- Pauses at dashes, parentheses, ¿ and ¡, from one clause splitter every platform now shares, and NVDA now passes ¿ and ¡ through (#133).
- Fixed: leftover audio on fast navigation, on SAPI and NVDA (#135); "agota" sounding like "agora" on NVDA (#127); dialect switching (#131, #137); the Arató melody scales with pitch (#136); words either side of a dash, ¿ or ¡ no longer run together; every platform starts each request fresh; and switching back to a language is fast.
- New: chorus in voice profiles (#124), and the Python wheel.
Next
These moved to the next cycle: a currency dictionary (#83), more Croatian testing and fixes, microintonation for the Arató mode, a reshaped English melody, the loudness contour for UK, Australian and Canadian English, English inside Russian text (#118), the Classic mode's "?" melody (#155), dictionaries in the phoneme editor's Speak button, and Edu's new voice profiles.
Credits
gregodejesus2 for more reports, blind rounds and regression catches than anyone; 29-Bloo for the Spanish and SAPI reports and blind rounds; edu-fblind for Brazilian Portuguese, language switching, the log that solved #127, voice profiles and pushing the editor until it made sense; MarioPercinic for Croatian and the fast-rate report; TurkrosoftLabs for Australian English, Italian and Dutch; sevapopov2 for the iOS 27 pauses, the language-switching report and "going"; Vsevolod for word-final stops; dgomez42 for the Spanish diagnosis and the Arató pitch report; Cleverson for Brazilian Portuguese tuning done in the phoneme editor; thgcode for Portuguese "lh"; Spacedog for the English double r; Michael Hansen for Danish; nicopn for the English aspiration report; Garrote Klein for the Speech Dispatcher advice; LeonardoBlancoSerna for the Spanish translation and the translated add-on, and with rmcpantoja and yaresDg for Spanish research and testing; kaveinthran for iOS sample-rate findings; Christopher Toth for the Klatt and DECtalk research notes; Arató András and Vaspöri Teréz, the designers of BraiLab; and GPT-6 Astra for review rounds.
Built with Claude (Anthropic) as engineering partner.
— Tamas + Claudeo