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

克隆自己的声音 怎么克隆别人的声音?

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

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

新媒体必备的工具大全

二、怎么克隆别人的声音?

用模仿声制作器和混合器模仿别人的声音

1.打开实用工具窗口,在模仿声制作器中,选择目标声音,输入名称,选择群组,并点击创建,把目标声音加入准备模仿的声音列表。

2.在准备模仿的声音列表中勾选新加入的模仿声,如果在已选模仿中有了新加入的模仿声,说明添加成功。

3.在您的声音部分,录制您自己的声音,或者载入一段您实现录好的声音,不用太长,5-10句话即可。

三、克隆出来的自己还是自己吗?

不是。克隆即无性繁殖,是指利用生物技术由无性生殖产生与原个体有完全相同基因组后代的过程。克隆的样品具有与母体相同的基因序列,只是一个复制样品,不是自己

四、QQ好友克隆被克隆的人的好友知道自己被克隆吗?

知道的,还会有提示,你被好友xxx克隆了。如果不喜欢的话,还可以设置,要经过自己的同意,才能被克隆。

五、怎么克隆自己啊?

普通QQ号克隆好友

首先只要我们先将自己原来的号和新号登陆一遍,然后在以旧号命名的文件夹里找到user.db数据库文件,复制.再到新号的文件夹里粘贴覆盖原文件.然后再登陆新号,你会发现哇~~好友都在了,不过都是永远不上线的,呵呵.没关系,接下来就是我们最关键的一步了,打开好友管理器(别跟我说不知道在哪里哦)在好友列表里选中自己想要加的人,记住哦,要按着ctrl来选啊,选好了,把刚才选中的好友全拉到陌生人一栏里,有人要问我,怎么要删掉啊,先别急,慢慢来,在跳出的对话框里都选确定啊,这样保证才能删掉,然后到陌生人一栏里,像刚才一样选中你的好友,^_^我拉,拉到好友列表里,哈哈这回要跳出好多要求好友确认的对话框,大功告成!!~~~慢慢点吧,虽然有点麻烦,可这是最简单的哦..

六、兰花是怎样克隆自己的?

兰花克隆 就是我们说的 组织培养, 它是一种快速短时间内繁育花苗的方法, 兰花组培的要求很高, 需要很多技术方法,具体我不清楚,如果想组培建议去专门的地方学习, 单纯的看书或上网查资料很难学到的, 兰花组培是将兰花假菱茎切块 放入试管中 使其繁殖 然后再切块,一生二 二生四 这样双被往上繁殖的 速度相当快

七、克隆了别人的好友自己还能给别人克隆吗?

qq被克隆,暂时不支持解除,只能通过把那个好友添加到黑名单或直接删除好友,才会取消克隆; 如果还是在对方号码的好友里,就不可避免的被克隆; 删除好友的步骤: 首先登陆QQ,然后打开主面板,点击状态按钮,然后选择“我的QQ中心”; 然后切换至好友管理; 继续在左侧选择好友分类,可以更细致地确定好友范围; 根据好友的昵称和备注以及上网时间,勾选自己的想要删除的好友; 选择是否在对方列表中删除自己,然后进行确认,点击确定即可。

八、qq空间克隆怎么把自己的照片克隆进去啊?

自己的照片是不需要克隆的,直接上传即可。如果是克隆朋友的照片。通过一键转载的方式克隆QQ空间照片。

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

(以下内容搬运自飞桨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.win_length,
    window=erniesat_config.window,
    n_mels=erniesat_config.n_mels,
    fmin=erniesat_config.fmin,
    fmax=erniesat_config.fmax)

collate_fn = build_erniesat_collate_fn(
    mlm_prob=erniesat_config.mlm_prob,
    mean_phn_span=erniesat_config.mean_phn_span,
    seg_emb=erniesat_config.model['enc_input_layer'] == 'sega_mlm',
    text_masking=False)

vocab_phones = {}

with open(phones_dict, 'rt') as f:
    phn_id = [line.strip().split() for line in f.readlines()]
for phn, id in phn_id:
    vocab_phones[phn] = int(id)

# ernie sat model
erniesat_inference = get_am_inference(
    am='erniesat_dataset',
    am_config=erniesat_config,
    am_ckpt=erniesat_ckpt,
    am_stat=erniesat_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)


wav_dict = get_wav( 
                                自媒体课程学习
                           

 

这篇关于《克隆自己的声音 怎么克隆别人的声音?》的文章就介绍到这了,更多新媒体运营相关内容请浏览A5工具以前的文章或继续浏览下面的相关文章,望大家以后多多支持A5工具 - 全媒体工具网

上一篇:app视频链接怎么提取?
下一篇:怎么提取iso文件里面的视频文件?

相关资讯

查看更多
怎么提取iso文件里面的视频文件?

怎么提取iso文件里面的视频文件?

一、怎么提取iso文件里面的视频文件?winrar解压缩,或者UltraISO软碟通提取,再或者用虚拟光驱把ISO镜像文件加载到虚拟光盘中,直接复制也行二、iso怎么提取dsd?foobar安装个新版...
语音生成器免费 姓氏谐音梗网名生成器免费?

语音生成器免费 姓氏谐音梗网名生成器免费?

一、tt语音涂鸦生成器叫什么?tt语音涂鸦生成器的中文名字是“字幕生成器”,英文名字是“TT Voice Recorder”。该软件可以将录制的声音转换为文本,并将其显示在屏幕上,实现可视化的效果。用...
怎么提取iso文件里面的视频文件?

怎么提取iso文件里面的视频文件?

一、怎么提取iso文件里面的视频文件?winrar解压缩,或者UltraISO软碟通提取,再或者用虚拟光驱把ISO镜像文件加载到虚拟光盘中,直接复制也行二、iso怎么提取dsd?foobar安装个新版...
对话式人工智能机器人 聊天游戏式对话?

对话式人工智能机器人 聊天游戏式对话?

一、机器人能与人对话主要是用了人工智能中的什么?机器人是一种复杂的技术,也是未来科技发展的趋势。机器人能与人工对话,主要是运用了人工智能中的自然语言处理(Natural Language Proces...
传统色彩提取及应用?

传统色彩提取及应用?

一、传统色彩提取及应用?传统的色彩提取主要是自然中的矿石为色彩原料。 矿石颜料的主要制作流程:矿石采集——粉碎矿石——淘、澄、飞,跌,研。(这个过程需要反复淘洗,不断去除杂质。)淘是用水淘洗杂质;澄是...
英语对话机器人 有关机器人的英语对话?

英语对话机器人 有关机器人的英语对话?

一、可以英语语音对话的机器人?推荐倚塔就是你的智能伙伴app里面有几大模块可以练习口语,还可以智能对话,也就是自由对话,这大大的给我们了一个聊天的主动权。我建议是正在学口语,正在考雅思或者是即将出国的...
怎么提取视频音频?

怎么提取视频音频?

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

如何把视频里的音乐提取出来?

一、如何把视频里的音乐提取出来?1.此方法适用于vivo X27手机首先打开抖音,向下滑动,选择一个要提取音频的视频2.接着选择并点击这个视频右侧的箭头符号,弹出设置框。3.然后在弹出来的新界面,点击...

移动版

扫一扫,打开小程序

扫一扫,打开小程序

扫一扫,关注公众号

扫一扫,关注公众号

热门工具

热门文章

推荐文章

分享赚佣金

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