前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >libsonic的原理介绍与应用

libsonic的原理介绍与应用

原创
作者头像
frankqpfu
发布2018-08-22 01:22:45
2.8K0
发布2018-08-22 01:22:45
举报
文章被收录于专栏:音视频应用

libsonic使用与原理介绍

引言:

在音频处理的时候常常会涉及到音频的变速、变调等方面的操作,使用的场景比较广泛如汤姆猫、男声变女声等,此外某些应用场合下的低延迟的播放器,往往也需要涉及到这方面的处理。目前常用的库是libsonic与libsoundtouch,两者的不同之处主要在于使用的算法上的差异,libsonic主要是使用的基于基音的变速处理,而libsoundtouch则主要基于的是波形相似的原理,在变速处理上libsonic对人声的处理更为优秀,而soundtouch对音乐等场景则更为适合。这里对libsonic的原理、使用介绍包括源代码等做一个分析和介绍。

libsonic的使用示范:

#include "sonic.h"

int main(int argc, char * argv[])

{

sonicStream sonicStream;

int sampleRate = 44100;

int channels = 2;

int samplesLength = 1024;   //常规AAC的samples 1024.

int rate = 1.5; //假设以1.5倍数进行播放

sonicCreateStream(sampleRate, channels);

sonicSetSpeed(sonicStream, rate);

while { //如果这里还有pcm的数据需要送入:

sonicWriteFloatToStream(sonicStream, (float*)inputPcmBuffer, samplesLength);

int couldReadSamples = sonicSamplesAvailable(sonicStream)

if (couldReadSamples > samplesLength) {

sonicReadFloatFromStream(sonicStream, (float*)outputPcmBuffer, samplesLength);

}

}

}

上面的例子展示了一个基本的44.1khz,双声道的pcm数据,经过libsonic然后以1.5倍数的速率进行播放后,得到新的pcm的数据的一个伪代码,此处的inputPcmBuffer和outputPcmBuffer需要自己读取真实的pcm数据和申请空间。其中sonicSetSpeed就是控制变速调用,在这个过程中可以动态的改变这个数值,变速的处理会在下一次pcm处理的时候生效。

声音变速处理的基本原理与概念:

声音变速主要对声音的PCM数据进行处理,使得在单位时间内播放的内容增加,在处理时会涉及声音的压缩操作,基础原理为OLA(Overlap and Add),原理示意图如下:

从x要得到压缩后的y的数据,根据要压缩的速率,选取前后的xm和xm+1

然后进行叠加到的ym,这里选择时间段间隔为20ms的内容,2个20ms的内容叠加得到30ms,相当于压缩了25%,也就是速度加快了1.25倍。

但是这种直接的相加会有如下的一些问题:

一个是音频的不连续,原始音频的波形比较连贯,经过处理后在直接叠加的部分会产生跳跃,会容易造成声音不连贯。

另一个是叠加部分造成声音的幅值改变,这两种都会造成声音的断续与失真。

后续改进这两个缺陷的方法有psola和wsola,基于基音的处理和基于波形相似的处理,需要指出的是上述方法都是针对时域的处理,还有针对频域的处理方法,不过计算复杂度过高,目前常用的还是针对时域的处理方法。

在实施OLA的处理的时候主要面对两个问题:1. 周期的选取,哪两段音频是可以用来叠加的?2. 叠加的时候如何保证信号的连续性?

基音周期-人声:

基音:声音的基础。根据声带震动的方式的不同,将声音信号分为清音和浊音。其中浊音需要声带周期性震动,所以具有明显的周期性,这种声带振动的频率称为基音频率,相应的周期就成为基音周期。其中男性说话者的基音频率较低,而女性说话者和小孩的基音频率相对较高,如果改变这个基音周期的话能实现这个男生变女声的效果。这里主要是解决第一个问题,周期的选取。

那么人声的基音周期如何寻找呢?假设声音的波形如下所示:

假设周期为t,经过平移后声音的波形将会产生近似的效果。那么如何反向推导这个t为多少呢?最直接的方法就是一个点一个点的试,经过挪动后得到的波形哪个最相似,哪个就是基音周期。那反过来也会带来计算量的问题,在这个过程中基音周期的寻找是比较耗时的。

上述的方法就是AMDF(平均幅度差函数法),公式表述为:

由于AMDF的计算主要是加法和减法,所以整体的计算量基本可控,另外由于人声音的基音周期有限(5ms-50ms),所以这个滑动比较的窗口也并不是很大。

我们来看下sonic中关于这个基音周期的寻找过程如下:

从这里看到在限定了最小和最大的基音周期后,滑动的窗口进行挪动,就能够得到diff的和, 如果(结果/周期)的值相对比较小,那么这个周期就是最佳的基音周期。

这里需要说明的是基音周期的寻找并非只有AMDF,只是AMDF方法相对比较简单,效果也不错,缺点就是应对复杂的噪声等环境的时候有一点局限性。

这里具体实现的时候在查找之前,会做一次下采样,将目标采样率下采样到4kHz,再进行AMDF,可以进一步提高查找的效率。

音频的压缩与变速处理

音频的压缩与变速主要是在changeSpeed中完成,变速算法会根据变速的速率,是否超过2倍变速,在实现上有所差别。

当1.0 < speed < 2.0,会对部分音频进行叠加处理,剩余的音频进行拷贝动作,这样达到压缩的目的,实现的示意图如下:

假设需要加速为1.25倍速,则数量为5的音频,需要压缩到4个。此时将2个音频进行叠加得到1个,然后剩余的3个音频原封不动的拷贝到目标输出,这样就获得了4个音频。

叠加的算法为了避免上述的波形不连贯与幅值波动的问题,算法的核心如下:

out为叠加后的目标输出,down和up分别是叠加的输入,分别对sample对down和up的输入取距离的权重,来表示同样位置的sample对叠加后的的目标输出的影响因子。

当i为0的时候,刚好等于这个down(0) , 当i为numsamples的时候恰好为up(numsamples),保持了这个信号的连续性。

当速率为2以上的倍数的时候,没有需要拷贝的内容,此时所有的原始输入信号都会直接进行压缩叠加处理。

而在降低播放速率的时候,进行的是一个类似的过程,前面主要是对声音进行压缩,而此时则是对声音进行拷贝和补充,补充的内容也是通过一样的的叠加策略而来。

其他的一些处理

音量调整:

音频的音量调整,是在原有的音频信号的基础上,乘以一个缩放的系数,如果放大的音量超过阈值的时候,会有一个折断,此时会导致波形的不完整,需要尽量避免这类的操作。

基音周期调整,男声变女声:

由于男声的基音周期普遍高于女声,在降低基音周期的同时也达到了男声变女声的效果,假设旧的基音周期为p,则新的基音周期缩短为p1, 选取p周期的前半部分数据,与p-p1开始的后半部分数据进行数据叠加处理,达到降低基音周期的目的。

变时又变调的处理:

主要是改变声音的频率周期,通过抽取或者内插来实现,在这个过程中需要使用使用滤波处理函数windowed sinc filter。

参考:

https://blog.csdn.net/sanglong01/article/details/46728089

https://wenku.baidu.com/view/93f5721b777f5acfa1c7aa00b52acfc788eb9f68.html

http://www.csie.ntnu.edu.tw/~u91029/Audio.html

https://www.cnblogs.com/welen/p/3782896.html

http://mirlab.org/jang/books/audiosignalprocessing/ptTimeDomainAmdf.asp?title=7-3%20AMDF&language=chinese

https://blog.csdn.net/liuxiaoheng1992/article/details/79379514

http://www.csie.ntnu.edu.tw/~u91029/Audio.html

https://blog.csdn.net/bugrunner/article/details/8829438

https://github.com/waywardgeek/sonic

http://blog.csdn.net/abcSunl/article/details/77196788?locationNum=3&fps=1

https://github.com/waywardgeek/sonic

https://github.com/waywardgeek/sonic/blob/master/doc/index.md

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • libsonic使用与原理介绍
    • 引言:
      • libsonic的使用示范:
        • 声音变速处理的基本原理与概念:
          • 基音周期-人声:
            • 音频的压缩与变速处理
              • 其他的一些处理
                • 音量调整:
                • 基音周期调整,男声变女声:
                • 变时又变调的处理:
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档