修改音频样本缓冲区的音量增益 [英] Modify volume gain on audio sample buffer

查看:56
本文介绍了修改音频样本缓冲区的音量增益的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想增加带有语音数据的缓冲区的音量.关键是我正在使用 DirectSound 并且我有一个主缓冲区和一个辅助缓冲区 - 所有流混合都是手工完成的.在语音聊天中,所有参与者都可以拥有独立的音量级别.我将每个流数据乘以一个值(增益)并将其与一个缓冲区相加.一切正常,但是当我尝试将数据乘以大于 1.0f 的值时 - 我听到一些剪辑或什么.

我试过使用 Audacity 效果压缩器,但这无助于减少奇怪的噪音.

也许我应该以其他方式修改增益?或者只是使用另一种后处理算法?

更新:哇,我刚刚发现了有趣的事情!我在增加音量之前和之后都转储了音频.

这是图片

对不起,质量 - 我认为这就是声音应该出现的方式(我自己画了红线).确实看起来值超出示例数据类型.但我不明白为什么?我的样本缓冲区是 BYTE 但我只能通过短指针访问它.它已签名,但即使 *ptr 约为 15-20,000 时也会发生剪裁.

解决方案

对于每个样本 - 将其转换为某种更大的数据类型 - 如果您有 16 位有符号样本,它们最初适合 SHORT - 从流中提取它,然后转换为本地双精度值,然后相乘,然后是 CLIP,然后转换回 SHORT.

它必须那样工作......

如果需要,我什至可以提供代码示例.

您的图片是您在乘法之前没有扩展到更大类型的确切证据 - 您无法在 SHORT 上捕获"裁剪条件,因为它会自动换行.

short* sampleBuffer;...短样本=*样本缓冲区;double dsample=(double)sample * 增益;如果(dsample>32767.0){dsample=32767.0;}如果(dsample<-32768.0){dsample=-32768.0;}*sampleBuffer=(short)dsample;样本缓冲区++;

还有一个

如果您有多个声音 - 首先将它们全部加倍 - 然后增加每个声音 - 然后添加它们 - 最后一步将它们剪辑.

再一次编辑(+1 激励着我):

如果你有立体声,同样的东西也可以工作,只需计算所有样本 x2,即

shorts 数量 = 样本数量 * 2.>

I want to increase a volume on buffer with voice data. The point is I'm using DirectSound and I have one primary and one secondary buffer - all streams mixing is done by hand. In a voice chat all participants can have independent volume levels. I multiply each stream data by a value (gain) and sum it to one buffer. Everything works fine but when I try to multiply data by a value greater than 1.0f - I hear some clipping or what.

I've tried using Audacity effect compressor but this doesn't help reducing the strange noise.

Probably I should modify gain in some other way? Or just use another post-processing algorithm?

UPDATE: Wow, I've just found out interesting thing! I've dumped audio before increasing volume and right after that.

Here is the pic

Sorry for the quality - I think that's how the sound is supposed to appear (I've drawn red line myself). Really looks like values exceed the sample data type. But I cannot understand WHY? My samplebuffer is BYTE but I access it only via short pointer. It is signed but clipping happens even when *ptr is about 15-20 thousand.

解决方案

For every sample - convert it to some larger data type - if you have 16 bit signed samples, they originally fit in SHORT - extract it from the stream, then cast to local double, then multiply, then CLIP, then cast back to SHORT.

It MUST work that way...

I can even provide code sample if needed.

EDIT:

Your picture is exact evidence that you didn't expand to larger type before multiplication - you can't 'capture' clipping condition on SHORT because it will wrap automatically.

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++;

And one more EDIT:

if you have several voices - first put them all to double - then GAIN each one - then add them - and CLIP them as the last step.

One more EDIT (+1s are inspiring me):

If you have STEREO, same stuff will work also, just count all the samples x2 i.e.

number of shorts = number of samples * 2.

这篇关于修改音频样本缓冲区的音量增益的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆