Files
diodiogod-TTS-Audio-Suite/utils/timing/overlap_detection.py
diodiogod d99318fe42 Modularize SRT overlap detection across all TTS engines
- Create utils/timing/overlap_detection.py with SRTOverlapHandler class
- Centralize overlap detection and smart_natural fallback logic
- Update ChatterBox, F5-TTS, and Higgs Audio to use modular utility
- Remove duplicate _detect_overlaps methods from all engines
- Ensure consistent overlap handling behavior across engines

Now all engines use the same logic for detecting overlapping SRT segments
and automatically falling back from smart_natural to pad_with_silence mode.
2025-08-20 18:44:02 -03:00

76 lines
2.9 KiB
Python

"""
SRT Overlap Detection and Smart Natural Fallback Utility
Modularized overlap detection and automatic fallback logic for all TTS engines
"""
from typing import List, Tuple
class SRTOverlapHandler:
"""
Utility class for detecting SRT subtitle overlaps and handling smart_natural mode fallback
Used by ChatterBox, F5-TTS, and Higgs Audio engines for consistent behavior
"""
@staticmethod
def detect_overlaps(subtitles: List) -> bool:
"""
Detect if subtitles have overlapping time ranges
Args:
subtitles: List of SRTSubtitle objects with start_time and end_time attributes
Returns:
bool: True if any overlaps are detected, False otherwise
"""
for i in range(len(subtitles) - 1):
current = subtitles[i]
next_sub = subtitles[i + 1]
if current.end_time > next_sub.start_time:
return True
return False
@staticmethod
def handle_smart_natural_fallback(timing_mode: str, has_overlaps: bool, engine_name: str) -> Tuple[str, bool]:
"""
Handle automatic fallback from smart_natural to pad_with_silence when overlaps are detected
Args:
timing_mode: Original timing mode requested by user
has_overlaps: Whether overlapping subtitles were detected
engine_name: Name of the engine for logging (e.g., "ChatterBox SRT", "F5-TTS SRT")
Returns:
Tuple of (actual_timing_mode, mode_switched):
- actual_timing_mode: The timing mode to actually use
- mode_switched: Whether a mode switch occurred
"""
if has_overlaps and timing_mode == "smart_natural":
print(f"⚠️ {engine_name}: Overlapping subtitles detected, switching from smart_natural to pad_with_silence mode")
return "pad_with_silence", True
return timing_mode, False
@staticmethod
def get_overlap_summary(subtitles: List, has_overlaps: bool) -> str:
"""
Generate a summary of overlap status for logging
Args:
subtitles: List of SRTSubtitle objects
has_overlaps: Whether overlaps were detected
Returns:
str: Summary message for logging
"""
if not has_overlaps:
return f"No overlaps detected in {len(subtitles)} subtitles"
# Count overlapping pairs
overlap_count = 0
for i in range(len(subtitles) - 1):
current = subtitles[i]
next_sub = subtitles[i + 1]
if current.end_time > next_sub.start_time:
overlap_count += 1
return f"Overlaps detected: {overlap_count} overlapping pairs in {len(subtitles)} subtitles"