修改音频样本缓冲区的音量增益

6
我希望增加缓冲区中的语音数据音量。问题在于我正在使用DirectSound,有一个主缓冲区和一个次要缓冲区——所有流的混合都是手动完成的。在语音聊天中,所有参与者都可以拥有独立的音量级别。我将每个流数据乘以一个值(增益),并将其总和添加到一个缓冲区中。一切都很好,但当我尝试将数据乘以大于1.0f的值时,会听到一些剪辑或其他奇怪的声音。
我尝试使用Audacity效果压缩器,但这并没有帮助减少奇怪的噪音。
也许我应该以其他方式修改增益?还是只需使用另一种后处理算法?
更新:哇,我刚发现了有趣的事情!我在增加音量之前和之后转储了音频。
这里是图片 Clipped audio 抱歉质量不高——我认为这就是声音应该出现的样子(我自己画了红线)。看起来真的像值超过了采样数据类型。但我无法理解为什么?我的样本缓冲区是BYTE,但我只通过short指针访问它。它是有符号的,但即使*ptr约为15-20千,剪辑也会发生。

什么是“一些剪辑或什么” - 您的值是否实际超出了示例数据类型的范围?而您所说的“尝试使用Audacity效果压缩器”是指在剪辑输出上还是在剪辑之前的输出上进行的? - lijie
样本是200毫秒的音频,采样率为22050赫兹。2个字节 - 短整型。如果我将此样本乘以1.f-原始音量-一切都很好。如果我乘以小于1.f的值-音量变低。但是,如果我乘以例如1.3f-音量会变高,但会有难听的刮痕噪音。我在混合缓冲区上使用了Audacity效果压缩器(带削波)。 - Dalamber
这是我的答案,附带一些代码 - 它是我脑海中的想法,所以不要指望它能直接运行。 - Daniel Mošmondor
1个回答

8
对于每个样本-将其转换为一些更大的数据类型-如果您有16位有符号样本,则最初适合SHORT-从流中提取它,然后转换为本地double,然后乘以,然后CLIP,然后转换回SHORT。
必须按这种方式工作...
如果需要,我甚至可以提供代码示例。
编辑:
您的图片正是您在乘法之前没有扩展到更大的类型的确凿证据-您无法“捕获”短剪辑条件,因为它将自动包装。
short* sampleBuffer;
...
short sample=*sampleBuffer;
double dsample=(double)sample * gain;
if (dsample>32767.0) {dsample=32767.0;}
if (dsample<-32768.0) {dsample=-32768.0;}
*sampleBuffer=(short)dsample;
sampleBuffer++;

还有一个编辑:

如果你有多个声音-首先将它们全部加倍-然后增益每个声音-然后将它们相加-最后裁剪它们。

再编辑一次(+1s让我受到启发):

如果你有立体声,同样的方法也可以使用,只需将所有样本数乘以2,即

短号数量=样本数量*2


哇!这真是一个超级棒的答案!非常感谢 - 我明天会尝试这种方法,如果一切顺利,我会标记为已回答 ;) - Dalamber
没错,它可以工作!老实说,这是我犯的一种愚蠢的错误 :'( Daniel,非常感谢你的帮助! - Dalamber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接