RishiKar210's picture
Initial backend deploy
99df98c
Raw
History Blame Contribute Delete
2.27 kB
"""Abstract base class for voice-conversion backends.
A teammate adds a new backend by:
1. Subclassing VoiceConverterBackend
2. Implementing setup(), convert(), cleanup()
3. Dropping the file in scripts/voice_convert/backends/
4. Adding the backend name to BACKEND_REGISTRY in cli.py
No other changes required. The CLI auto-dispatches by name.
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
@dataclass
class ConversionResult:
"""Per-clip result returned by a backend's convert() call."""
output_wav: Path
method: str # backend name (e.g. "seed_vc")
elapsed_seconds: float
metadata: dict[str, Any] = field(default_factory=dict)
success: bool = True
error: str | None = None
class VoiceConverterBackend(ABC):
"""Backend protocol. Subclass to implement a new voice-conversion method."""
name: str = "abstract"
@abstractmethod
def setup(self, config: dict[str, Any]) -> None:
"""Load model weights, allocate GPU, etc.
Called once per batch run before any convert() calls.
config carries backend-specific options (checkpoint paths, hyperparams).
"""
@abstractmethod
def convert(
self,
source_wav: Path,
target_voice_wav: Path,
output_wav: Path,
*,
preserve_accent: bool = True,
preserve_emotion: bool = True,
**kwargs: Any,
) -> ConversionResult:
"""Convert source speech to target voice.
Args:
source_wav: path to the speech to be converted (TTS output)
target_voice_wav: path to a reference clip of the target voice
output_wav: path where the converted WAV should be saved
preserve_accent: if True, request accent + style transfer (where supported)
preserve_emotion: if True, request emotion preservation (where supported)
**kwargs: backend-specific overrides (similarity, pitch_shift, etc.)
"""
@abstractmethod
def cleanup(self) -> None:
"""Free GPU memory and any other resources. Called once after the batch."""