Skip to content

Repository files navigation

voxmorph

CI Python License: MIT Ruff

任意到任意(any-to-any)零样本语音转换工具包。

voxmorph 把一段语音拆解为“语言内容”和“说话人音色”两部分,转换时保留源语音的 内容表示,替换成目标说话人的音色统计量,再重新合成波形。整个流程无需训练, 对未见过的说话人也能直接工作,因此是零样本(zero-shot)的。

  • 内容 / 音色解耦:对数幅度谱做实例归一化(instance normalization), 去掉逐频带的全局统计量得到说话人无关的内容表示。
  • 说话人嵌入:把每个频带的均值与标准差拼接、归一化,作为训练无关的说话人表示。
  • AdaIN 音色重组:用目标说话人的统计量对内容做仿射变换,实现音色替换。
  • 离线优先:核心只依赖 NumPy;WAV 读写走标准库,无需任何音频库即可运行。
  • 可选 PyTorch 后端:FFT 可切换到 torch.fft,未安装时自动降级为 NumPy。
  • 客观评价:内置梅尔倒谱失真(MCD)、SNR、对数谱距离、谱收敛度,以及基于 说话人嵌入余弦相似度与等错误率(EER)的相似度评估。

安装

pip install voxmorph            # 核心(仅 NumPy)
pip install "voxmorph[torch]"   # 附带可选 PyTorch 后端

从源码开发:

uv sync --extra dev
uv run pytest

快速上手

无需任何音频素材,直接用内置的合成说话人做一次零样本转换:

from voxmorph import VoiceConverter, SpeakerEncoder
from voxmorph.datasets import synth_speaker

# 同样的“内容种子”配不同音色 = 两个不同说话人说同一句话
source = synth_speaker("alice", content_seed=1, duration=1.0)  # 提供内容
target = synth_speaker("bob", content_seed=7, duration=1.0)    # 提供音色

converter = VoiceConverter()
converted = converter.convert(source, target)

# 转换后语音的说话人身份更接近目标
spk = SpeakerEncoder()
print("转换后 vs 目标:", float(spk.embed(converted) @ spk.embed(target)))
print("转换前 vs 目标:", float(spk.embed(source) @ spk.embed(target)))

处理真实文件:

from voxmorph import VoiceConverter, read_wav, write_wav

source, sr = read_wav("source.wav")
target, _ = read_wav("target.wav")
converted = VoiceConverter().convert(source, target)
write_wav("converted.wav", converted, sr)

命令行

voxmorph convert  --source a.wav --target b.wav --output out.wav
voxmorph embed    --input a.wav  --output spk.npy
voxmorph features --input a.wav  --output mel.npy --kind mel
voxmorph evaluate --reference ref.wav --test out.wav        # 打印 MCD / LSD / SNR / 相似度

文档

许可证

MIT

About

任意到任意语音转换(VC)工具包(Python):内容与音色解耦、说话人嵌入 + 内容表示重组,实现零样本音色转换,含转换质量与说话人相似度评估(NumPy 内核、可选 PyTorch 后端、离线优先)

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages