音频变时不变调处理(SoundTouch WSOLA)
现在已有一些博客写这相关的内容,但是真的写的看完和没看一样,我最近也研究了一下相关内容,为自己记个笔记,同时也分享出来,和大家一起讨论
变时不变调时音频处理里的一个小方向,但又没那么简单,算法有很多,我就以soundtouch库为例来展开聊一下。
-
soundtouch是一个音频处理开源库,其官网(http://soundtouch.surina.net),该库支持在windows、GNU、android平台的安装,有编译好的库也有源码。
-
soundtouch能处理wav格式的音频。
-
soundtouch支持音频的变时不变调处理(tempo),变调不变时处理(pitch),和变时变调处理(playback rate),在soundtouch的可执行命令里对应tempo、pitch、rate,其实这三个参数是通过两大类算法来控制的,tempo是通过类WSOLA算法来控制音频的时长且不改变音频的音调,rate是通过采样的算法加滤波算法(这两者一般是在一起的,不管是上采样还是下采样,因为抽取可能产生混叠,内插可能产生镜像,所以分别要使用抗混叠或抗镜像滤波器来处理,这两种滤波器一般都是低通滤波去)来控制音频的时长同时也改变音频的音调,pitch就是tempo+rate的结果。
-
soundtouch库对音频进行变时不变调处理时会有100ms的延时。
下面主要就讲一下WSOLA算法,这里不会讲到太深的理论,不使用复杂公式,通过一篇综述来讲一下:
- 综述名叫《A Review of Time-Scale Modification of Music Signals》,可以自己google一下 *
1.音频的时长变换TSM
时长变换基本分为三个步骤:
-
将音频按帧分解
-
将分解好的帧重新定位
-
合成最终音频
如下图所示:
音频的时长变换流程2.OLA算法(Overlap-Add)
看名字可以理解,这就是一个简单的叠加算法,先将输入的音频进行分帧处理,然后进行音频合成(叠加),叠加间隔计算如下面公式
叠加间隔计算公式OLA算法如下图所示:
OLA算法这样做会使得产生的音频有两个问题:
- 会造成音频的不连续,如下图所示
- 直接叠加会造成音频叠加部分信号幅值改变,如下图所示
3.WSOLA算法(Waveform Similarity Overlap-Add)
WSOLA类似于SOLA,不同的是在对输入音频分解成音频帧后不直接叠加,而是在一定的范围内查找待叠加的音频帧,该音频帧要符合与原位置处音频帧“波形最相似”的条件,符合该条件的音频帧作为输出帧进行输出视频的合成。“波形最相似”可以通过互相关系数来确定。
上面这句话可能较难理解,但是是核心,可以结合下图来理解(图片的注释很有帮助)
WSOLA算法原理基本就这样了,回到sountouch的源码来看一下,源码下载地址(http://soundtouch.surina.net/download.html),我目前下的是SoundStretch 2.0 for Mac OSX 版本,下载后解压,按照Readme安装该库,在文件夹soundstretch_mac_osx_v2.0.0/soundtouch/source中保存着soundtouch的源码,其中source/SoundStretch保存着一个使用样例用于音频的变时不变调处理,source/SoundTouch保存着soundtouch的源码。
自己用xcode新建了一个工程,源码使用source/SoundStretch,如下图所示
xcode工程目录在上图中,soundtouch_test文件夹中,main里面是主函数,RunParameters是用来处理输入参数的类,WavFile是用来处理wav文件的类,TDStretch就是用来处理变时不变调的类(改变tempo),RateTransposer是用来处理音频采样的类(改变tempo和pitch),pitch的实现则是使用了TDStretch和RateTranspose两个类。
在处理变时不变调时,可以调整三个参数,DEFAULT_SEQUENCE_MS、DEFAULT_SEEKWINDOW_MS、DEFAULT_OVERLAP_MS,这部分的设置方法可以在readme和TDStretch.h看到一些信息,默认的设置是有利于处理音乐音频,如果要处理演讲类的音频TDStretch.h给出了另一组设置。DEFAULT_SEQUENCE_MS指的是处理的音频片段长度,DEFAULT_SEEKWINDOW_MS指的是WSOLA算法中查找“波形最相似”音频的区域大小,DEFAULT_OVERLAP_MS指的是最后的叠加区域大小。
还有一点要注意的是在SoundTouch类中定义了virtualTempo、virtualPitch、virtualRate,这些是外部设置的参数与命令工具的tempo、pitch、rate不对应,而内部运算用的也不是virtualTempo、virtualPitch、virtualRate,而是SoundTouch类中的tempo、rate(如果命令工具设置tempo=-70则virtualTempo=0.3、virtualPitch=1、virtualRate=1,tempo=0.3、rate=1)