mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 13:40:27 +02:00
feat: add SupertonicBackend implementing TTSBackend protocol
Encapsulate SupertonicPipeline as an internal detail of SupertonicBackend. The factory create_supertonic_backend() now returns a SupertonicBackend instance instead of a raw SupertonicPipeline, satisfying the TTSBackend protocol with metadata, synthesize, get_available_voices, get_supported_formats, and get_info methods. Backward-compatible __call__ delegates to the internal pipeline.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import numpy as np
|
||||
|
||||
from abogen.tts_backends.supertonic import SupertonicPipeline
|
||||
from abogen.tts_backends.supertonic import SupertonicBackend, SupertonicPipeline
|
||||
|
||||
|
||||
class _DummyTTS:
|
||||
@@ -26,13 +26,23 @@ class _DummyTTS:
|
||||
return audio, 0.05
|
||||
|
||||
|
||||
def test_supertonic_pipeline_strips_unsupported_characters_and_retries():
|
||||
# Avoid importing/initializing real supertonic by manually constructing the pipeline.
|
||||
def _make_pipeline() -> SupertonicPipeline:
|
||||
pipeline = SupertonicPipeline.__new__(SupertonicPipeline)
|
||||
pipeline.sample_rate = 24000
|
||||
pipeline.total_steps = 5
|
||||
pipeline.max_chunk_length = 1000
|
||||
pipeline._tts = _DummyTTS()
|
||||
return pipeline
|
||||
|
||||
|
||||
def _make_backend() -> SupertonicBackend:
|
||||
backend = SupertonicBackend.__new__(SupertonicBackend)
|
||||
backend._pipeline = _make_pipeline()
|
||||
return backend
|
||||
|
||||
|
||||
def test_supertonic_pipeline_strips_unsupported_characters_and_retries():
|
||||
pipeline = _make_pipeline()
|
||||
|
||||
segs = list(pipeline("Hello • world", voice="M1", speed=1.0))
|
||||
assert len(segs) == 1
|
||||
@@ -43,11 +53,56 @@ def test_supertonic_pipeline_strips_unsupported_characters_and_retries():
|
||||
|
||||
|
||||
def test_supertonic_pipeline_drops_chunk_if_only_unsupported_characters():
|
||||
pipeline = SupertonicPipeline.__new__(SupertonicPipeline)
|
||||
pipeline.sample_rate = 24000
|
||||
pipeline.total_steps = 5
|
||||
pipeline.max_chunk_length = 1000
|
||||
pipeline._tts = _DummyTTS()
|
||||
pipeline = _make_pipeline()
|
||||
|
||||
segs = list(pipeline("•", voice="M1", speed=1.0))
|
||||
assert segs == []
|
||||
|
||||
|
||||
# --- SupertonicBackend tests ---
|
||||
|
||||
|
||||
def test_backend_metadata():
|
||||
backend = _make_backend()
|
||||
meta = backend.metadata
|
||||
assert meta.id == "supertonic"
|
||||
assert meta.name == "SuperTonic"
|
||||
assert "SuperTonic" in meta.description
|
||||
|
||||
|
||||
def test_backend_get_available_voices():
|
||||
backend = _make_backend()
|
||||
voices = backend.get_available_voices()
|
||||
assert isinstance(voices, list)
|
||||
assert "M1" in voices
|
||||
assert "F1" in voices
|
||||
|
||||
|
||||
def test_backend_get_supported_formats():
|
||||
backend = _make_backend()
|
||||
formats = backend.get_supported_formats()
|
||||
assert "wav" in formats
|
||||
|
||||
|
||||
def test_backend_get_info():
|
||||
backend = _make_backend()
|
||||
info = backend.get_info()
|
||||
assert info["sample_rate"] == 24000
|
||||
assert info["total_steps"] == 5
|
||||
assert isinstance(info["voices"], list)
|
||||
|
||||
|
||||
def test_backend_call_delegates_to_pipeline():
|
||||
backend = _make_backend()
|
||||
segs = list(backend("Hello • world", voice="M1", speed=1.0))
|
||||
assert len(segs) == 1
|
||||
assert segs[0].audio.size > 0
|
||||
|
||||
|
||||
def test_backend_synthesize_returns_wav_bytes():
|
||||
backend = _make_backend()
|
||||
wav_bytes = backend.synthesize("Hello world", voice="M1", speed=1.0)
|
||||
assert isinstance(wav_bytes, bytes)
|
||||
assert len(wav_bytes) > 0
|
||||
# WAV magic number
|
||||
assert wav_bytes[:4] == b"RIFF"
|
||||
|
||||
Reference in New Issue
Block a user