如何使用C ++过滤掉PCM样本中的听外范围数据?

时间:2013-02-21 17:06:53

标签: c++ audio pcm

我有原始16位48khz pcm数据。我需要删除所有超出人类听觉范围的数据。

现在我只是对所有样本求和,然后除以样本计数来计算峰值声级,但我需要减少误报。

我一直有很高的峰值,说话和其他声音,我可以听到增加的水平,所以我需要实现一些过滤。我根本不熟悉声音处理,所以目前我没有使用任何过滤,因为我不明白如何创建它。我目前的代码如下:

for(size_t i = 0; i < buffer.size(); i++)
level += abs(buffer[i]);
level /= buffer.size();

如何使用C ++实现这种过滤?

2 个答案:

答案 0 :(得分:1)

使用band pass filter

  

带通滤波器是一种在a内传递频率的设备   某些范围并拒绝(衰减)该范围之外的频率。

这听起来就像你正在寻找的那种过滤器。

我有一个快速的谷歌搜索,并找到了讨论C ++实现的this线程。

答案 1 :(得分:1)

如果声级高于某个阈值,听起来你想要做某事(可能开始录音)。这有时被称为“门”。听起来你也有误报的麻烦。这有时通过应用于门的“侧链”来处理。

门的一般原理是创建信号的包络,然后监视包络以发现它何时超过某个阈值。如果它高于阈值,你的门是“开”,如果没有,你的门是“关闭”。如果您在以某种方式创建信封之前处理信号,使其对信号/噪声的各个部分或多或少敏感,则该处理被称为“侧链”。

你必须自己发现细节,因为Q&amp; A网站太多了,但这可能只是一个开始:

float[] buffer; //defined elsewhere
float HOLD = .9999 ; //there are precise ways to compute this, but experimentation might work fine
float THRESH = .7 ; //or whatever
float env = 0; //we initialize to 0, but in real code be sure to save this between runs
for(size_t i = 0; i < buffer.size(); i++) {
     // side-chain, if used, goes here
     float b = buffer[i];
     // create envelope:
     float tmp = abs(b); // you could also do buffer[i] * buffer[i]
     env = env * HOLD + tmp * (1-HOLD);
     // threshold detection
     if( env > THRESH ) {
        //gate is "on"
     } else {
        //gate is "off"
     }
}

侧链可能包含像eq这样的过滤器。以下是设计音频eq:http://blog.bjornroche.com/2012/08/basic-audio-eqs.html

的教程