Skip to content
11 changes: 11 additions & 0 deletions omnivoice/models/omnivoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
)
from omnivoice.utils.duration import RuleDurationEstimator
from omnivoice.utils.lang_map import LANG_IDS, LANG_NAMES
from omnivoice.utils.text_normalization import normalize_text as _normalize_text_ml
from omnivoice.utils.text import (
add_punctuation,
chunk_text_punctuation,
Expand Down Expand Up @@ -1061,6 +1062,16 @@ def _preprocess_all(
text_list = [
_normalize_text(t, lang) for t, lang in zip(text_list, language_list)
]

# Apply language-specific text normalization (e.g., numbers, currency,
# units) so the TTS model receives spoken-form text instead of raw
# digits/symbols. Currently supports Malayalam ("ml").
for i in range(batch_size):
if language_list[i] is not None:
text_list[i] = _normalize_text_ml(
text_list[i], language=language_list[i]
)

instruct_list = self._ensure_list(instruct, batch_size)
for i, s in enumerate(instruct_list):
if s is None:
Expand Down
44 changes: 44 additions & 0 deletions omnivoice/utils/text_normalization/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Text normalization utilities for TTS preprocessing.

Provides language-aware text normalization that converts numbers, currency,
percentages, and units into spoken-form text. This improves TTS pronunciation
quality for non-Latin scripts where raw digits produce poor speech output.

Currently supported languages:
- Malayalam (``ml``)

Usage::

from omnivoice.utils.text_normalization import normalize_text

text = normalize_text("എനിക്ക് ₹100 ഉണ്ട്", language="ml")
# Returns: "എനിക്ക് നൂറ് രൂപ ഉണ്ട്"
"""

from typing import Optional


def normalize_text(text: str, language: Optional[str] = None) -> str:
"""Normalize text for TTS based on the target language.

Converts numbers, currency symbols, percentages, and measurement units
into their spoken-word equivalents in the target language.

Args:
text: Input text that may contain raw numbers, currency, etc.
language: ISO 639 language code (e.g., ``"ml"`` for Malayalam).
If ``None`` or unsupported, the text is returned unchanged.

Returns:
Normalized text with numbers/symbols replaced by words.
"""
if language is None or not text:
return text

if language == "ml":
from omnivoice.utils.text_normalization.malayalam import normalize_malayalam

return normalize_malayalam(text)

# Unsupported languages pass through unchanged
return text
Loading