Multi-language syllable counter and TTS duration estimator (12 languages)
Project description
syllable-counter
Multi-language syllable counter and TTS duration estimator. Supports 12 languages with per-language strategies (pyphen hyphenation, pypinyin, regex on Hangul blocks, optional pyopenjtalk/phonikud).
Install
pip install syllable-counter
Optional native backends for better accuracy:
pip install syllable-counter[ja] # adds pyopenjtalk for Japanese
pip install syllable-counter[he] # adds phonikud for Hebrew
pip install syllable-counter[all] # both
Usage
from syllable_counter import count_syllables, estimate_duration
# Count syllables
count_syllables("hello world", lang="en") # 3
count_syllables("xin chào các bạn", lang="vi") # 4
count_syllables("我是中国人", lang="zh") # 5
count_syllables("iPhone15", lang="en") # iPhone + 15 = ~6
# Numbers are read in the target language
count_syllables("2026", lang="en") # "two thousand and twenty-six" → 7
count_syllables("2026", lang="es") # "dos mil veintiséis" → 4
count_syllables("2026", lang="zh") # "二零二六" → 4
# Symbols and units are spelled out
count_syllables("$25", lang="en") # "twenty-five dollars" → ~5
count_syllables("25°C", lang="en") # "twenty-five degrees celsius" → ~7
count_syllables("5km", lang="en") # "five kilometers" → ~4
count_syllables("100MB", lang="en") # "one hundred megabytes" → ~6
count_syllables("50%", lang="fr") # "cinquante pour cent" → ~5
# Estimate TTS duration
est = estimate_duration("hello world", lang="en")
# DurationEstimate(seconds=0.87, frames=47, syllable_count=3, ...)
Supported languages
| Code | Language | Backend |
|---|---|---|
en |
English | pyphen + vowel-group fallback |
es |
Spanish | pyphen + vowel-group fallback |
fr |
French | pyphen + vowel-group fallback |
de |
German | pyphen + vowel-group fallback |
it |
Italian | pyphen + vowel-group fallback |
pt |
Portuguese | pyphen + vowel-group fallback |
ru |
Russian | pyphen + per-vowel Cyrillic fallback |
vi |
Vietnamese | whitespace tokens (monosyllabic) |
zh |
Chinese | pypinyin |
ja |
Japanese | pyopenjtalk (optional) → char-range fallback |
ko |
Korean | regex on Hangul blocks |
he |
Hebrew | phonikud (optional) → CV-structure fallback |
Numbers are handled per-language via num2words (45 languages natively, with English fallback for the rest, plus digit-by-digit native fallback for Chinese).
Calibrated duration estimation
When you have reference word timestamps from a target speaker, you can calibrate:
ref_words = [
("hello", 0.0, 0.4),
("world", 0.5, 0.9),
("how", 1.0, 1.2),
("are", 1.3, 1.5),
("you", 1.6, 1.8),
]
est = estimate_duration("nice to meet you", lang="en", ref_words=ref_words)
est.calibrated # True
est.sec_per_syllable_used # fitted from the reference
Calibration uses OLS to fit word_duration ≈ silence + sec_per_syl × n_syllables. Falls back to per-language defaults when fewer than 5 usable reference words are provided.
Pause-aware
count_pauses(text) returns (short, medium, long) punctuation counts:
count_pauses("hello, world. yes!") # (1, 0, 2)
estimate_duration automatically adds pause time:
- short (
,,、,,) = 1× short_pause - medium (
;,:,;,:) = 1.5× short_pause - long (
.,!,?,。,!,?) = 2.5× short_pause
API
count_syllables(text: str, lang: str) -> int
compute_sec_per_syllable(ref_words, lang) -> (sec_per_syl, silence_overhead)
compute_short_pause(ref_words) -> float
count_pauses(text: str) -> (short, medium, long)
estimate_duration(target_text, lang, ref_words=None, ...) -> DurationEstimate
Errors:
UnsupportedLanguageError—langnot inSUPPORTED_LANGSInsufficientReferenceError— calibration needs ≥5 usable words
Limitations
- Pyphen-based fallback for unknown words is English-tuned for silent-e
'5.5'reads as "five five" (decimal point is lost; off by 1 syl)'-5'reads as just "five" (negative sign lost; off by 2 syl)- Hebrew without nikud uses
ceil(letters/2)approximation (±1 syl per word) - Japanese without
pyopenjtalktreats each kanji as 1 mora (kanji can be 2–3)
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file syllable_counter-0.2.1.tar.gz.
File metadata
- Download URL: syllable_counter-0.2.1.tar.gz
- Upload date:
- Size: 29.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c39e5df13350f3f73209b431a33f5c65f56a8f17a19def75558f1615c1efd90
|
|
| MD5 |
ff8ef8cb3c3b7c571aef99a3a3f3bdad
|
|
| BLAKE2b-256 |
700442e18b7de816e046cd205ad4e29eab553ed848c8817d3ee5c36907f5c214
|
File details
Details for the file syllable_counter-0.2.1-py3-none-any.whl.
File metadata
- Download URL: syllable_counter-0.2.1-py3-none-any.whl
- Upload date:
- Size: 20.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee8e18140f9c1ad86ba6d440516a59947f993ad707abe21acb3231dbb22fad94
|
|
| MD5 |
328c0a0d03c6321a9629cc5ea2465254
|
|
| BLAKE2b-256 |
9c1077b403cff3363f160301ae4266070f5ff56dbd8e39808811ebad8b036a5a
|