在pcm上减小音量后出现奇怪的噪音

时间:2012-02-24 22:03:34

标签: c++ audio

有人知道为什么我在c ++中应用这个算法来减少pcm的音量会在背景中产生白噪声吗?

for(int i = 0; i<pcm.length(); i+=2) {
   quint16 byte0 = pcm[i];
   quint16 byte1 = pcm[i+1];

   //merge byte0 and byte1
   qint16 n = (byte1 << 8) + byte0;

   n *= volume; // multiplier;

   //split n into byte0 and byte1
   byte1   = (n >> 8) & 255;
   byte0    = n & 255;

   //save the new values
   pcm[i] = byte0;
   pcm[i+1] = byte1;
}

4 个答案:

答案 0 :(得分:3)

很长一段时间后,我来找解决方案。问题是我正在合并两个叮咬的模式。

 for(int i = 0; i<pcm.length(); i+=2) {
   quint16 byte0 = pcm[i];
   quint16 byte1 = pcm[i+1];

   //merge byte0 and byte1
   qint16 n = 0;
   n |= speakersRaw[j][i+1] & 0xFF;
   n <<= 8;
   n |= speakersRaw[j][i] & 0xFF;

   n *= volume; // multiplier;

   //split n into byte0 and byte1
   byte1   = (n >> 8) & 255;
   byte0    = n & 255;

   //save the new values
   pcm[i] = byte0;
   pcm[i+1] = byte1;
}

答案 1 :(得分:0)

您的n *= 0.5实际上与n >>= 1的效果相同。您将最低有效位从byte1转移到byte0的最高位,这可能是您噪音的来源。

为什么要将这两个值组合成一个整数而不是分别执行每个整数?

答案 2 :(得分:0)

也许你正在以错误的顺序打包和解包你的字节?

qint16 n = (byte0 << 8) + byte1;

byte0   = (n >> 8) & 255;
byte1   = n & 255;  

答案 3 :(得分:0)

Mark Ransom提到的字节顺序是一个明显可能的问题。你应该检查一下。

另一个可能的问题是签名延期。

如果您已签名样本并且您正在以无符号类型操作它们,则将丢失所有负样本上的符号位。

如果您的字节类型已经过签名,那么当您加载byte0和byte1时,您将在高字节中进行符号扩展,而不是您想要的。

quint16类型是否与样本的实际类型相匹配?如果没有,您应该使用相同的类型。您应该让用户使用unsigned char作为字节类型。

从评论中的信息更新:

要测试符号扩展理论,请更改:

n *= 0.5;

行到:

n = ((short) n) * 0.5;