6

我用 C++ 编写了一个程序来为 800Hz 正弦波生成一个 .wav 文件(1 个通道,8 位,16000Hz 采样,32000 个样本,所以 2 秒长),但是当我在 Audacity 中播放它或检查它的频谱图时,它有泛音。

我认为问题在于将正弦波转换为 PCM 的算法;我不确定在哪里放置“零”位移,在 127、127.5 或 128 等处。

char data[32000];
for (int j = 0; j < 32000; ++j)
{
    data[j] = (char) (round(127 + 60 * (sin(2.0 * 3.14159265358979323846264338327950 * j / 20.0))));
}

生成的文件是这样的:output.wav

如有必要,这是 cpp 文件:wavwriter.cpp

谢谢!

编辑 2:我已将 char 更改为 uint8_t

uint8_t data[32000];
for (int j = 0; j < 32000; ++j)
{ 
    data[j] = round(127 + 60 * (sin(2.0 * 3.14159265358979323846264338327950 * j / 20.0)));


}
outfile.write((char *)&data[0], sizeof data);


outfile.close();
return true;

以避免未定义的行为。同样的问题仍然适用。

4

1 回答 1

3

您添加了舍入噪声和确定性量化噪声。您的正弦波以精确的整数个样本重复;因此,舍入误差(或浮点值与正弦波的 UInt_8 值之间的差异)会精确地周期性重复,从而产生可听的谐波。

在将浮点正弦波转换为 UInt_8 值时,您可以通过使用抖动和噪声过滤舍入来减少这种噪声。

抖动(或在舍入之前向每个样本添加小数随机值)消除了确定性噪声。由此产生的噪音将更白,而不是由泛音组成。

噪声过滤不只是从舍入中舍弃小数部分,而是将这个小数余数与 IIR 滤波器相结合,以将量化噪声移到它可能听不见且不太可能产生 DC 偏移的地方。

于 2016-04-23T22:20:59.163 回答