feat(lib): add voice reference resolution

This commit is contained in:
Federico Volovnik-Jose
2026-04-25 16:29:30 +02:00
parent 0370200d19
commit 1964079031
2 changed files with 80 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
"""Resolve a ComfyUI AUDIO input or string path into a voice-reference dict."""
import logging
import os
from typing import Optional
from lib.audio import audio_dict_to_wav
log = logging.getLogger(__name__)
def build_voice_reference(
audio: Optional[dict],
audio_path: str,
temp_dir: str,
) -> dict:
"""Return a voice-reference container.
Priority:
1. If `audio` is set, write it to a temp WAV and use that path.
If `audio_path` is also set, log a warning and ignore it.
2. Else if `audio_path` is non-empty, validate the path exists and use it.
3. Else return source="none" / path=None (default voice).
"""
if audio is not None:
if audio_path:
log.warning("Both audio and audio_path provided; ignoring audio_path=%r", audio_path)
path = audio_dict_to_wav(audio, dest_dir=temp_dir)
return {"path": path, "source": "audio"}
if audio_path:
if not os.path.isfile(audio_path):
raise FileNotFoundError(f"Voice reference audio not found: {audio_path}")
return {"path": audio_path, "source": "path"}
return {"path": None, "source": "none"}
+44
View File
@@ -0,0 +1,44 @@
import os
import pytest
from lib.voice import build_voice_reference
def test_no_inputs_returns_none_source(tmp_path):
result = build_voice_reference(audio=None, audio_path="", temp_dir=str(tmp_path))
assert result == {"path": None, "source": "none"}
def test_audio_path_only(tmp_path, sample_comfy_audio):
# Write a fake wav so the path exists
import torchaudio
wav_path = tmp_path / "ref.wav"
torchaudio.save(str(wav_path), sample_comfy_audio["waveform"][0], sample_comfy_audio["sample_rate"])
result = build_voice_reference(audio=None, audio_path=str(wav_path), temp_dir=str(tmp_path))
assert result["source"] == "path"
assert result["path"] == str(wav_path)
def test_audio_path_missing_raises(tmp_path):
with pytest.raises(FileNotFoundError):
build_voice_reference(audio=None, audio_path=str(tmp_path / "nope.wav"), temp_dir=str(tmp_path))
def test_audio_input_writes_temp_wav(tmp_path, sample_comfy_audio):
result = build_voice_reference(audio=sample_comfy_audio, audio_path="", temp_dir=str(tmp_path))
assert result["source"] == "audio"
assert os.path.isfile(result["path"])
assert result["path"].startswith(str(tmp_path))
def test_audio_wins_over_path(tmp_path, sample_comfy_audio, caplog):
import torchaudio
wav_path = tmp_path / "ref.wav"
torchaudio.save(str(wav_path), sample_comfy_audio["waveform"][0], sample_comfy_audio["sample_rate"])
result = build_voice_reference(
audio=sample_comfy_audio,
audio_path=str(wav_path),
temp_dir=str(tmp_path),
)
assert result["source"] == "audio"
assert result["path"] != str(wav_path)
assert any("audio_path" in rec.message for rec in caplog.records)