-2

我有原始的 16 位 48khz pcm 数据。我需要剥离所有超出人类听力范围的数据。

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

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

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

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

4

2 回答 2

1

使用带通滤波器

带通滤波器是一种通过特定范围内的频率并拒绝(衰减)该范围之外的频率的设备。

这听起来正是您正在寻找的那种过滤器。

我进行了一次快速的谷歌搜索,发现了这个讨论 C++ 实现的线程。

于 2013-02-21T17:10:42.110 回答
1

如果声级超过某个阈值,听起来你想做某事(也许开始录音)。这有时被称为“门”。听起来您在误报方面也遇到了麻烦。这有时通过应用于门的“侧链”来处理。

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

您将不得不自己发现细节,因为问答网站的内容太多了,但也许这已经足够开始了:

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。这是一个关于设计音频均衡器的教程:http: //blog.bjornroche.com/2012/08/basic-audio-eqs.html

于 2013-02-21T19:00:20.953 回答