• 首页
  • AI配音
  • 克隆配音
  • AI写作
  • 智能改写
  • 文案提取
  • 短视频工具
  • 文章工具
  • 资讯
  • 解说文案

声音克隆软件的技术原理

一、克隆自己声音的软件?

MockingBird是一款方便易用的中文语音克隆工具。该软件界面美观,已整合训练好的模型,不需要特别高的配置和IT水平,只需要几秒就可以克隆你自己的声音,有兴趣的小伙伴可以试试。

新媒体必备的工具大全

二、克隆技术的原理?

原理是同一个祖先细胞分裂繁殖而形成的纯细胞系,该细胞系中每个细胞的基因彼此相同。

1.克隆技术先将含有遗传物质的供体细胞的核移植到去除了细胞核的卵细胞中,利用微电流刺激等使两者融合为一体,然后促使这—新细胞分裂繁殖发育成胚胎,当胚胎发育到一定程度后,再被植入动物子宫中使动物怀孕,便可产下与提供细胞核者基因相同的动物。

2.克隆是英语单词clone的音译。它的原意是指幼苗和嫩枝以无性繁殖或营养繁殖的方法培养植物。随着时间的推移,克隆的内涵已经扩大了。只要是由一个体细胞获得二个以上的细胞、细胞群或生物体,由一个亲本系列产生的DNA系列,就是克隆。可见克隆是一种无性繁殖的方法。

3.1997年7月,一只名叫多莉的绵羊,通过克隆技术而诞生的消息传出后,立即引起了世界各地的注意,从此,克隆成了大家的热门话题。其实,克隆与我们并不陌生。我们在日常生活中也经常会用到这种无性繁殖的生物方法。例如,每当春暖花开的时候,喜欢种花弄草的人,就会做植物扞插的实验。从一棵植株上,剪下枝条,通过扞插就会得到许多遗传物质相同的植株,这就是克隆。

三、克隆技术原理?

克隆技术是利用细胞工程完成的的一项现代科技手段,其原理是取目标生物的体细胞核,利用显微注射技术将其注射到一同种雌性生物的去核卵细胞中,并刺激其形成类似受精卵的细胞,进一步使其分裂分化,到一定时期再移植到另一同种雌性生物子宫内,经正常妊娠后获得克隆个体。此个体的遗传物质与其孕母无任何关系,其绝大部分遗传信息均由目标生物提供,因此最像目标生物,但是又有极小部分遗传信息由提供卵细胞的雌性提供。

克隆技术是利用生物技术由无性生殖产生与原个体有完全相同基因组之后代的过程。科学家把人工遗传操作动物繁殖的过程叫克隆,这门生物技术叫克隆技术,含义是无性繁殖。克隆技术在现代生物学中被称为“生物放大技术”。

四、基因克隆技术的原理?

基因克隆技术包括把来自不同生物的基因同有自主复制能力的载体DNA在体外人工连接,构建成新的载体DNA,然后送入受体生物中去表达,从而产生遗传物质和状态的转移和重新组合.因此基因克隆技术又叫做分子克隆,基因的无性繁殖,基因操作,重组DNA技术以及基因工程等。

五、克隆技术原理属于?

克隆技术是利用细胞工程完成的的一项现代科技手段。

其原理是取目标生物的体细胞核,利用显微注射技术将其注射到一同种雌性生物的去核卵细胞中,并刺激其形成类似受精卵的细胞,进一步使其分裂分化,到一定时期再移植到另一同种雌性生物子宫内,经正常妊娠后获得克隆个体,此个体的遗传物质与其孕母无任何关系,其绝大部分遗传信息均由目标生物提供,因此最像目标生物,但是又有极小部分遗传信息由提供卵细胞的雌性提供。

六、克隆技术的原理及过程?

克隆技术是利用细胞工程完成的的一项现代科技手段,其原理是取目标生物的体细胞核,利用显微注射技术将其注射到一同种雌性生物的去核卵细胞中,并刺激其形成类似受精卵的细胞,进一步使其分裂分化,到一定时期再移植到另一同种雌性生物子宫内,经正常妊娠后获得克隆个体,此个体的遗传物质与其孕母无任何关系,其绝大部分遗传信息均由目标生物提供,因此最像目标生物,但是又有极小部分遗传信息由提供卵细胞的雌性提供.克隆技术是利用生物技术由无性生殖产生与原个体有完全相同基因组之后代的过程.科学家把人工遗传操作动物繁殖的过程叫克隆,这门生物技术叫克隆技术,含义是无性繁殖.克隆技术在现代生物学中被称为“生物放大技术”.

七、转基因技术和克隆技术的原理?

转基因技术的原理是将人工分离和修饰过的优质基因,导入到生物体基因组中,从而达到改造生物的目的。

转基因技术的理论基础来自进化论的分子生物学。 基因片段可以源自特定生物的基因组中所需的靶基因或来自特定序列人工合成的DNA片段。

将DNA片段转移到特定生物体中,与它们自己的基因组重组,然后从重组体中人工选择代数,以获得具有特定遗传性状稳定表现的个体。 该技术可以使重组生物增加所需的新特性并培育新品种。

八、克隆的原理?

资料:1938年,第一位现代胚胎学家、德国的汉斯?斯皮曼博士建议用成熟的细胞核植入卵子的办法进行哺乳动物克隆。

1952年,运用斯皮曼的构想,出现世界上第一只克隆青蛙。 1962年,约翰?格登宣布他用一个成熟细胞克隆出一只蝌蚪,从而引发了关于克隆的第一轮辩论。

1984年,斯蒂恩?威拉德森用胚胎细胞克隆出一只羊。

这是第一例得到证实的克隆哺乳动物。 1995年10月,美国麻省麻醉学家维坎蒂博士利用改良组织工程,令老鼠背上长出人耳,从而使人类能在实验室培育出可向人类移植的皮肤和软骨。

1996年7月,英国苏格兰罗斯林研究所成功地用羊乳腺细胞克隆出小绵羊"多利"。

1997年10月,英国专家研制出一个无头的青蛙胚胎,令其有关技术可以制造人类器官以便作为医学移植用途。

1999年7月,日本科学家克隆出多头牛,并将其肉类推向市场出售。

2000年4月,美国先进细胞工程公司克隆出6头比它们本身实际年龄年轻的小牛。

2000年,美国科学家用无性繁殖技术成功克隆出一只猴子"泰特拉",这意味着克隆人本身已没有技术障碍。 2001年11月25日,美国马萨诸塞州的生物技术

九、如何评价百度开发的「声音克隆」技术,半小时训练数据即可复制声音?

(以下内容搬运自飞桨PaddleSpeech语音技术课程,点击链接可直接运行源码)

一句话语音合成全流程实践

点击播放视频

1 声音克隆介绍 & 语音合成基本概念回顾

语音合成(Speech Sysnthesis),又称文本转语音(Text-to-Speech, TTS),指的是将一段文本按照一定需求转化成对应的音频的技术。

1.1 声音克隆的应用场景

随着以语音为交互渠道的产业不断升级,企业对语音合成有着越来越多的需求,比如智能语音助手、手机地图导航、有声书播报等场景都需要用到语音合成技术。通过语音合成技术想要得到一个新的音色,需要定制音库,但是定制音库所耗费的人力成本和时间成本巨大,成为产业升级的屏障。

声音克隆一般是指 one-shot TTS ,即只需要一条参考音频就可以合成该音色的语音,而无需收集大量该音色的音频数据进行训练。

1.2 声音克隆和语音合成的关系

声音克隆属于语音合成的一个小分类,想要合成一个人的声音,可以收集大量该说话人的声音数据进行标注(一般至少一小时,1400+ 条数据),训练一个语音合成模型,也可以用一句话声音克隆方案来实现。

声音克隆模型本质是语音合成的声学模型

一句话声音克隆的效果没有收集大量数据集训练或收集少量数据集 fintune 一个语音合成模型的效果好,其效果是否可以在商业中落地还有待商榷。

一般商业应用中想要合成某个特定的音色,需要收集大量数据进行训练,即使类似于百度地图的定制化音色播报,也是采用某种小样本 finetune的方案,至少需要用户录制 9 ~ 20 句指定文本内容的音频。

1.3 语音合成的基本流程回顾

本教程主要讲解基于深度学习的语音合成技术,流水线包含 文本前端(Text Frontend)声学模型(Acoustic Model)声码器(Vocoder) 三个主要模块:

  • 文本前端模块将原始文本转换为字符/音素
  • 声学模型将字符/音素转换为声学特征,如线性频谱图、mel 频谱图、LPC 特征等
  • 声码器将声学特征转换为波形

语音合成基本流程图

1.3.1 文本前端

文本前端模块主要包含: 分段(Text Segmentation)、文本正则化(Text Normalization, TN)、分词(Word Segmentation, 主要是在中文中)、词性标注(Part-of-Speech, PoS)、韵律预测(Prosody)和字音转换(Grapheme-to-Phoneme,G2P)等。

其中最重要的模块是 文本正则化 模块和 字音转换(TTS 中更常用 G2P 代指) 模块。

各模块输出示例:

• Text: 全国一共有112所211高校
• Text Normalization: 全国一共有一百一十二所二一一高校
• Word Segmentation: 全国/一共/有/一百一十二/所/二一一/高校/
• G2P(注意此句中“一”的读音):
    quan2 guo2 yi2 gong4 you3 yi4 bai3 yi1 shi2 er4 suo3 er4 yao1 yao1 gao1 xiao4
    (可以进一步把声母和韵母分开)
    q uan2 g uo2 y i2 g ong4 y ou3 y i4 b ai3 y i1 sh i2 er4 s uo3 er4 y ao1 y ao1 g ao1 x iao4
    (把音调和声韵母分开)
    q uan g uo y i g ong y ou y i b ai y i sh i er s uo er y ao y ao g ao x iao
    0 2 0 2 0 2 0 4 0 3 ...
• Prosody (prosodic words #1, prosodic phrases #2, intonation phrases #3, sentence #4):
    全国#2一共有#2一百#1一十二所#2二一一#1高校#4
    (分词的结果一般是固定的,但是不同人习惯不同,可能有不同的韵律)

1.3.2 声学模型

声学模型将字符/音素转换为声学特征,如线性频谱图、mel 频谱图、LPC 特征等。声学特征以 “帧” 为单位,一般一帧是 10ms 左右,一个音素一般对应 5~20 帧左右。声学模型需要解决的是 “不等长序列间的映射问题”,“不等长”是指,同一个人发不同音素的持续时间不同,同一个人在不同时刻说同一句话的语速可能不同,对应各个音素的持续时间不同,不同人说话的特色不同,对应各个音素的持续时间不同。这是一个困难的 “一对多” 问题。

# 卡尔普陪外孙玩滑梯
000001|baker_corpus|sil 20 k 12 a2 4 er2 10 p 12 u3 12 p 9 ei2 9 uai4 15 s 11 uen1 12 uan2 14 h 10 ua2 11 t 15 i1 16 sil 20

声学模型主要分为自回归模型和非自回归模型。自回归模型在 t 时刻的预测需要依赖 t-1 时刻的输出作为输入,预测时间长,但是音质相对较好;非自回归模型不存在预测上的依赖关系,预测时间快,音质相对较差。

主流声学模型: - 自回归模型: Tacotron、Tacotron2 和 Transformer TTS 等 - 非自回归模型: FastSpeech、SpeedySpeech、FastPitch 和 FastSpeech2 等

1.3.3 声码器

声码器将声学特征转换为波形,它需要解决的是 “信息缺失的补全问题”。信息缺失是指,在音频波形转换为频谱图时,存在相位信息的缺失;在频谱图转换为 mel 频谱图时,存在频域压缩导致的信息缺失。假设音频的采样率是 16kHz, 即 1s 的音频有 16000 个采样点,一帧的音频有 10ms,则 1s 中包含 100 帧,每一帧有 160 个采样点。声码器的作用就是将一个频谱帧变成音频波形的 160 个采样点,所以声码器中一般会包含上采样模块。

与声学模型类似,声码器也分为自回归模型和非自回归模型: - 自回归模型:WaveNet、WaveRNN 和 LPCNet 等 - 非自回归模型:Parallel WaveGAN、Multi Band MelGAN、Style MelGAN 和 HiFiGAN 等

更多关于语音合成基础的精彩细节,请参考之前的课程

2 基于说话人嵌入的声音克隆:SV2TTS

2.1 基本原理

SV2TTS 论文全称是 Transfer Learning from Speaker Verification to Multispeaker Text-To-Speech Synthesis, 是 Google 发表在 NeurIPS 2018 上的文章。

SV2TTS 模型结构图

SV2TTS 的声学模型使用了 Tacotron2,声码器使用了 WaveNet, 用于提取 speaker embedding 的声纹模型选择了 GE2E

SV2TTS 原作的开源代码是 Real-Time-Voice-Cloning, 仅支持英文合成,代码实现中使用的声码器是 WaveRNNMockingBird fork 自原作仓库并支持了中文合成。

在 Speaker Encoder、Synthesizer 和 Vocoder 阶段,PaddleSpeech 提供了不同的说话人编码器、合成器以及声码器组合。

|Speaker Encoder|Synthesizer|Vocoder| | :---:| :---: | :---: | |GE2E / ECAPA-TDNN |Tacotron2 / FastSpeech2|GAN Vocoder(Parallel WaveGAN / HiFiGAN / ...)|

2.2 模型训练

2.2.1 声纹模型

PaddleSpeech 已提供了预训练好的声纹模型,相关训练代码请参考 GE2EECAPA-TDNN。 PaddleSpeech 声纹相关课程请参考声纹检索系统与实践

2.2.2 声学模型

SV2TTS 与多说话人声学模型的区别是:多说话人声学模型在训练模型的时候,输入 spk_id 标识不同的说话人,模型内通过 Speaker Embedding Table (nn.Embedding 类)获取 speaker embeding,预测时只能选择在训练时包含的 spk_id只能合成训练集内的音色;而 SV2TTS 通过预训练好的声纹模型提取 speaker embeding,预测时可以输入任意说话人的音频作为参考音频,即使该说话人不在训练集中,也可以合成具有其音色的音频。

以 FastSpeech2 为例,两者的区别仅仅是红框所标部分。

基于 FastSpeech2 的多说话人语音合成模型

2.2.3 声码器

声音克隆模型本质是语音合成声学模型,声码器可以直接使用 PaddleSpeech 提供的各种声码器:Parallel WaveGANMulti Band MelGANStyle MelGANHiFiGAN 等, 由于声音克隆会见到各种不同的音色,建议使用 PaddleSpeech 提供的在多说话人数据集 AISHELL-3VCTK 上训练的声码器

声码器和数据集相关,如果待合成音色是成年女性音色,用 CSMSC(成年女性单说话人数据集)的声码器效果可能会更好,若待合成音色是男性音色,由于和女性声音特征相差较大,用 CSMSC 数据集训练的声码器的表现就不会很好,AISHELL-3、VCTK、CSMSC 都是 24k 的,声码器可以任意换,只是效果好不好的问题。

使用自己的数据重新训练或者 finetune 这些声码器,合成的音频会有更好的音质。

2.3 实践

以 ECAPA-TDNN 声纹模型 + FastSpeech2 声学模型为例,下列代码修改自 voice_cloning.py

安装 paddlespeech

# pip install paddlespeech or
!git clone https://github.com/PaddlePaddle/PaddleSpeech.git
from IPython.display import clear_output
%cd PaddleSpeech
!pip install .
%cd -
# 清理很长的内容
clear_output()
# 本项目的依赖需要用到 nltk 包,但是有时会因为网络原因导致不好下载,此处手动下载一下放到百度服务器的包
!wget https://paddlespeech.bj.bcebos.com/Parakeet/tools/nltk_data.tar.gz
!tar zxvf nltk_data.tar.gz
clear_output()

获取预训练模型和数据

!wget -P download https://paddlespeech.bj.bcebos.com/Parakeet/released_models/fastspeech2/fastspeech2_aishell3_ckpt_vc2_1.2.0.zip
!unzip -o -d download download/fastspeech2_aishell3_ckpt_vc2_1.2.0.zip
!wget -P download https://paddlespeech.bj.bcebos.com/Parakeet/released_models/pwgan/pwg_aishell3_ckpt_0.5.zip
!unzip -o -d download download/pwg_aishell3_ckpt_0.5.zip
clear_output()

获取 ref_audio

!wget -P download https://paddlespeech.bj.bcebos.com/Parakeet/docs/demos/ref_audio.zip
!unzip -o -d download download/ref_audio.zip
clear_output()

导入 Python 包

# 设置 gpu 环境
%env CUDA_VISIBLE_DEVICES=0

import logging
import sys
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)

import os
from pathlib import Path

import numpy as np
import paddle
import soundfile as sf
import yaml
from yacs.config import CfgNode

from paddlespeech.cli.vector import VectorExecutor
from paddlespeech.t2s.exps.syn_utils import get_am_inference
from paddlespeech.t2s.exps.syn_utils import get_voc_inference
from paddlespeech.t2s.frontend.zh_frontend import Frontend
clear_output()

主程序

am ='fastspeech2_aishell3'
am_config = 'download/fastspeech2_aishell3_ckpt_vc2_1.2.0/default.yaml'
am_ckpt = 'download/fastspeech2_aishell3_ckpt_vc2_1.2.0/snapshot_iter_96400.pdz'
am_stat = 'download/fastspeech2_aishell3_ckpt_vc2_1.2.0/speech_stats.npy'
phones_dict = "download/fastspeech2_aishell3_ckpt_vc2_1.2.0/phone_id_map.txt"

voc = 'pwgan_aishell3'
voc_config = 'download/pwg_aishell3_ckpt_0.5/default.yaml'
voc_ckpt = 'download/pwg_aishell3_ckpt_0.5/snapshot_iter_1000000.pdz'
voc_stat = 'download/pwg_aishell3_ckpt_0.5/feats_stats.npy'

# 读取 conf 配置文件并结构化
with open(am_config) as f:
    am_config = CfgNode(yaml.safe_load(f))
with open(voc_config) as f:
    voc_config = CfgNode(yaml.safe_load(f))
# 加载模型,第一次使用 vec_executor 时候会下载模型
# speaker encoder
vec_executor = VectorExecutor()

frontend = Frontend(phone_vocab_path=phones_dict)
print("frontend done!")

# acoustic model
am_inference = get_am_inference(
    am=am,
    am_config=am_config,
    am_ckpt=am_ckpt,
    am_stat=am_stat,
    phones_dict=phones_dict)

# vocoder
voc_inference = get_voc_inference(
    voc=voc,
    voc_config=voc_config,
    voc_ckpt=voc_ckpt,
    voc_stat=voc_stat)
ref_audio_path = 'download/ref_audio/yuantian01_02.wav'
sentence = '每当你觉得,想要批评什么人的时候,你切要记着,这个世界上的人,并非都具备你禀有的条件。'

input_ids = frontend.get_input_ids(sentence, merge_sentences=True)
phone_ids = input_ids["phone_ids"][0]

spk_emb = vec_executor(audio_file=ref_audio_path, force_yes=True)
spk_emb = paddle.to_tensor(spk_emb)

with paddle.no_grad():
    wav = voc_inference(am_inference(phone_ids, spk_emb=spk_emb))

sf.write(
    "output.wav",
    wav.numpy(),
    samplerate=am_config.fs)
print("Voice Cloning done!")
# 播放参考音频
import IPython.display as dp
dp.Audio("download/ref_audio/yuantian01_02.wav")
# 播放生成的音频
dp.Audio('output.wav', rate=am_config.fs)

SV2TTS 的效果受多说话人数据集和 Speaker Encoder 模型的影响较大,新发音人的声音会跟提取的 speaker embedding 在整个发音人向量空间中的最接近的那几个人的音色会比较像,因此一句话合成整体音色的效果因人而异,音色学习效果并不稳定。

具体实现代码请参考:

3 端到端声音克隆:ERNIE-SAT

ERNIE-SAT 是百度自研的文心大模型,是可以同时处理中英文的跨语言的语音-语言跨模态大模型,其在语音编辑、个性化语音合成以及跨语言的语音合成等多个任务取得了领先效果。可以应用于语音编辑、个性化合成、语音克隆、同传翻译等一系列场景。

点击播放视频

语音编辑的应用场景

3.1 基本原理

3.1.1 A3T 简介

ERNIE-SAT 是基于百度自研模型 A3T: Alignment-Aware Acoustic and Text Pretraining for Speech Synthesis and Editing 的改进,A3T 提出了一种对齐感知的声学、文本预训练模型,可以重建高质量的语音信号,多用于语音编辑任务。

训练时,根据 MFA 获取 mel 频谱和音素的对齐信息,mask 住单词文本对应的 mel 频谱,并对其进行重建。

A3T 模型结构图

预测时,使用额外的 Duration Predictor 模块(如,预训练好的 FastSpeech2 模型的 duration_predictor)获取待重建音频(输入文本对应的音频)的时长,构造相应的长度的空 mel 频谱并 mask 住,模型预测对应的 mel 频谱。

A $\color{red}{good}$ actor -> A $\color{blue}{successful}$ actor

语音编辑流程图

3 种不同的语音编辑

3.1.2 模型框架

ERNIE-SAT 中提出了 3 项创新: - 提出了一个通用的端到端语音和文本联合预处理框架用于跨语言语音合成,它可以联合学习语音和文本输入的统一表示。 - 由于多语语音语料库有限,有效地利用多个单语语音数据在单一模型中构建双语音素列表,并利用不同语言的数据重建语音和文本的训练目标。模型在跨语言推理过程中可生成高质量的语音。 - 能够对看不见的说话人执行跨语言语音合成,并且优于基于说话人嵌入的多说话人 TTS 方法(SV2TTS)。

ERNIE-SAT 模型结构图

ERNIE-SAT 是基于 A3T 的改进,A3T 没有对文本(phoneme)做 mask,只对语音(mel 频谱)做了 mask,只能对被 mask 住的语音做高质量重建,ERNIE-SAT 同时对语音和文本做 mask,可以同时重建语音信息和文本信息;此外,A3T 只能处理单语言的情况,并不支持跨语言合成,ERNIE-SAT 可以实现跨语言合成: 1. 纯中文和纯英文的 ERNIE-SAT,模型结构和 A3T 一样,直接使用 VCTK 数据集(英文)或 AISHELL-3 数据集(中文)进行训练 2. 中英文混合的 ERNIE-SAT 是语音和文本一起 mask,可以实现跨语言合成任务,混合 VCTK 数据集(英文)和 AISHELL-3 数据集(中文)进行训练 - 随机 mask 住 80% 的 mel 频谱特征 - 再 mask 住剩余的 20% 的 mel 频谱特征对应的 phoneme 里的一半

3.2 ERNIE-SAT 和 SV2TTS 的区别与联系

  1. SV2TTS 和 ERNIE-SAT 本质都是语音合成声学模型,需要输入合成文本信息,输出 mel 频谱特征,其后需要接声码器才能合成音频,都属于 one-shot TTS 模型。
  2. SV2TTS 和 ERNIE-SAT 都是声音克隆模型,都需要输入参考音频获取合成音频的音色信息。
  3. SV2TTS 需要额外的声纹模型作为 speaker encoder 提取参考音频的 speaker embedding 作为输入,在训练和预测时,并不是一个 end-to-end 的系统;ERNIE-SAT 直接输入参考音频的 mel 频谱获取音色特征,在训练和预测时都是完全 end-to-end 的。
  4. 对于 SV2TTS 所需的声纹模型来说,在低资源的语言场景中,收集大量多说话人、多语言数据来训练模型提取 speaker embedding 非常困难。
  5. SV2TTS 仅有声音克隆功能,ERNIE-SAT 在声音克隆的基础上,可同时完成语音编辑以及跨语言的语音合成任务。

3.3 实践

纯中文或纯英文的 ERNIE-SAT 支持语音编辑和个性化合成,中英文混合的 ERNIE-SAT 支持跨语言合成,本质都是声音克隆。

英文语音编辑为例,下列代码修改自 ernie_sat/synthesize_e2e.py,环境准备参考 vctk/ernie_sat

For that reason cover $\color{red}{should}$ $\color{red}{not}$ be given -> For that reason cover $\color{blue}{is}$ $\color{blue}{not}$ $\color{blue}{impossible}$ $\color{blue}{to}$ be given

获取预训练模型和数据

# prepare aligner
!mkdir -p tools/aligner
%cd tools
# download MFA
# !wget https://github.com/MontrealCorpusTools/Montreal-Forced-Aligner/releases/download/v1.0.1/montreal-forced-aligner_linux.tar.gz
!wget https://paddlespeech.bj.bcebos.com/MFA/montreal-forced-aligner_linux.tar.gz
# extract MFA
!tar xvf montreal-forced-aligner_linux.tar.gz
# fix .so of MFA
%cd montreal-forced-aligner/lib
!ln -snf libpython3.6m.so.1.0 libpython3.6m.so
%cd -
# download align models and dicts
%cd aligner
!wget https://paddlespeech.bj.bcebos.com/MFA/ernie_sat/aishell3_model.zip
!wget https://paddlespeech.bj.bcebos.com/MFA/AISHELL-3/with_tone/simple.lexicon
!wget https://paddlespeech.bj.bcebos.com/MFA/ernie_sat/vctk_model.zip
!wget https://paddlespeech.bj.bcebos.com/MFA/LJSpeech-1.1/cmudict-0.7b
%cd ../../
clear_output()
# prepare pretrained FastSpeech2 models
!mkdir download
%cd download
!wget https://paddlespeech.bj.bcebos.com/Parakeet/released_models/fastspeech2/fastspeech2_conformer_baker_ckpt_0.5.zip
!wget https://paddlespeech.bj.bcebos.com/Parakeet/released_models/fastspeech2/fastspeech2_nosil_ljspeech_ckpt_0.5.zip
!unzip fastspeech2_conformer_baker_ckpt_0.5.zip
!unzip fastspeech2_nosil_ljspeech_ckpt_0.5.zip
%cd ../
clear_output()
# prepare source data
!mkdir source
%cd source
!wget https://paddlespeech.bj.bcebos.com/Parakeet/released_models/ernie_sat/source/SSB03540307.wav
!wget https://paddlespeech.bj.bcebos.com/Parakeet/released_models/ernie_sat/source/SSB03540428.wav
!wget https://paddlespeech.bj.bcebos.com/Parakeet/released_models/ernie_sat/source/LJ050-0278.wav
!wget https://paddlespeech.bj.bcebos.com/Parakeet/released_models/ernie_sat/source/p243_313.wav
!wget https://paddlespeech.bj.bcebos.com/Parakeet/released_models/ernie_sat/source/p299_096.wav
!wget https://paddlespeech.bj.bcebos.com/Parakeet/released_models/ernie_sat/source/this_was_not_the_show_for_me.wav
!wget https://paddlespeech.bj.bcebos.com/Parakeet/released_models/ernie_sat/source/README.md
%cd ../
clear_output()
# 下载预训练模型
!wget -P download https://paddlespeech.bj.bcebos.com/Parakeet/released_models/ernie_sat/erniesat_vctk_ckpt_1.2.0.zip
!unzip -o -d download download/erniesat_vctk_ckpt_1.2.0.zip
!wget -P download https://paddlespeech.bj.bcebos.com/Parakeet/released_models/hifigan/hifigan_vctk_ckpt_0.2.0.zip
!unzip -o -d download download/hifigan_vctk_ckpt_0.2.0.zip
clear_output()

导入 Python 包

import os
from pathlib import Path
from typing import List

import librosa
import numpy as np
import paddle
import pypinyin
import soundfile as sf
import yaml
from pypinyin_dict.phrase_pinyin_data import large_pinyin
from yacs.config import CfgNode

from paddlespeech.t2s.datasets.am_batch_fn import build_erniesat_collate_fn
from paddlespeech.t2s.datasets.get_feats import LogMelFBank
from paddlespeech.t2s.exps.ernie_sat.align import get_phns_spans
from paddlespeech.t2s.exps.ernie_sat.utils import eval_durs
from paddlespeech.t2s.exps.ernie_sat.utils import get_dur_adj_factor
from paddlespeech.t2s.exps.ernie_sat.utils import get_span_bdy
from paddlespeech.t2s.exps.ernie_sat.utils import get_tmp_name
from paddlespeech.t2s.exps.syn_utils import get_am_inference
from paddlespeech.t2s.exps.syn_utils import get_voc_inference
from paddlespeech.t2s.exps.syn_utils import norm

定义 ERNIE-SAT 所需功能函数

def _p2id(phonemes: List[str]) -> np.ndarray:
    # replace unk phone with sp
    phonemes = [phn if phn in vocab_phones else "sp" for phn in phonemes]
    phone_ids = [vocab_phones[item] for item in phonemes]
    return np.array(phone_ids, np.int64)

def prep_feats_with_dur(wav_path: str,
                        old_str: str='',
                        new_str: str='',
                        source_lang: str='en',
                        target_lang: str='en',
                        duration_adjust: bool=True,
                        fs: int=24000,
                        n_shift: int=300):
    '''
    Returns:
        np.ndarray: new wav, replace the part to be edited in original wav with 0
        List[str]: new phones
        List[float]: mfa start of new wav
        List[float]: mfa end of new wav
        List[int]: masked mel boundary of original wav
        List[int]: masked mel boundary of new wav
    '''
    wav_org, _ = librosa.load(wav_path, sr=fs)
    phns_spans_outs = get_phns_spans(
        wav_path=wav_path,
        old_str=old_str,
        new_str=new_str,
        source_lang=source_lang,
        target_lang=target_lang,
        fs=fs,
        n_shift=n_shift)

    mfa_start = phns_spans_outs['mfa_start']
    mfa_end = phns_spans_outs['mfa_end']
    old_phns = phns_spans_outs['old_phns']
    new_phns = phns_spans_outs['new_phns']
    span_to_repl = phns_spans_outs['span_to_repl']
    span_to_add = phns_spans_outs['span_to_add']

    # 中文的 phns 不一定都在 fastspeech2 的字典里, 用 sp 代替
    if target_lang in {'en', 'zh'}:
        old_durs = eval_durs(old_phns, target_lang=source_lang)
    else:
        assert target_lang in {'en', 'zh'}, \
            "calculate duration_predict is not support for this language..."

    orig_old_durs = [e - s for e, s in zip(mfa_end, mfa_start)]

    if duration_adjust:
        d_factor = get_dur_adj_factor(
            orig_dur=orig_old_durs, pred_dur=old_durs, phns=old_phns)
        d_factor = d_factor * 1.25
    else:
        d_factor = 1

    if target_lang in {'en', 'zh'}:
        new_durs = eval_durs(new_phns, target_lang=target_lang)
    else:
        assert target_lang == "zh" or target_lang == "en", \
            "calculate duration_predict is not support for this language..."

    # duration 要是整数
    new_durs_adjusted = [int(np.ceil(d_factor * i)) for i in new_durs]

    new_span_dur_sum = sum(new_durs_adjusted[span_to_add[0]:span_to_add[1]])
    old_span_dur_sum = sum(orig_old_durs[span_to_repl[0]:span_to_repl[1]])
    dur_offset = new_span_dur_sum - old_span_dur_sum
    new_mfa_start = mfa_start[:span_to_repl[0]]
    new_mfa_end = mfa_end[:span_to_repl[0]]

    for dur in new_durs_adjusted[span_to_add[0]:span_to_add[1]]:
        if len(new_mfa_end) == 0:
            new_mfa_start.append(0)
            new_mfa_end.append(dur)
        else:
            new_mfa_start.append(new_mfa_end[-1])
            new_mfa_end.append(new_mfa_end[-1] + dur)

    new_mfa_start += [i + dur_offset for i in mfa_start[span_to_repl[1]:]]
    new_mfa_end += [i + dur_offset for i in mfa_end[span_to_repl[1]:]]

    # 3. get new wav
    # 在原始句子后拼接
    if span_to_repl[0] >= len(mfa_start):
        wav_left_idx = len(wav_org)
        wav_right_idx = wav_left_idx
    # 在原始句子中间替换
    else:
        wav_left_idx = int(np.floor(mfa_start[span_to_repl[0]] * n_shift))
        wav_right_idx = int(np.ceil(mfa_end[span_to_repl[1] - 1] * n_shift))
    blank_wav = np.zeros(
        (int(np.ceil(new_span_dur_sum * n_shift)), ), dtype=wav_org.dtype)
    # 原始音频,需要编辑的部分替换成空音频,空音频的时间由 fs2 的 duration_predictor 决定
    new_wav = np.concatenate(
        [wav_org[:wav_left_idx], blank_wav, wav_org[wav_right_idx:]])

    # 4. get old and new mel span to be mask
    old_span_bdy = get_span_bdy(
        mfa_start=mfa_start, mfa_end=mfa_end, span_to_repl=span_to_repl)

    new_span_bdy = get_span_bdy(
        mfa_start=new_mfa_start, mfa_end=new_mfa_end, span_to_repl=span_to_add)

    # old_span_bdy, new_span_bdy 是帧级别的范围
    outs = {}
    outs['new_wav'] = new_wav
    outs['new_phns'] = new_phns
    outs['new_mfa_start'] = new_mfa_start
    outs['new_mfa_end'] = new_mfa_end
    outs['old_span_bdy'] = old_span_bdy
    outs['new_span_bdy'] = new_span_bdy
    return outs


def prep_feats(wav_path: str,
               old_str: str='',
               new_str: str='',
               source_lang: str='en',
               target_lang: str='en',
               duration_adjust: bool=True,
               fs: int=24000,
               n_shift: int=300):

    with_dur_outs = prep_feats_with_dur(
        wav_path=wav_path,
        old_str=old_str,
        new_str=new_str,
        source_lang=source_lang,
        target_lang=target_lang,
        duration_adjust=duration_adjust,
        fs=fs,
        n_shift=n_shift)

    wav_name = os.path.basename(wav_path)
    utt_id = wav_name.split('.')[0]

    wav = with_dur_outs['new_wav']
    phns = with_dur_outs['new_phns']
    mfa_start = with_dur_outs['new_mfa_start']
    mfa_end = with_dur_outs['new_mfa_end']
    old_span_bdy = with_dur_outs['old_span_bdy']
    new_span_bdy = with_dur_outs['new_span_bdy']
    span_bdy = np.array(new_span_bdy)

    mel = mel_extractor.get_log_mel_fbank(wav)
    erniesat_mean, erniesat_std = np.load(erniesat_stat)
    normed_mel = norm(mel, erniesat_mean, erniesat_std)
    tmp_name = get_tmp_name(text=old_str)
    tmpbase = './tmp_dir/' + tmp_name
    tmpbase = Path(tmpbase)
    tmpbase.mkdir(parents=True, exist_ok=True)

    mel_path = tmpbase / 'mel.npy'
    np.save(mel_path, normed_mel)
    durations = [e - s for e, s in zip(mfa_end, mfa_start)]
    text = _p2id(phns)

    datum = {
        "utt_id": utt_id,
        "spk_id": 0,
        "text": text,
        "text_lengths": len(text),
        "speech_lengths": len(normed_mel),
        "durations": durations,
        "speech": np.load(mel_path),
        "align_start": mfa_start,
        "align_end": mfa_end,
        "span_bdy": span_bdy
    }

    batch = collate_fn([datum])
    outs = dict()
    outs['batch'] = batch
    outs['old_span_bdy'] = old_span_bdy
    outs['new_span_bdy'] = new_span_bdy
    return outs


def get_mlm_output(wav_path: str,
                   old_str: str='',
                   new_str: str='',
                   source_lang: str='en',
                   target_lang: str='en',
                   duration_adjust: bool=True,
                   fs: int=24000,
                   n_shift: int=300):

    prep_feats_outs = prep_feats(
        wav_path=wav_path,
        old_str=old_str,
        new_str=new_str,
        source_lang=source_lang,
        target_lang=target_lang,
        duration_adjust=duration_adjust,
        fs=fs,
        n_shift=n_shift)

    batch = prep_feats_outs['batch']
    new_span_bdy = prep_feats_outs['new_span_bdy']
    old_span_bdy = prep_feats_outs['old_span_bdy']

    out_mels = erniesat_inference(
        speech=batch['speech'],
        text=batch['text'],
        masked_pos=batch['masked_pos'],
        speech_mask=batch['speech_mask'],
        text_mask=batch['text_mask'],
        speech_seg_pos=batch['speech_seg_pos'],
        text_seg_pos=batch['text_seg_pos'],
        span_bdy=new_span_bdy)

    # 拼接音频
    output_feat = paddle.concat(x=out_mels, axis=0)
    wav_org, _ = librosa.load(wav_path, sr=fs)
    outs = dict()
    outs['wav_org'] = wav_org
    outs['output_feat'] = output_feat
    outs['old_span_bdy'] = old_span_bdy
    outs['new_span_bdy'] = new_span_bdy

    return outs


def get_wav(wav_path: str,
            source_lang: str='en',
            target_lang: str='en',
            old_str: str='',
            new_str: str='',
            duration_adjust: bool=True,
            fs: int=24000,
            n_shift: int=300,
            task_name: str='synthesize'):

    outs = get_mlm_output(
        wav_path=wav_path,
        old_str=old_str,
        new_str=new_str,
        source_lang=source_lang,
        target_lang=target_lang,
        duration_adjust=duration_adjust,
        fs=fs,
        n_shift=n_shift)

    wav_org = outs['wav_org']
    output_feat = outs['output_feat']
    old_span_bdy = outs['old_span_bdy']
    new_span_bdy = outs['new_span_bdy']

    masked_feat = output_feat[new_span_bdy[0]:new_span_bdy[1]]

    with paddle.no_grad():
        alt_wav = voc_inference(masked_feat)
    alt_wav = np.squeeze(alt_wav)

    old_time_bdy = [n_shift * x for x in old_span_bdy]
    if task_name == 'edit':
        wav_replaced = np.concatenate(
            [wav_org[:old_time_bdy[0]], alt_wav, wav_org[old_time_bdy[1]:]])
    else:
        wav_replaced = alt_wav
    wav_dict = {"origin": wav_org, "output": wav_replaced}
    return wav_dict

主程序

erniesat_config = 'download/erniesat_vctk_ckpt_1.2.0/default.yaml'
erniesat_ckpt = 'download/erniesat_vctk_ckpt_1.2.0/snapshot_iter_199500.pdz'
erniesat_stat = 'download/erniesat_vctk_ckpt_1.2.0/speech_stats.npy'
phones_dict = 'download/erniesat_vctk_ckpt_1.2.0/phone_id_map.txt'

voc = 'hifigan_vctk'
voc_config = 'download/hifigan_vctk_ckpt_0.2.0/default.yaml'
voc_ckpt = 'download/hifigan_vctk_ckpt_0.2.0/snapshot_iter_2500000.pdz'
voc_stat = 'download/hifigan_vctk_ckpt_0.2.0/feats_stats.npy'

task_name = 'edit'
wav_path = 'source/p243_313.wav'
# should not -> is not impossible to
old_str = 'For that reason cover should not be given'
new_str = 'For that reason cover is not impossible to be given'
source_lang = 'en'
target_lang = 'en'
duration_adjust = True
output_name = 'sat_output.wav'

# evaluate(args)
with open(erniesat_config) as f:
    erniesat_config = CfgNode(yaml.safe_load(f))
with open(voc_config) as f:
    voc_config = CfgNode(yaml.safe_load(f))
# convert Chinese characters to pinyin
if source_lang == 'zh':
    old_str = pypinyin.lazy_pinyin(
        old_str,
        neutral_tone_with_five=True,
        style=pypinyin.Style.TONE3,
        tone_sandhi=True)
    old_str = ' '.join(old_str)
if target_lang == 'zh':
    new_str = pypinyin.lazy_pinyin(
        new_str,
        neutral_tone_with_five=True,
        style=pypinyin.Style.TONE3,
        tone_sandhi=True)
    new_str = ' '.join(new_str)

if task_name == 'edit':
    new_str = new_str
elif task_name == 'synthesize':
    new_str = old_str + ' ' + new_str
else:
    new_str = old_str + ' ' + new_str

# Extractor
mel_extractor = LogMelFBank(
    sr=erniesat_config.fs,
    n_fft=erniesat_config.n_fft,
    hop_length=erniesat_config.n_shift,
    win_length=erniesat_config. 
                                自媒体课程学习
                           

 

这篇关于《声音克隆软件的技术原理》的文章就介绍到这了,更多新媒体运营相关内容请浏览A5工具以前的文章或继续浏览下面的相关文章,望大家以后多多支持A5工具 - 全媒体工具网

上一篇:化妆教学视频去水印
下一篇:从视频中提取音频怎样提取视频中的音频?

相关资讯

查看更多
从视频中提取音频怎样提取视频中的音频?

从视频中提取音频怎样提取视频中的音频?

一、从视频中提取音频怎样提取视频中的音频?如何从视频中提取音频:1、首先从桌面打开Potplayer播放器,进入播放器主界面2、在播放器主界面上单击鼠标右键,选择“声音”选项,子菜单选择“音轨”,再继...
山西小院视频去水印

山西小院视频去水印

山西小院视频去水印 在数字时代,视频成为了人们生活中不可或缺的一部分。无论是在社交媒体上分享自己的生活片段,还是在工作中使用视频进行演示和培训,视频都扮演着重要的角色。然而,有时候在我们想要使用别人...
在线提取视频工具?

在线提取视频工具?

一、在线提取视频工具?现在网络上有很多在线提取视频工具,常见的有Clipchamp、FlexClip、Videoproc等。这些工具可以满足不同用户的需求,它们都可以轻松快捷地帮助用户提取视频或者修剪...
声音模拟器人声模拟 yuzu模拟器声音卡顿?

声音模拟器人声模拟 yuzu模拟器声音卡顿?

一、psp模拟器声音不流?把它修个修一下,插上电源,玩上点牛。跳跳接一下就可以了,声音就会流就会流通,太棒了。二、yuzu模拟器声音卡顿?修改设置1、运行yuzu模拟器之后,点击左上角的“文件”,选择...
西瓜旗袍视频去水印

西瓜旗袍视频去水印

在这篇博客文章中,我们将讨论有关西瓜旗袍视频去水印的内容。作为专业人士,我们将详细介绍如何有效地去除视频中的水印,并提供一些实用的技巧和工具。 了解西瓜旗袍视频去水印的重要性 在现今的数字时代,视...
怎么提取视频音频?

怎么提取视频音频?

一、怎么提取视频音频?如何从视频中提取音频:1、首先从桌面打开Potplayer播放器,进入播放器主界面2、在播放器主界面上单击鼠标右键,选择“声音”选项,子菜单选择“音轨”,再继续选择“声音录制”3...
录音变好听的修音软件 录音后怎么修音?

录音变好听的修音软件 录音后怎么修音?

一、朗诵录音怎么修音?录好后,使用修音软件进行后期处理,再播放。二、录音后怎么修音?首先可以通过放大波形找到一些不需要的杂音,比如口水、 唇齿、衣扣摩擦之类的声音,去除。然后可以使用Autotune之...
免费提取视频的网站?

免费提取视频的网站?

一、免费提取视频的网站?mixikit是一个不用注册就可以免费下载视频的网站二、快手提取视频无水印网站?没有。每个视频网站下载的视频都会有该视频网站的水印,这样是为了保护他的著作权。三、请问网站的视频...

移动版

扫一扫,打开小程序

扫一扫,打开小程序

扫一扫,关注公众号

扫一扫,关注公众号

热门工具

热门文章

推荐文章

分享赚佣金

扫描二维码进入小程序分享页