2

我想知道 C++ 中放大 WaveForm 音频的正确公式是什么。

假设有一个 16 位波形数据如下: 0x0000 0x2000, 0x3000, 0x2000, 0x0000, (负部分), ...

由于声学原因,只是将数字加倍不会产生两倍大的音频,如下所示:0x0000 0x4000, 0x6000, 0x4000, 0x0000, (加倍负部分), ...

如果有人对音频修改很了解,请告诉我。

4

3 回答 3

7

如果将所有样本值加倍,它肯定会听起来“两倍响”,即响亮 6dB。当然,您需要小心避免由于削波而造成的失真——这就是当今所有专业音频处理软件在内部使用浮点采样的主要原因。

最终输出声音数据时,您可能需要返回整数。如果您只是为某些 DAW 编写插件(如果您想编写简单而有效的声音 FX 程序,我会建议您这样做),它会为您完成所有这些工作:您只需获得一个浮点数,用它做一些事情,然后再次输出一个浮点数。但是,例如,如果您想直接输出一个 .wav 文件,您需要首先限制输出,以便将高于 0dB(在通常的浮点流中为 +-1)的所有内容都剪裁为 +-1。然后你可以乘以你想要的整数类型可以达到的最大值-1,然后把它转换成那个类型。完毕。

无论如何,您肯定是对的,以对数方式而不是线性方式缩放音量旋钮很重要(许多消费级程序不这样做,这很愚蠢,因为您最终会使用非常接近旋钮左端的值范围),但这与放大计算本身无关,只是因为我们以对数尺度感知信号的响度。尽管如此,响度本身还是由声压常数因子的简单乘积决定的,而声压因子又与模拟电路中的电压和任何 DSP 中的数字样本值成正比。

另一件事:我不知道你打算走多远,但如果你想真正做到这一点,你不应该只剪掉超过 0dB 的峰值(剪裁听起来非常刺耳),而是实施适当的压缩器/限制器。然后,这将通过降低最响亮部分的电平来自动防止削波。您也不想过度使用(流行音乐通常会被过度压缩,结果会丢失很多动态音乐表达),但它仍然是增加音频电平的“不太危险”的方式。

于 2011-05-17T22:43:12.173 回答
2

我每次都使用线性乘法,它从未失败过。例如,它甚至适用于淡出...

所以

float amp=1.2;
short sample;
short newSample=(short)amp*sample;

如果您希望淡出是线性的,请在样本处理循环中执行

amp-=0.03;

如果你想对数,在样本处理循环中做

amp*=0.97;

直到 amp 达到某个小值(amp < 0.1)

于 2011-05-18T10:16:41.147 回答
0

这可能只是一个认知问题。您的耳朵(和眼睛 - 查找视频中的伽玛)不会在对输入的线性响应中感知响度。一个很好的模型是你的耳朵会响应感知到 ln(n) 的增加以增加音量。查找线性电位器和音频电位器之间的区别。

无论如何,我不知道这在这里是否重要,因为您的输出放大器可能会解释这一点,但是如果您希望它被感知为两倍响,您可能必须使其响亮 e^2 倍。这可能意味着您现在处于剪辑领域。

于 2011-05-17T22:44:49.443 回答