我用C++编写了一个程序,用于为800Hz正弦波生成一个.wav文件(1 channel ,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;
避免不确定的行为。
同样的问题仍然适用。
最佳答案
您已经添加了舍入噪声和确定性量化噪声。您的正弦波将以精确的整数个样本重复。因此,舍入误差(或浮点值与正弦波的UInt_8值之间的差)会精确地周期性重复,从而产生可听见的谐波。
将浮点正弦波转换为UInt_8值时,可以通过使用抖动和噪声过滤舍入来减少这种噪声。
抖动(或在四舍五入前将分数随机值添加到每个样本)会消除确定性噪声。产生的噪声将更白,而不是泛音。
噪声滤波不仅可以舍弃小数部分的舍入,还可以将这一小数余数与IIR滤波器集成在一起,从而将量化噪声移至听不到的位置并不太可能产生DC偏移。
关于c++ - 写入8位PCM正弦波WAV文件会产生泛音,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36814549/