实时变声算法实现(基频追踪+信号重构)

  • Voice Morph 简介
    • 思路简介
    • 基频追踪
      • 预处理
      • 基频计算
    • 信号重构
    • 总结

Voice Morph 简介

本人在语音信号处理领域工作了一年半时间,希望通过博客的方式来记录一下工作中的一些项目,以及自己在平时学习的一些心得。先从最近的一些项目开始写,前面的一些项目会慢慢补上。希望能与大家互相探讨,共同进步。
最近在工作中接触了一个变声算法,是从github上的一个开源项目改过来的。这个算法能够实现音高和音色的改变,同时保持语速不变,实现变声器的功能。算法分为两个互相独立的模块,分别是基频追踪和信号重构。与这个功能相对的是改变语速但保持音高音色不变,即变速不变调,这个大家在看视频的时候应该能体会到,不过这个算法就不介绍了,下面还是着重介绍变声算法。

思路简介

如果想实现男声变女声,要改变语音信号的两个特征,分别是音高和音色:
1.音高是指说话人的音调,这个主要是由声带振动频率决定的,一般来说女声的音高是高于男声的,不过在信号处理里面我们更喜欢把音调说成基频,代表了一段语音的基础频率,也就是频谱图最下面那条;
2.音色是指说话人所具有的个人特征,这个在频谱上表现为共振峰,反应的是声道的特性。一般来说男生的音色会更加雄厚,而女生的则更加清爽一些。
下面就来介绍如何去改变这两个特征,主要分为基频追踪和信号重构两个部分。

基频追踪

预处理

一般来说变声算法都需要对原信号的基频进行计算,且基频的计算越精确,最后的变声效果也会越好。计算基频的方式有很多种,这里就不多介绍了,我用了自相关函数法来追踪基频,但是在计算之前需要对信号进行预处理,避免不必要的麻烦,具体如下:
a)去直流
去除一帧信号的直流分量,尽可能减少直流分量带来的影响,下面的一些预处理都需要在去直流以后进行;
b)过零率检测
语音分为清音和浊音,通常说话的爆破声都属于清音,清音是没有基频的,所以需要在计算基频前先判断是否是清音,如果是清音就直接跳过基频计算部分,把这一段作为噪声处理。
那么如何去检测清音还是浊音,最简单有效的办法就是过零率检测,即检测信号在一帧内由正到负或者由负到正的次数,根据次数判断是清音还是浊音,一般来说清音的过零率会远大于浊音;
c)低通滤波
由于语音信号中可能有高频噪声,或者是语音本身的共振峰,都会影响自相关函数的计算。当信号中有高频成分时,自相关函数会计算出多个波峰,而基频的计算是根据自相关函数的波峰位置确定的,波峰太多会提高后续基频筛选的难度,因此需要用低通滤波滤除。低通滤波的截止频率一般选取600Hz,这是考虑到有些人在说话时基频可能能够达到600Hz;
d)峰值检测
除了排除清音以外,如果判断到当前帧是噪声,也需要跳过基频计算的步骤,这样可以避免错误的基频。我在算法中用了最简单的峰值检测来判断是否是噪声,这是基于一个假设:噪声段的信号强度一般小于语音段的信号强度,只要检测一帧内的最大峰值是否大于某个阈值,就可以判断这一帧是否是噪声。

基频计算

经过预处理以后,我们就知道哪些帧是需要计算基频的,这里采用了计算自相关函数来计算基频,计算的一般公式如下:
s(n)=∑m=0N−1f(m)∗f(m+n)s(n)=\sum_{m=0}^{N-1}f(m)*f(m+n) s(n)=m=0∑N−1​f(m)∗f(m+n)
上面是用时域的方法,为了节省运算量,也可以利用自相关函数与功率谱密度互为傅里叶变换对的特性来计算自相关函数。先对这一帧信号进行加窗,做FFT,利用帕斯瓦尔定理计算功率谱,再把该结果经过IFFT就得到了自相关函数。
如果原信号是比较周期的信号,则自相关函数也会呈现周期性,每隔一段时间就会产生波峰,如下图所示:

上面的图是原信号,下面的图是自相关函数,可以看到自相关函数在第一个点时值最大,因为自己与自己的相关性肯定是最大的,后续每次相关性的波峰出现的位置都正好对应了原信号的一个周期,只要寻找到自相关函数最大的那个波峰,计算与原点的距离,就能算出原信号的基频周期T。
实际计算时,会在一段较长的窗口内寻找自相关函数的波峰值,并记录对应的基频周期和自相关函数值,形成多个基频候选,在后续算法中再进行选择。基频候选点中比较常见的有半频候选,也叫半频误差,就是实际基频的一半(即周期为两倍)的频率也会呈现较高的自相关值,就如上面图中,除了在T位置有自相关的波峰,在2T位置也有,因此怎么去排除这种错误的候选基频也是基频追踪精准度的问题之一。
我选择了计算自相关函数的同时,进行原信号(低通滤波以后)波峰位置的估计,在一个窗口内采集若干个波峰,计算波峰之间的平均距离,在候选基频得分相近,且呈现出半频误差的形态时,根据波峰的平均距离选取可能性最大的基频。

信号重构

完成基频追踪以后就可以进行信号重构,信号重构也分为两个部分,分别是确定原信号波峰位置以及重构信号的计算。简单介绍一下信号重构的思路,与SOLA的方法有些类似:

图中从原信号重构输出信号,按照以下步骤进行:
a)确定重构信号的新基频;
b)确定重构信号的波峰位置(时间坐标),重构信号的第一个波峰与原信号的第一个波峰位置相同(理想情况下),然后根据新基频来确定后续的波峰位置,也就是每隔一个新的周期就是一个新的波峰位置;
c)以新的波峰位置为中心,计算两边的重构信号,具体思路与overlap加窗有点类似,先生成一个长度为原信号基频周期的余弦窗(或直接用余弦函数),然后用这个窗与原信号相乘,窗顶点与原信号的波峰要对应,计算得到的数据存在重构信号中。当前帧的前半帧的计算结果与上一帧的后半帧的计算结果叠加,就得到了最后的输出信号。这种重构方式能够一定程度上改善帧与帧之间的不连续性,避免高频噪声的产生。

完成上面的步骤以后就可以完成基频的更改,也就是能够获得一个音高被改变的音频。但是如果男声变女声的时候只改变音高,那你只能得到一个音调变高的厚重的男声…接下来就要对共振峰进行改变,才能达到最后的目的。

共振峰说白了就是基频上的一些高频分量,给一张图直观感受一下:

图中的基频波峰就是信号重构时需要找到的波峰,波峰之间的距离决定了音高,而波峰之间的高频分量就导致了共振峰的产生。如果按照上面信号重构的方法来计算,基频波峰之间的距离会被改变,但是波峰之间的高频分量的频率却不会被改变(因为按照算法来看,相当于原信号的数据乘上一个系数就被拿来重构信号了,那么原信号数据本身带有的频率信息是没有被改变的)。为了解决这个问题,就需要在重构时对整个信号进行拉伸或压缩,使得这些高频分量也会被改变频率。下面举个例子帮助理解:
现在有一个原音频,采样率为44.1k,男声。如果我需要把男声变女声,那么在进行信号重构时,需要进行上采样。如果进行1.2倍上采样(即采样率上升到52.92k),就在确定重构信号的波峰位置时,把波峰位置相对上个波峰的距离变为新基频的1.2倍,这样波峰之间的采样点数就是原来的1.2倍。在这种情况下再进行overlap加窗重构等操作,如果高频分量原来是800Hz(44.1k采样的情况下),那么现在就变成了960Hz。也就达到了改变共振峰频率的目的。最后我们得到了一个52.92k采样的音频,再经过重采样到44.1k。就完成了整个计算。

总结

这个算法整体的思路还是比较清晰的,主要难点在于基频的追踪,如何能更准确的追踪基频决定了算法的最后效果。之前有一些版本用了动态规划来做,但是动态规划有回溯的过程,这种思路在实时计算中比较难以实现(就算分块动态规划,延迟也稍微偏大了一些)。所以只能考虑多个角度来计算基频,通过多个计算结果来综合决定选取哪个候选基频,后续有机会的话可能考虑做一个代价函数来简化这一过程。

变声算法实现(基频追踪+SOLA)相关推荐

  1. SoundTouch与Rubber Band Library变声算法对比与ASR结果分析

    详细内容见群文件,欢迎大家加入音频/识别/合成算法群(696554058)交流学习,谢谢! 本内容原创,转载和使用请注明出处,谢谢配合: 变声背景与目的 目前基于对语音识别数据收集缓慢且质量不高的情况 ...

  2. 音频社交的变声,应用了哪些算法?

    导读:2021开年以来,音频社交市场伴随着Clubhouse的爆火再获资本的关注,国内相关产品荔枝.映客都迎来了股价的大幅上涨,预计未来音频化在社交领域还会有长期且广泛的需求. 在移动互联网技术加持下 ...

  3. 语音聊天室源码中的变声,应用了哪些算法?

    导读:2021开年以来,语音聊天室源码伴随着Clubhouse的爆火再获资本的关注,国内相关产品都迎来了股价的大幅上涨,预计未来音频化在社交领域还会有长期且广泛的需求. 在移动互联网技术加持下,语音聊 ...

  4. 音频算法之小黄人变声 附完整C代码

    前面提及到<大话音频变声原理 附简单示例代码>与<声音变调算法PitchShift(模拟汤姆猫) 附完整C++算法实现代码> 都稍微讲过变声的原理和具体实现. 大家都知道,算法 ...

  5. 【毕业设计系列】033:基于MATLAB语言的实时变声器系统【含Matlab源码】

    Date:2022.5.5 文章目录 前言 1.算法原理 2.实现效果 2.1.男声变女声 2.2.女声变男声 2.3.男声变大叔声 3.部分matlab代码实现 前言 在大学毕业设计中,要求实现一个 ...

  6. 【毕业设计/Matlab系列】基于MATLAB语言的实时变声器系统

    Date:2022.5.5 文章目录 前言 1.算法原理 2.实现效果 2.1.男声变女声 2.2.女声变男声 2.3.男声变大叔声 3.部分matlab代码实现 前言 在大学毕业设计中,要求实现一个 ...

  7. Any to Any 实时变声的实现与落地丨RTC Dev Meetup

    前言 「语音处理」是实时互动领域中非常重要的一个场景,在「RTC Dev Meetup丨语音处理在实时互动领域的技术实践和应用」活动中,来自声网.微软和数美的技术专家,围绕该话题进行了相关分享. 本文 ...

  8. Python实时变声教程:用代码实现自定义音频处理效果

    如何使用Python编写实时变声程序 随着人们对音频处理技术的需求越来越高,音频处理技术在各个领域的应用也越来越广泛.其中,实时变声技术是一种比较有趣的音频处理技术.本文将介绍如何使用Python编写 ...

  9. 柯南变声器的算法实现原理

    1.背景 小时候特别喜欢看柯南,里面有个变声蝴蝶结,让我印象深刻.变声蝴蝶结的作用就是可以把输入的语言转化成其它人的声音.举个例子,如果我有这个语音转换功能,下次录歌的时候就可以用周杰伦的声音录制(唱 ...

  10. soundtouch 变声使用和算法

    soundtouch 源码下载地址 编译完成之后$soundstretch --help This program is subject to (L)GPL license. Run "so ...

最新文章

  1. U-Boot 之二 详解使用 eclipse + J-Link 进行编译及在线调试
  2. This Style does not belong to the supplied Workbook. Are you trying to assign a style from one workb
  3. 数据查询和业务流分开_数据仓库介绍与实时数仓案例--阿里
  4. MySQL触发器 trigger学习
  5. 优酷电视剧爬虫代码实现一:下载解析视频网站页面(3)补充知识点:htmlcleaner使用案例...
  6. 计算机数学基础模拟试题,计算机数学基础》模拟考试试题.doc
  7. 小样本点云深度学习库_合成鲁棒的对抗样本来欺骗深度学习分类器
  8. 深度学习中常说的向量和表示
  9. 哈尔滨工程大学ACM预热赛(A,C,H,I)
  10. bindZip下载地址
  11. 有关目标的SMART法则
  12. java魔法门1_魔法门之英雄无敌5
  13. Linux 中各个文件夹的作用
  14. 解决git push报错问题
  15. 散粉在哪个步骤用_定妆粉是在哪个步骤用
  16. DDD第3篇 - 事件风暴
  17. 新同事上来就优化了一遍MySQL索引和查询,老板人傻了。。。
  18. linux下打开chm格式文件
  19. [RK3288][Android6.0] 不同分辨率的bootanimation.zip下载
  20. dodo:人脸识别方法个人见解zz

热门文章

  1. uniapp开发关于视频播放器适配H5的全屏(横屏)操作
  2. 修改IE地址栏Tomcat小猫咪图标
  3. IP地址中的网络地址和主机地址分别是什么意思?
  4. 用python中django创建网页_使用python Django做网页
  5. 即使是昏暗的街道,也有每日照耀的月
  6. 火狐浏览器打开IE窗口/IE跳谷歌页面等 --- 自定义协议---手动执行注册表
  7. 【生信可视化】ChemDraw基础操作教程
  8. 高级PHP工程师所应该具备的一些技能
  9. CVPR2021:单目标跟踪
  10. 拉普拉斯变换的性质 - 对查表