これがまたいびき検出器です。
何かがあったときに信号を検出するのが得意です。壁をはがしているいびきから、録音では聞こえない呼吸まで追跡できます。問題は、信号がいつ検出可能なレベルを下回っており、アプリが「物事を聞いている」だけなのかわからないことです。そして、残念なことに、いびき/呼吸はしばしば不規則であり、単純な自己相関または同様のインターバルタイミングスキームがあまり役に立たないようです。(実際には、場合によっては、呼吸よりもノイズがより規則的である可能性があります。)
それで、信号がないときに理解するために私が見逃しているトリックはありますか?「シグナル」はもともと非常にノイズのようなものであることを考えると、私はここで難しい場所に反対しているようです。
(そしてこれは私が抱えている別の問題に関連している可能性があります:不思議なことに、かなり大きな音量でも信号レベルを正確に(または概算で)測定できません。レベル情報の種類が失われます。再構成するためのいくつかのトリックを探しています。)
基本的なテクニック
(依田用)
オーディオ信号はサンプリングされ(通常、さまざまな理由で8000Hzで)、1024ブロックでFFTされます。(私の実験では、ハミングフィルターとオーバーラップブロックはほとんど影響がないようですが、後で再検討する場合があります)。
FFTは「バンド」(現在は5、ローエンドでより詳細に配置するためにサイズがわずかに歪んでいる)に分割され、各バンドの「スペクトル差」とレベルが合計されます。ピーク制限値の長期平均が「しきい値」として使用され、さらにバイアス調整を使用して、約20%の「しきい値超過」率を維持します。
各「しきい値を超える」値には1の重みが与えられます(しきい値未満には0の重みが与えられます)が、その重みはバンドの見かけの「変動性」(約2Hzで)によって調整され、バンドにより多くの重みを与えますより明白な信号を運びます。
バンドの重みが合計され、後続のブロックの合計された重みが約1秒にわたって合計されて、実行中の「スコア」が生成されます。これは、繰り返し平均しきい値(およびいくつかのヒューリスティック)と比較され、いびきの開始/オフセットを検出します。
更新
突然、アルゴリズムが(信号レベルの問題ごとに)一定レベルの信号を維持する場合、SNRを効果的に測定する方法は、信号がないときにノイズを測定することです。
便宜上、いびきは断続的であり、その間にたくさんの「死んだ空気」が存在します。そして、いびきのエンベロープをすでに検出しています。したがって、エンベロープの外側(いびきの終わりと次のいびきの始まりの間)の外側は、おそらくノイズです。これは(ある程度の正確さ/再現性で)測定できます。(もちろん、中途半端なアルゴリズムを思いつくのに3回の試行が必要でした-現実が理論と一致することは決してありません。)
まだ完全な答えは出ていませんが、進歩しました。
(上記の手法でSNRのかなり良いプロキシが得られますが、実際の信号レベルを推定するのにまだ問題があります。私の「相対レベル」の表示は、かろうじて聞こえる息の場合はスケールから外れ、ウィンドウのガラガラの場合はまあまあです。絶対レベルのプロキシが必要です。)