ソース オーディオ ファイルのスクリーンショットを見ると、サウンド レベルの変化を検出する簡単な方法の 1 つは、サンプルの数値積分を行って、特定の時間における波の「エネルギー」を見つけることです。
大まかなアルゴリズムは次のようになります。
- サンプルをセクションに分割します
- 各セクションのエネルギーを計算する
- 前のウィンドウと現在のウィンドウの間のエネルギーの比率を取る
- 比率があるしきい値を超えた場合は、突然の大きなノイズがあったと判断します。
疑似コード
samples = load_audio_samples() // Array containing audio samples
WINDOW_SIZE = 1000 // Sample window of 1000 samples (example)
for (i = 0; i < samples.length; i += WINDOW_SIZE):
// Perform a numerical integration of the current window using simple
// addition of current sample to a sum.
for (j = 0; j < WINDOW_SIZE; j++):
energy += samples[i+j]
// Take ratio of energies of last window and current window, and see
// if there is a big difference in the energies. If so, there is a
// sudden loud noise.
if (energy / last_energy > THRESHOLD):
sudden_sound_detected()
last_energy = energy
energy = 0;
これを試していないという免責事項を追加する必要があります。
この方法は、最初にすべてのサンプルを記録しなくても実行できるはずです。ある程度の長さのバッファーがある限り (WINDOW_SIZE
例では)、数値積分を実行して音のセクションのエネルギーを計算できます。ただし、これは、ファイルの長さによっては、処理に遅延が生じることを意味しWINDOW_SIZE
ます。サウンドのセクションの適切な長さを決定することは、もう 1 つの懸念事項です。
セクションに分割する方法
最初のオーディオ ファイルでは、ドアが閉まる音の長さは 0.25 秒であるように見えるため、数値積分に使用されるウィンドウはおそらくその半分、または 10 分の 1 程度になるはずです。無音部分とノイズ部分でウィンドウが重なっていても、無音や突然の音に気付くことができます。
たとえば、統合ウィンドウが 0.5 秒で、最初のウィンドウが 0.25 秒の無音と 0.25 秒のドア閉鎖をカバーし、2 番目のウィンドウが 0.25 秒のドア閉鎖と 0.25 秒の無音をカバーしていた場合、音の 2 つのセクションには同じレベルのノイズがあるため、音の検出はトリガーされません。ウィンドウを短くすると、この問題が多少緩和されると思います。
ただし、ウィンドウが短すぎると、音の立ち上がりが 1 つのウィンドウに収まりきらず、隣接するセクション間のエネルギーの差がほとんどないように見え、音を聞き逃す可能性があります。
WINDOW_SIZE
とTHRESHOLD
はどちらも、検出される音に対して経験的に決定する必要があると思います。
このアルゴリズムがメモリに保持する必要があるサンプル数を決定するためにWINDOW_SIZE
、ドアが閉まる音の 1/10、つまり約 0.025 秒とします。4 kHz のサンプリング レートでは、100 サンプルです。それはメモリ要件のあまり多くないようです。200 バイトの 16 ビット サンプルを使用します。
利点/欠点
この方法の利点は、ソース オーディオが整数として入力された場合に、単純な整数演算で処理を実行できることです。問題は、既に述べたように、統合されるセクションのサイズに応じて、リアルタイム処理に遅延が生じることです。
このアプローチには、私が考えることができる問題がいくつかあります。
- バックグラウンド ノイズが大きすぎると、バックグラウンド ノイズとドアが閉まるエネルギーの差がわかりにくくなり、ドアが閉まったことを検出できない場合があります。
- 拍手などの突然のノイズは、ドアが閉まっていると見なすことができます。
おそらく、フーリエ解析を使用してドアが閉まる周波数特性を分析しようとするなど、他の回答の提案を組み合わせると、より多くの処理が必要になりますが、エラーが発生しにくくなります。
この問題を解決する方法を見つけるには、おそらくいくつかの実験が必要になるでしょう。