-2

生の 16bit 48khz pcm データがあります。人間の聴覚の範囲外にあるすべてのデータを削除する必要があります。

今のところ、すべてのサンプルの合計を計算し、サンプル数で割ってピーク サウンド レベルを計算していますが、誤検知を減らす必要があります。

私は常に大きなピーク レベルを持っており、話し声やその他の音のレベルが少しだけ上がって聞こえるので、何らかのフィルタリングを実装する必要があります。音の加工に全く詳しくないので、作り方が分からないので今のところフィルターは使っていません。私の現在のコードは次のようになります。

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

C++ を使用してこの種のフィルタリングを実装するにはどうすればよいですか?

4

2 に答える 2

1

サウンドレベルが特定のしきい値を超えると、何かをしたい (おそらく録音を開始したい) ように聞こえます。これは「ゲート」と呼ばれることもあります。また、誤検知に問題があるようです。これは、ゲートに適用される「サイドチェーン」で処理されることがあります。

ゲートの一般的な原則は、信号のエンベロープを作成し、エンベロープを監視して、特定のしきい値を超えたときを検出することです。しきい値を超えている場合はゲートが「オン」になり、そうでない場合はゲートが「オフ」になります。何らかの方法でエンベロープを作成する前に信号を処理して、信号/ノイズのさまざまな部分に多かれ少なかれ敏感にする場合、その処理は「サイドチェーン」と呼ばれます。

Q&A Web サイトには情報が多すぎるため、自分で詳細を確認する必要がありますが、最初はこれで十分かもしれません。

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

于 2013-02-21T19:00:20.953 に答える
1

バンドパスフィルターを使用してください。

バンドパス フィルターは、特定の範囲内の周波数を通過させ、その範囲外の周波数を拒否 (減衰) するデバイスです。

これはまさにあなたが探している種類のフィルターのように聞こえます。

Google で簡単に検索したところ、C++ での実装について説明しているこのスレッドが見つかりました。

于 2013-02-21T17:10:42.110 に答える