一、介绍
SoundTouch 是一个开源音频处理库,它允许相互独立地更改声音速度、音高和播放速率参数,即:
声音速度可以增加或减少,同时保持原始音高
音高可以增加或减少,同时保持原始速度
更改同时影响速度和音高的播放速率
选择速度/音高/速率的任意组合
1.1 联系方式
作者电子邮件: oparviai ‘at’ iki.fi
SoundTouch WWW 页面:http /soundtouch.surina.net
SoundTouch git 存储库:https /codeberg.org/soundtouch/soundtouch.git
另请注意,SoundTouch 可以使用 OpenMP 指令进行并行计算,以加快多核系统中的运行时处理速度,但这些改进需要在编译前单独启用。请参阅下面第 3 章中的 OpenMP 注释。
2.1. 在 Microsoft Windows 中构建
Microsoft Visual C++ 的项目文件随源代码包一起提供。前往 Microsoft WWW 页面免费下载 Microsoft Visual Studio Express 版本。
要使用 Visual C++ 编译器构建二进制文件,请运行“make-win.bat”脚本,或使用 Visual Studio 在源代码目录中打开相应的项目文件。最终的可执行文件将出现在“SoundTouch\bin”目录下。如果使用 Visual Studio IDE 而不是 make-win.bat 脚本,则可能需要手动为最终可执行文件的 SoundTouch 包根目录创建目录 bin 和 lib。make-win.bat 脚本会自动创建这些目录。
C# 示例:源代码包还包括一个适用于 Windows 的 C# 示例应用程序,它展示了如何调用 SoundTouch.dll 动态加载库来处理 mp3 音频。
OpenMP 注意:如果在编译中激活 OpenMP 并行计算,目标程序将需要额外的 vcomp dll 库才能正常运行。在 Visual C++ 9.0 中,可以在以下文件夹中找到这些库。
x86 32 位:C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.OPENMP\vcomp90.dll
x64 64 位:C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\amd64\Microsoft.VC90.OPENMP\vcomp90.dll
在其他 VC++ 版本中,预期会在类似的“redist”位置找到所需的库。
请注意,作为“dll地狱”现象的次要演示,vcomp90.dll的32位和64位版本具有相同的文件名但内容不同,因此请选择合适的版本以允许程序启动。
2.2. 在 Gnu 平台上构建
SoundTouch 库几乎可以在任何支持 GNU 编译器 (GCC) 工具的平台上进行编译。
2.2.1 使用自动工具编译
要为“autotools”工具链安装构建先决条件:
sudo apt-get install automake autoconf libtool build-essential
要构建和安装二进制文件,请在 /soundtouch 目录中运行以下命令:
./引导程序-
使用本地 autoconf/automake 工具集创建“配置”文件。
。/配置 -
为本地环境配置 SoundTouch 包。请注意,在运行上述“./bootstrap”命令之前,“configure”文件不可用。
制作 -
构建 SoundTouch 库和 SoundStretch 实用程序。您可以选择在“make”之后添加“-j”开关以加快多核系统中的编译速度。
进行安装 -
将 SoundTouch 和 BPM 库安装到/usr/local/lib 并将 SoundStretch 实用程序安装到/usr/local/bin。请注意,将二进制文件安装到目标位置可能需要“root”权限。
编译可移植共享库/DLL 版本
GNU autotools 编译不会自动创建 SoundTouch(.so 或 .dll)的共享库版本,该版本具有与 C++ 库相比更适合跨语言开发的位置无关代码和 C 语言 api。
如果需要,请使用脚本“make-gnu-dll-sh”来构建可移植的动态库版本。
2.2.2 用cmake编译
‘cmake’ 构建脚本是作为 autotools 工具链的替代提供的。
要安装 cmake 构建先决条件:
sudo apt-get install libtool build-essential cmake
构建:
制作。
make -j
进行安装
要使用本机 C 语言 API 编译附加的可移植共享库/DLL 版本:
制作。-DSOUNDTOUCH_DLL=ON
make -j
make install
2.3. 在 Android 中构建
Android编译说明在源码包内,详见源码包中的“ source/Android-lib/README-SoundTouch-Android.html ”文件。
Android 编译会自动为 ARM、X86 和 MIPS 处理器架构构建单独的 .so 库二进制文件。为获得最佳设备支持,请将所有这些 .so 库二进制文件包含到 Android .apk 应用程序包中,以便目标 Android 设备可以自动选择要使用的正确库二进制文件版本。
所述源极/ Android的LIB文件夹还包括一个Android示例应用程序,进程WAV使用SoundTouch库在Android设备的音频文件。
2.4. 在 Mac 中构建
按照http://macappstore.org/autoconf/ 中的说明安装 autoconf 工具,或者“cmake”工具链。
然后,按照上面“在 Gnu 平台中构建”部分中的描述进行构建。
默认样本类型是 32 位浮点格式,这也提供比整数格式更好的音质,因为整数算法需要缩放已经中间的计算结果以避免整数溢出。这些早期的整数缩放会略微降低输出质量。
在 Windows 环境中,通过选择以下定义之一在文件“STTypes.h”中选择示例数据格式:
#define SOUNDTOUCH_INTEGER_SAMPLES为 16 位有符号整数
#define SOUNDTOUCH_ FLOAT_SAMPLES用于 32 位浮点
在 GNU 环境中,默认使用浮动样本格式,但可以通过将以下开关切换到配置脚本来选择整数样本格式:
./configure --enable-integer-samples
样本数据可以有单(单声道)或双(立体声)音频通道。立体声数据是交错的,因此每隔一个数据值用于左声道,每隔一秒用于右声道。请注意,虽然理论上可以将立体声作为两个单独的单声道处理,但不建议这样做,因为单独处理声道会导致失去声道之间的相位一致性,从而破坏立体声效果。
支持 8000-48000H 之间的采样率。
3.2. 处理延迟
SoundTouch 库的处理和延迟约束是:
SoundTouch 处理器的输入/输出处理延迟约为 100 毫秒。这是使用时间拉伸的时候。如果单独使用速率转置效应,则延迟要求要短得多,请参阅“关于算法”部分。
如果使用“快速”处理算法,则可以从相当于 Intel Pentium 133Mh 或更好的处理器开始,实时或更快地处理 CD 质量的声音(16 位立体声和 44100H 采样率)。如果不使用“快速”模式或正在使用浮点样本数据,则通常需要数倍的 CPU 功率。
3.3. 关于算法
SoundTouch 提供了三种看似独立的效果:速度、音高和播放速率控制。这三个控件是作为两个主要效果的组合实现的,采样率移调 和时间拉伸。
采样率移调影响音频流持续时间和音高。它是通过从原始音频样本进行插值将原始音频样本流转换为所需的持续时间来实现的。在 SoundTouch 中,使用带有抗混叠过滤的线性插值。理论上,高阶内插提供比一阶线性内插更好的结果,但在音频应用中,线性内插与抗混叠滤波在主观上与高阶滤波一样好。
时间拉伸意味着在不影响音高的情况下改变音频流的持续时间。SoundTouch 使用在时域中运行的类似 WSOLA 的时间拉伸例程。与采样率转置相比,时间拉伸是一项更繁重的操作,并且还需要更长的处理算法使用的声音样本处理“窗口”,从而增加了算法输入/输出延迟。SoundTouch 时间拉伸算法的典型输入/输出延迟约为 100 毫秒。
然后一起使用采样率移调和时间拉伸来产生速度、音高和速率控制:
“速度”控制纯粹是通过时间拉伸来实现的。
'Rate ’ 控制完全通过采样率转置来实现。
“音高”控制是作为时间拉伸和采样率移调的组合来实现的。例如,为了增加音调,音频流首先被时间拉伸到更长的持续时间(不影响音调),然后通过采样率移调移回原始持续时间,这同时减少持续时间并增加音调。结果是原始持续时间但增加了音高。
3.4 算法参数调优
时间拉伸算法的参数很少,可以调整以优化某些应用程序的声音质量。当前默认参数已通过迭代 if-then 分析(阅读:“试错”)选择,以在流行/摇滚音乐处理中获得最佳主观音质,但在处理不同类型声音的应用程序中,默认参数集可能导致次优结果。
时间拉伸算法默认参数值由文件“TDStretch.h”中的以下#defines 设置:
#define DEFAULT_SEQUENCE_MS AUTOMATIC
#define DEFAULT_SEEKWINDOW_MS AUTOMATIC
#define DEFAULT_OVERLAP_MS 8
这些参数对时间拉伸算法的影响如下:
DEFAULT_SEQUENCE_MS:这是单个处理序列的默认长度(以毫秒为单位),它决定了原始声音在时间拉伸算法中的截断方式。较大的值意味着在处理中使用的序列较少。原则上,减慢速度时较大的值听起来更好,但增加速度时听起来更糟,反之亦然。
默认情况下,此设置值是根据速度值自动计算的。
DEFAULT_SEEKWINDOW_MS:寻找窗口默认长度(以毫秒为单位)用于寻找最佳重叠位置的算法。这决定了当声音序列要重新链接在一起时算法可以使用的样本“窗口”有多宽来找到最佳混合位置。
此窗口设置越大,找到更好混合位置的可能性就越大,但同时较大的值可能会导致“漂移”声音伪影,因为可以以更不均匀的间隔选择相邻序列。如果有令人不安的伪像听起来好像一个恒定的频率在漂移,请尝试降低此设置。
默认情况下,此设置值是根据速度值自动计算的。
DEFAULT_OVERLAP_MS:以毫秒为单位的重叠长度。当声音序列重新混合在一起以再次形成连续的声音流时,此参数定义了连续序列的末端将彼此重叠的程度。
这不应该是那个关键参数。如果您大量减少 DEFAULT_SEQUENCE_MS 设置,您可能希望对此尝试较小的值。
请注意,这些参数也可以在执行期间使用函数“ TDStretch::setParameters() ”和“ SoundTouch::setSetting() ”设置。
下表总结了如何针对不同应用调整参数:
参数名称 默认值大小 较大的值会影响… 较小的值会影响… 对 CPU 负担的影响
SEQUENCE_MS
默认值比较大,选择放慢音乐节奏 较大的值通常更适合放慢速度。当放慢速度时,增加该值会减慢“回声”伪像。 较小的值可能更适合加快节奏。降低该值会在减慢速度时加速“回声”伪影 增加参数值减少计算负担
SEEKWINDOW_MS
默认值比较大,选择放慢音乐节奏 较大的值更容易找到一个好的混合位置,但可能会导致“漂移”伪影 较小的减少了找到一个好的混合位置的可能性,但减少了“漂移”伪影。 增加参数值会增加计算负担
OVERLAP_MS
默认值比较大,选择适合以上参数。 如果您减少“sequence ms”设置,您可能希望尝试较小的值。 增加参数值会增加计算负担
3.5 性能优化
整数与浮点数:
通常建议使用浮点样本类型,因为它提供更好的音质。
但是,整数和浮点处理之间的执行速度差异取决于 CPU 架构。作为经验法则,
在 32 位 x86 浮点和整数中的速度大致相同
在 64 位 x86/x64 浮点中可以明显快于整数版本,因为 MMX 整数优化在 x64 架构中不可用。然而,这取决于编译器,因此 gcc 可以自动向量化整数例程以与浮点数一样快地工作,而 Visual C++ (2017) 的性能并不一样,并且生成的整数代码运行速度比 SSE 优化的浮点代码慢 3 倍.
在 ARMv7 中整数例程是浮点数的两倍。它们的相对差异在有和没有 NEON 的情况下大致相同;然而,NEON vfpu 可以带来 2.4 倍的速度提升。
在其他平台上:试试执行时间性能是否有很大的不同
一般优化:
时间拉伸例程具有“快速”模式,可显着加快算法速度,但可能会略微影响音质。此模式通过调用具有 SETTING_USE_QUICKSEEK 参数 id 和值为“1”的 SoundTouch::setSetting() 函数激活,即
设置(SETTING_USE_QUICKSEEK,1);
特定于 CPU 的优化:
英特尔 x86 特定的 SIMD 优化是使用编译器内在函数实现的,与非 SIMD 实现相比,x86 兼容处理器的处理速度提高了大约 3 倍:
当使用 16 位整数样本类型时,在 32 位 x86 构建中使用 MMX 优化例程
当使用 32 位浮点样本类型时,SSE 优化例程用于 32 位和 64 位 x86 CPU
这些算法经过调整,可以在其他 CPU 架构中也有效地利用自动向量化,例如,当存在 NEON SIMD 支持时,ARM cpu 的处理速度提高了大约 2.4 倍。
3.5 OpenMP 并行计算
SoundTouch 1.9 及更高版本支持在多个 CPU 内核中并行运行算法。基于基准测试,经验丰富的多核处理加速增益范围在 +30%(在高规格双核 x86 Windows PC 上)到 215%(在 Raspberry Pi2 的中等低规格四核 ARM 上)之间。
请参阅外部博客文章,了解有关 SoundTouch OpenMP 优化的更多详细讨论 。
并行计算支持是使用 OpenMP 规范 3.0 指令实现的。Visual C++ 2008 及更高版本以及 GCC v4.2 及更高版本支持这些指令。不支持 OpenMP 的编译器将忽略这些优化并且例程仍将正常工作。关于未知 #pragmas 的可能警告与 OpenMP 支持有关,可以安全地忽略。
OpenMP 改进在默认情况下是禁用的,需要由开发人员在编译时启用。这样做的原因是并行处理在管理多线程时增加了适度的运行时开销,因此在所有应用程序中它可能不是必需的也不可取的。例如,不受 CPU 功率限制的实时处理不会受益于并行处理提供的加速,相反,由于开销增加,它可能会增加功耗。
但是,在低规格多核 CPU 上运行且性能可能受限的应用程序将受益于 OpenMP 的改进。这包括例如多核嵌入式设备。
可以在编译 SoundTouch 库之前启用 OpenMP 并行计算,如下所示:
Visual Studio:打开SoundTouch 子项目的属性,浏览到C/C++和语言 设置。将“ OpenMP support ”设置为“ Yes ”。或者将/openmp开关添加 到命令行参数
GNU:使用“ ./configure --enable-openmp ”开关运行配置脚本,然后像往常一样运行 make
Android :在编译器和链接器选项中添加“ -fopenmp ”开关,更多详细说明请参见源代码包中的 README-SoundTouch-Android.html。
4. SoundStretch 音频处理实用程序
SoundStretch 音频处理实用程序
版权所有 © Olli Parviainen 2002-2015
SoundStretch 是一个简单的命令行应用程序,可以更改 WAV 声音文件的速度、音高和播放速率。该程序主要用于演示如何使用“SoundTouch”库在您自己的程序中处理声音,但它也可以用于处理声音文件。
4.1. SoundStretch 使用说明
SoundStretch 使用语法:
soundstretch infilename outfilename [开关]
在哪里:
“文件名”
输入声音数据文件的名称(.WAV 音频文件格式)。将“stdin”作为文件名以使用标准输入管道。
“输出文件名”
保存生成的声音的输出声音文件的名称(.WAV 音频文件格式)。如果您不想保存输出(例如,仅使用“-bpm”开关计算 BPM 速率时),则可以省略此参数。将“stdout”作为文件名以使用标准输出管道。
[开关]
是一个或多个控制开关。
可用的控制开关有:
-节奏=n
将声音速度更改 n 个百分比 (n = -95.0 … +5000.0 %)
-pitch=n
将音高更改 n 个半音(n = -60.0 … + 60.0 个半音)
-率=n
将声音播放率更改为 n 个百分比 (n = -95.0 … +5000.0 %)
-bpm=n
检测声音的每分钟节拍数 (BPM) 并调整速度以满足“n”个 BPM。应用此开关时,将忽略“-tempo”开关。如果省略“=n”,即单独使用开关“-bpm”,则估计并显示BPM 速率,但不会根据BPM 值调整速度。
-快的
使用更快的速度变化算法。速度提高,但音质下降。
-naa
不要在采样率转置中使用抗混叠过滤。速度提高,但音质下降。
-执照
显示程序许可证文本 (LGPL)
笔记:
要使用标准输入/输出管道进行处理,请相应地将“stdin”和“stdout”作为输入/输出文件名。标准输入/输出管道仍将携带 .wav 音频文件格式的音频数据。
数字开关允许整数(例如“-tempo=123”)和十进制(例如“-tempo=123.45”)数字。
“-naa” 和/或 “-quick” 开关可用于减少 CPU 使用率,同时影响一些音质
BPM 检测算法通过检测 <250Hz 的低频重复低音或鼓模式来工作。对于具有不均匀或复杂低音模式的音乐,可能会报告低于预期的 BPM 数字。
4.2. SoundStretch 使用示例
示例 1
以下命令将声音文件“originalfile.wav”的速度提高 12.5% 并将结果存储到文件“destinationfile.wav”:
soundstretch originalfile.wav destinationfile.wav -tempo=12.5
示例 2
以下命令将声音文件“orig.wav”的音调(键)降低两个半音,并将结果存储到文件“dest.wav”中:
soundstretch orig.wav dest.wav -pitch=-2
示例 3
以下命令通过将声音速度降低 25.3% 并将音高(键)增加 1.5 个半音来处理文件“orig.wav”。生成的 .wav 音频数据被定向到标准输出管道:
soundstretch orig.wav stdout -tempo=-25.3 -pitch=1.5
示例 4
以下命令检测文件“orig.wav”的 BPM 速率并调整速度以匹配每分钟 100 节拍。结果存储到文件“dest.wav”:
soundstretch orig.wav dest.wav -bpm=100
例 5
以下命令从标准输入管道读取 .wav 声音数据并估计 BPM 速率:
soundstretch 标准输入 -bpm
例 6
以下命令将歌曲从原始 440Hz 调音调到 432Hz 调音:这对应于将音高降低 -0.318 个半音: