写8位PCM正弦波wav文件会产生泛音

时间:2016-04-23 18:08:01

标签: c++ audio wav pcm modulation

我用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;

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

1 个答案:

答案 0 :(得分:3)

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

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

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

噪声滤波不会将小数部分从舍入中丢弃,而是将此小数余数与IIR滤波器相结合,以将量化噪声移至可能听不到的位置,并且不太可能产生DC偏移。 / p>