speaker_helper.spoken_numbers module
Numbers, dates, times and amounts, said as words before an engine reads them.
Module summary
A neural engine trained on prose reads “le 14/11 à 9h30, 3 200 €” however its training data happened to: measured on 2026-11-04, Audio8 said “14/11” as an hour and swallowed the colon after “Correction”. Whisper hearing the right words back does not prove the listener did. The robust fix is the oldest one in speech synthesis: hand the engine words, not digits.
This module is that step for French and English, deterministic and dependency-free. Other languages pass through untouched — a wrong verbalisation is worse than the engine’s own guess. What it rewrites:
dates
14/11,14/11/2026(fr: day/month; en: month/day unless the first number cannot be a month);times
9h30,14 h,9:30,2:30 p.m.;amounts
3 200 €,12,50 €,3 M€,$3,200,€12.50,£5;percentages
7,94 %,12%;ordinals
1er,2e,3ème,1st,14th;grouped and decimal numbers
3 200,7,94(fr) /3,200,2.91(en), negatives, leading zeros (06→ “zéro six”), English years (2026→ “twenty twenty-six”).
It is applied by Speaker to what is spoken,
never to what a page shows: a narration’s cues keep the document’s digits.
settings.numbers_to_words = False turns it off.
Usage example
>>> from speaker_helper.spoken_numbers import verbalize
>>> verbalize("Rendez-vous le 14/11 à 9h30 pour 3 200 €.", "fr")
'Rendez-vous le quatorze novembre à neuf heures trente pour trois mille deux cents euros.'
>>> verbalize("Meet on July 12th at 2:30 p.m., $3,200.", "en")
'Meet on July twelfth at two thirty p.m., three thousand two hundred dollars.'
- speaker_helper.spoken_numbers.SUPPORTED_LANGUAGES: tuple[str, ...] = ('fr', 'en')
Languages this module verbalises; anything else is returned unchanged.
- speaker_helper.spoken_numbers.en_cardinal(n)[source]
Spell a non-negative integer in English.
Examples
>>> en_cardinal(3200) 'three thousand two hundred' >>> en_cardinal(1_000_001) 'one million one'
- speaker_helper.spoken_numbers.en_ordinal(n)[source]
Spell an English ordinal.
Examples
>>> en_ordinal(1), en_ordinal(12), en_ordinal(14), en_ordinal(21), en_ordinal(40) ('first', 'twelfth', 'fourteenth', 'twenty-first', 'fortieth')
- speaker_helper.spoken_numbers.en_year(n)[source]
Read a year the way English speakers do.
Examples
>>> en_year(2026), en_year(2000), en_year(2005) ('twenty twenty-six', 'two thousand', 'two thousand five') >>> en_year(1999), en_year(1900) ('nineteen ninety-nine', 'nineteen hundred')
- speaker_helper.spoken_numbers.fr_cardinal(n)[source]
Spell a non-negative integer in French.
Examples
>>> fr_cardinal(71) 'soixante et onze' >>> fr_cardinal(3200) 'trois mille deux cents' >>> fr_cardinal(80_000) 'quatre-vingt mille' >>> fr_cardinal(2_000_001) 'deux millions un'
- speaker_helper.spoken_numbers.fr_ordinal(n)[source]
Spell a French ordinal (
1→ “premier”).Examples
>>> fr_ordinal(1), fr_ordinal(5), fr_ordinal(9), fr_ordinal(21) ('premier', 'cinquième', 'neuvième', 'vingt et unième')
- speaker_helper.spoken_numbers.verbalize(text, language)[source]
Rewrite the digits in
textas the words a speaker would say.- Parameters:
- Returns:
The text with dates, times, amounts, percentages, ordinals and numbers spelled out; unchanged when it holds no digit.
- Return type:
Examples
>>> verbalize("Correction : non pas le 14, mais le 15.", "fr") 'Correction : non pas le quatorze, mais le quinze.' >>> verbalize("Un WER de 7,94 %.", "fr") 'Un WER de sept virgule quatre-vingt-quatorze pour cent.' >>> verbalize("Hola 12", "es") 'Hola 12'