mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 13:40:27 +02:00
refactor(pyt): add text normalization via prepare_text_for_tts — P0
PyQt desktop GUI now calls the shared normalization pipeline before TTS synthesis, matching the Web UI's behavior: 1. Heteronym sentence rules (context-dependent pronunciation) 2. Pronunciation rules (token-level replacements) 3. Pipeline normalization (apostrophe handling, LLM) Before: PyQt passed raw text to the backend — no normalization at all, resulting in inferior audio quality compared to the Web UI. The normalization rules are compiled once at the start of run() from pronunciation_overrides and heteronym_overrides (currently None since the PyQt GUI doesn't expose these settings yet — basic apostrophe normalization still applies). 1053 tests pass.
This commit is contained in:
@@ -38,6 +38,7 @@ from abogen.domain.audio_buffer import (
|
||||
from abogen.domain.subtitle_generation import process_subtitle_tokens
|
||||
from abogen.domain.voice_loader import load_voice_cached
|
||||
from abogen.domain.progress import calc_etr_str
|
||||
from abogen.domain.normalization import prepare_text_for_tts
|
||||
from abogen.domain.metadata_extraction import (
|
||||
extract_metadata_and_build_args,
|
||||
read_text_for_metadata,
|
||||
@@ -535,6 +536,22 @@ class ConversionThread(QThread):
|
||||
fix_punct,
|
||||
)
|
||||
|
||||
# --- Compile normalization rules (heteronym + pronunciation) ---
|
||||
from abogen.domain.pronunciation import (
|
||||
compile_pronunciation_rules,
|
||||
compile_heteronym_sentence_rules,
|
||||
merge_pronunciation_overrides,
|
||||
)
|
||||
pronunciation_overrides = merge_pronunciation_overrides(
|
||||
getattr(self, "pronunciation_overrides", None),
|
||||
getattr(self, "manual_overrides", None),
|
||||
)
|
||||
self._pronunciation_rules = compile_pronunciation_rules(pronunciation_overrides)
|
||||
self._heteronym_rules = compile_heteronym_sentence_rules(
|
||||
getattr(self, "heteronym_overrides", None)
|
||||
)
|
||||
self._usage_counter = {}
|
||||
|
||||
# --- Chapter splitting logic ---
|
||||
# Use pre-compiled pattern for better performance
|
||||
chapter_splits = list(_CHAPTER_MARKER_SEARCH_PATTERN.finditer(text))
|
||||
@@ -1092,6 +1109,21 @@ class ConversionThread(QThread):
|
||||
print("Using split pattern: (unprintable)")
|
||||
|
||||
for text_segment in text_segments:
|
||||
# Normalize text through the shared pipeline
|
||||
# (heteronym + pronunciation + apostrophe normalization)
|
||||
try:
|
||||
text_segment = prepare_text_for_tts(
|
||||
text_segment,
|
||||
heteronym_rules=getattr(self, "_heteronym_rules", None),
|
||||
pronunciation_rules=getattr(self, "_pronunciation_rules", None),
|
||||
normalization_overrides=getattr(self, "normalization_overrides", None),
|
||||
usage_counter=getattr(self, "_usage_counter", None),
|
||||
)
|
||||
except Exception as exc:
|
||||
self.log_updated.emit(
|
||||
(f"Warning: Text normalization failed: {exc}", "orange")
|
||||
)
|
||||
|
||||
for result in self.backend(
|
||||
text_segment,
|
||||
voice=loaded_voice,
|
||||
|
||||
Reference in New Issue
Block a user