SoX tips
0 背景
最近要生成一个扫幅信号(amplitude sweep signal),要求幅值变化为12dB,信号为某个频率的正弦波或者白噪声均可。看了几个开源GUI软件,其中 audacity
的 Generate->Chirp 功能可以生成需求的正弦波,但是却不支持白噪声。如果先生成白噪声,然后通过添加 Effect -> Fade In ,则不能满足任意的幅值变化,幅值只能从 0 变为 1。
因此,我研究了一下命令行的音频处理工具,发现了本文要介绍的 SoX
.
1 简介
Sox
号称音频处理界的“瑞士军刀”,提供了音频组合(包括mix, merge等),音频合成,以及音频播放器或者多轨录音器的功能。此外,它也提供了有限的分割一个音频文件为多个的功能。
Sox
在命令行上主要有以下四个程序:
play
用于播放音频rec
用于录音soxi
用于查询音频文件头的信息sox
提供了所有SoX
的功能(包括以上3个程序)
SoX
的处理流程如下所示:
Input(s) → Combiner → Effects → Output(s)
注意,在命令行上调用时顺序与上面所示不同:
sox [global-options] [format-options] infile1
[[format-options] infile2] ... [format-options] outfile
[effect [effect-options]] ...
音频文件的格式
音频文件的格式的确定
SoX
有多个规则来决定音频文件的格式。
对于输入文件,SoX
会按照如下的优先级从高到低地去决定其格式:
- 命令行指定的格式选项
- 文件头的信息
- 文件名后缀
对于输出文件, SoX
会按照如下的优先级从高到低地去决定其格式:
- 命令行指定的格式选项
- 文件名后缀
- 输入文件的格式(其中好像不包括采样点的大小端)
2 实践
以下记录了我用 SoX
做的一些实践。
生成扫幅信号
这里假设我要生成一个幅值差12dB的正弦波文件。我使用的方法是利用 synth
和 gain
生成一个恒定的正弦波,然后利用 synth
, gain
和 fade
生成一个渐入的正弦波。然后,将两者 mix起来。
这里需要计算两个正弦波的 gain 设为多少,计算过程如下:
设恒定的白噪声的RMS为 x, 渐入的白噪声的最大RMS为 y, 混音后的最大RMS为 z.
则有:(x + y) / 2 = z (1)
由于需要幅值差最大为12dB,可得:
(x + 0) / 2 = z / 4 # 因为12dB对应于4倍幅值差 (2)
由(1) 和 (2) 可得:
x = z/2
y = 3*z/2
假设上面的 x, y, z都是相对于特定格式所能表示的最大值的比例, 也即:
0 <= x, y, z <= 1
因此有:
0 <= z <= 2/3
我们可以取 x = 0.3, y = 0.9, z = 0.6. 相对应的增益为,恒定的波形增益为 20*log10(0.3/1) = -10.46dB
, 渐入的波形增益为 20*log10(0.9/1) = -0.92dB
.
由此,我们可以执行如下 SoX 命令:
$ sox -m "|sox -n -p synth 10 sine 1000 gain -10.46" "|sox -n -p synth 10 sine 1000 gain -0.92 fade t 10" output.wav
同样的方法如果用于白噪声,得到的结果貌似不太精确。
Comments