Spaces:
Running
Running
| """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 | |
| 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" | |
| 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). | |
| """ | |
| 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.) | |
| """ | |
| def cleanup(self) -> None: | |
| """Free GPU memory and any other resources. Called once after the batch.""" | |