mirror of
https://github.com/denizsafak/abogen.git
synced 2026-09-20 11:40:57 +02:00
fix(segmentation): process TTS segments per sentence, fix all subtitle modes
Sentence modes processed all text as a whole: Pipeline.__call__ merged every engine segment back into one (whole text, no per-token timings), producing a single giant subtitle and whole-text progress logs. - tts_plugin/types: add TokenTiming, AudioSegment, SynthesizedAudio.segments - tts_plugin/utils: Pipeline yields one Segment per engine segment (with tokens); merged fallback only when engine provides none - kokoro engine: expose per-segment graphemes/audio + per-word token timings - supertonic engine: expose per-segment graphemes/audio (no tokens) - split_pattern: English Sentence/Sentence+Comma engine split is newline-only (boundaries applied at subtitle time via spaCy); non-English Sentence+Comma with spaCy ON uses spaCy pre-segmentation + newline engine split (no commas); spaCy-off fallback keeps comma pattern - tts_segments: restore inter-segment whitespace on real per-word token boundaries only (never FakeToken fallbacks) - _to_language_enum: accept Language enum input (str(enum) is "Language.ES", silently resolved to EN_US and disabled spaCy pre-TTS for every language in WebUI) - pyqt/conversion, utils: replace print with logging - add AGENTS.md documenting the segmentation/subtitle contract for future sessions - tests: update English split-pattern expectations (1566 passing)
This commit is contained in:
@@ -19,6 +19,7 @@ from abogen.tts_plugin.errors import EngineError
|
||||
from abogen.tts_plugin.manifest import VoiceManifest
|
||||
from abogen.tts_plugin.types import (
|
||||
AudioFormat,
|
||||
AudioSegment,
|
||||
Duration,
|
||||
SynthesisRequest,
|
||||
SynthesizedAudio,
|
||||
@@ -113,6 +114,7 @@ class SuperTonicSession:
|
||||
total_steps = int(total_steps)
|
||||
|
||||
audio_parts: list[np.ndarray] = []
|
||||
segments: list[AudioSegment] = []
|
||||
for segment in self._pipeline(
|
||||
request.text,
|
||||
voice=voice,
|
||||
@@ -120,7 +122,17 @@ class SuperTonicSession:
|
||||
split_pattern=split_pattern,
|
||||
total_steps=total_steps,
|
||||
):
|
||||
audio_parts.append(segment.audio)
|
||||
audio = np.asarray(segment.audio, dtype="float32")
|
||||
if audio.size == 0:
|
||||
continue
|
||||
audio_parts.append(audio)
|
||||
segments.append(
|
||||
AudioSegment(
|
||||
graphemes=str(getattr(segment, "graphemes", "") or ""),
|
||||
audio=audio.tobytes(),
|
||||
sample_rate=self._pipeline.sample_rate,
|
||||
)
|
||||
)
|
||||
|
||||
if not audio_parts:
|
||||
return SynthesizedAudio(
|
||||
@@ -139,6 +151,7 @@ class SuperTonicSession:
|
||||
data=audio_bytes,
|
||||
format=AudioFormat(mime="audio/wav", extension="wav"),
|
||||
duration=Duration(seconds=duration_seconds),
|
||||
segments=tuple(segments),
|
||||
)
|
||||
except EngineError:
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user