0 背景

最近要生成一个扫幅信号(amplitude sweep signal),要求幅值变化为12dB,信号为某个频率的正弦波或者白噪声均可。看了几个开源GUI软件,其中 audacityGenerate->Chirp 功能可以生成需求的正弦波,但是却不支持白噪声。如果先生成白噪声,然后通过添加 Effect -> Fade In ,则不能满足任意的幅值变化,幅值只能从 0 变为 1。

因此,我研究了一下命令行的音频处理工具,发现了本文要介绍的 SoX.

1 简介

Sox 号称音频处理界的“瑞士军刀”,提供了音频组合(包括mix, merge等),音频合成,以及音频播放器或者多轨录音器的功能。此外,它也提供了有限的分割一个音频文件为多个的功能。

Sox 在命令行上主要有以下四个程序:

SoX 的处理流程如下所示:

Input(s) → Combiner → Effects → Output(s)

注意,在命令行上调用时顺序与上面所示不同:

sox [global-options] [format-options] infile1
    [[format-options] infile2] ... [format-options] outfile
    [effect [effect-options]] ...

音频文件的格式

音频文件的格式的确定

SoX 有多个规则来决定音频文件的格式。

对于输入文件,SoX 会按照如下的优先级从高到低地去决定其格式:

  1. 命令行指定的格式选项
  2. 文件头的信息
  3. 文件名后缀

对于输出文件, SoX 会按照如下的优先级从高到低地去决定其格式:

  1. 命令行指定的格式选项
  2. 文件名后缀
  3. 输入文件的格式(其中好像不包括采样点的大小端)

2 实践

以下记录了我用 SoX 做的一些实践。

生成扫幅信号

这里假设我要生成一个幅值差12dB的正弦波文件。我使用的方法是利用 synthgain 生成一个恒定的正弦波,然后利用 synth, gainfade 生成一个渐入的正弦波。然后,将两者 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

同样的方法如果用于白噪声,得到的结果貌似不太精确。