有人知道为什么我在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;
}
答案 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;