オーディオエンベロープの開始と停止の場所を検出する最も簡単な方法


43

以下は、話している人の録音を表す信号です。これに基づいて一連の小さなオーディオ信号を作成したいと思います。「重要な」サウンドの開始と終了を検出し、それらをマーカーに使用してオーディオの新しいスニペットを作成するという考え方です。言い換えれば、音声の「チャンク」がいつ開始または停止したかを示すインジケータとして無音を使用し、これに基づいて新しい音声バッファを作成したいと思います。

たとえば、ある人が自分自身を記録する場合

Hi [some silence] My name is Bob [some silence] How are you?

次に、これから3つのオーディオクリップを作成したいと思います。言うHiもの、言うMy name is Bobもの、言うものHow are you?

私の最初のアイデアは、低振幅の領域がある場所を常にチェックするオーディオバッファーを実行することです。たぶん、最初の10個のサンプルを取得して値を平均し、結果が低い場合は無音としてラベル付けすることでこれを行うことができます。次の10個のサンプルをチェックして、バッファを進めていきます。この方法で増分することで、エンベロープの開始位置と停止位置を検出できました。

誰でも良い、しかしこれを行う簡単な方法についてアドバイスがあれば、それは素晴らしいことです。私の目的のために、解決策非常に初歩的なことできます。

私はDSPのプロではありませんが、いくつかの基本的な概念を理解しています。また、プログラムでこれを行うので、アルゴリズムとデジタルサンプルについて話すのが最善です。

すべての助けてくれてありがとう!

ここに画像の説明を入力してください


編集1

これまでのところ素晴らしい反応です!ライブオーディオではないことを明確にしたかったので、ライブラリを使用するソリューションは実際には選択肢ではないため、CまたはObjective-Cでアルゴリズムを自分で記述します。


1
沈黙の期間をブレークポイントとして使用して、分割しようとしているようです。電力しきい値を使用して「無音」を判断し、それが中断を構成するのに十分な長さであるかどうかを判断するためのしきい値時間があるのはなぜですか。
ジム・クレイ

@JimClayはい、それはまさに私がやろうとしていることです。電力のしきい値設定について聞いたことがありませんが、使用できるように思えます。複雑ですか?少し拡張していただけますか?
エリックブロット

@EricBrottoおそらく、あなたのライブラリにどのような機能があるかについて少し教えてください。それにより、実際の方法論をより良くマッサージできます。
スペイシー

無音検出のためのこのアプローチはより良いですか?0.05 x = wavread( 's1.wav')以外のしきい値レベルはどうあるべきですか?i = 1; while abs(x(i))<0.05%無音検出i = i + 1; end x(1:i)= []; x(6000:10000)= 0;
zeee

回答:


26

これは、音声検出の古典的な問題です。最初にすることは、Googleにコンセプトを与えることです。これはデジタル通信で広く使用されており、このテーマに関して多くの研究が行われており、そこには良い論文があります。

一般に、音声検出のより複雑な方法に対処する必要があるバックグラウンドノイズが多いほど必要です。静かな部屋で撮影した録音を使用している場合は、非常に簡単に行うことができます(後ほど)。誰かが話している間にあらゆる種類のノイズがある場合(トラックが通り過ぎる、犬がbarえる、プレートが破壊される、エイリアンが攻撃する)、もっと賢いものを使用する必要があります。

接続した波形を見ると、ノイズは最小限に抑えられているため、次のことをお勧めします。

  1. 信号エンベロープの抽出
  2. 適切なしきい値を選択する
  3. エンベロープの大きさがしきい値を超える場所を検出する

これはどういう意味ですか?信号の包絡線は、その周波数成分がどのように振動させるかとは無関係に、時間の大きさを表す曲線です(下の画像を参照)。

ここに画像の説明を入力してください

{1,45,6,2,43,2}{1,45,6,2,43,2} 実験的に見つけることができ、サンプリングレートなどのいくつかの事項に依存する可能性があります。

画像から、ノイズがあまりないこと、信号エンベロープが常に特定のしきい値(ラウドネスレベル)を超えていることがわかり、これらの領域を音声検出領域と見なすことができます。


3
実際に、これをgood'ol winampのプラグインの1つとして実装しました。あなたが説明していることは良いですが、十分ではありません。通常、有声音(母音)と無声音(子音)があります。有声音のみが存在する場合は、説明しているものが機能しますが、無声音は非常に低エネルギーであり、一般的なノイズとはまったく区別できません。また、スタジオでもノイズのない状態は非常にまれです。
ディパンメタ

Pythonでこれを達成する方法は?
kRazzy R

26

本当にやりたいことは、基本的に音声アクティビティ検出または音声検出と呼ばれます。

基本的に、純粋な音声信号(音楽を含まない)には3つの部分があります。

  1. 有声音-基本的に母音が原因
  2. 無声音-子音が含まれています。

人間の音の特徴は、有声音で多くのエネルギーが使用される一方で、実際の情報が子音に含まれていることです。また、無声音がより高い周波数であるのに対して、有声音は通常より低い周波数です。[正確には、すべての有声音は、その人のピッチである特定の人に対してほぼ一定の周波数で共鳴します]。

さて、どのシステムにもノイズがあります。有声音は通常、非常に強力であるため、識別できます。より低い周波数のフィルタリングを適用すると、有声音の十分な大きさを収集できますが、無声音(すべての豊富な情報を含む)は失われます。

それを解決する方法の質問に来る:

秘Theは、無声音がまだ共鳴源から来るという事実にあります。特定の周波数で本質的に制限されます。ここで、ノイズはかなり均一です。したがって、3つすべてを区別する簡単な方法は「ローカルパワー」であり、または同等ではあるが、ウィンドウ化された自己相関を取ることです。

一度に100個のサンプルを取得し、自己相関する場合、ノイズのみが含まれている場合、結果はほとんどゼロになります(これはホワイトノイズの特性です)。音声信号に関しては、信号の大きさはまだ良い構造を持っています。これは過去に私のために働いてきました。

ほとんどすべての携帯電話通信が音声以外の部分を検出し、エンコードから削除するため、VADは活発な研究分野です。しかし、もし彼らが非音声のスピーチを削除すると、電話は役に立たなくなります。

G.729標準は、ラインスペクトル周波数、フルバンドエネルギー、ローバンドエネルギー(<1 kHz)、ゼロクロスレートなどの機能に基づいてVADを計算します。

GSM標準は次のように機能します。オプション1は9つの帯域でSNRを計算し、これらの値にしきい値を適用します。オプション2は、さまざまなパラメーターを計算します:チャネルパワー、音声メトリック、およびノイズパワー。次に、推定SNRに応じて変化するしきい値を使用して、音声メトリックのしきい値を設定します。(ウィキペディアから)

より高度なテクニックについては、この主題に関するいくつかの参考文献をリストしています。

  1. 最も参照されているリファレンス:Jongseo Sohn; ナムスーキム; ウォンヨン・ソン; 「統計モデルベースの音声アクティビティ検出」Signal Processing Letters、IEEE、1999年1月、巻:6号:1 pp:1-3

  2. 最も関連性の高いもの:Mark MarzinzikおよびBirger Kollmeier「パワーエンベロープダイナミクスの追跡によるノイズスペクトル推定のための音声ポーズ検出」IEEE TRANSACTIONS ON SPEECH AND AUDIO PROCESSING、VOL。10、NO。2、2002年2月pp.109

  3. ラミレス、J .; JMゴリズ、JCセグラ(2007年)。「音声アクティビティの検出。基礎と音声認識システムの堅牢性」。M. GrimmとK. Kroschelで。堅牢な音声認識と理解。1〜22ページ。ISBN 978-3-902613-08-0。

  4. 入門:ジョナサン・コラ、キャロル・エスパイ=ウィルソン、タルン・プルティ「音声アクティビティ検出」


Pythonでこれを達成する方法は?
kRazzy R

9

私は彼のアプローチでジム・クレイを完全に2番目にしたいと思いますが、エンベロープを使用してフレーバーをわずかに変えます:

音声は主に1-2kHz付近で発生することがわかっています。データのサンプリングは44kHzになる可能性があります(これは録音デバイスによって異なります)。したがって、最初に行うことは、10ポ​​イントにわたるリアルタイムでの2乗信号の移動平均です。これにより、信号パワーのエンベロープが得られます。それは検出の遅延を引き起こすので、これを低く保ちたいです。

次に、システムにキャリブレーションフェーズを追加します。ユーザーに沈黙させ、ボタンを押し、バックグラウンドノイズを10秒間記録するように依頼します。エンベロープの振幅の平均または中央値を取得し、2を掛けて安全性を確保します。これにより、ジムが自動的に話しているしきい値が得られます。

リアルタイム記録ではない場合、0相移動平均を使用して、遅延による不快感を軽減すると便利です。そのまま機能するかどうかを教えてください。


9

エリック、

本当に早くて汚いものを求めている場合、最初に取得しなければならないのはエンベロープです。これを(MATLABで)単純に行うには:

 envelope = abs(hilbert(yourSignal));

その時点で、私は単にしきい値を設定し、特定のしきい値を超えている場合は「音声が存在します」。

これは非常に簡単な解決策ですが、うまくいくかもしれません。


1
+1。おそらく、このコード行の背後にあるメソッドについて詳しく説明できますか?OPは、ヒルベルト変換によるエンベロープ抽出に慣れていないはずです。
フォノン

@Mohammadありがとう!しかし、私の編集1を参照してください。私は間違いなく迅速かつ汚いが、自分でアルゴリズムを行う必要もあります:)
エリックブロット

@EricBrottoああ、まあ、ヒルベルト変換を実装する方法を教えてくれますが、C / Obj-CライブラリでFFTを実行する機能があると思いますか?そうでなければ、問題になるだろう... :
スペイシー

Pythonでこれを達成する方法は?
kRazzy R

Sir / Ma'am氏は、このhilbertをPythonでどのように実装するかについてのリソースを教えていただけますか?
kRazzy R

6

複雑な信号ではなく、実際の信号を扱っていると思います。そうでない場合はお知らせください。答えを修正できます。

電力は、信号の2乗として定義されます(つまり、信号サンプルに乗算されます)。パワーをあるしきい値と比較して、音声が存在するかどうかを判断できます。経験的に適切なしきい値を見つけるには、おそらく録音でいくつかの測定を行う必要があります。

録音が「クリーン」(つまり、ノイズがそれほど多くない)である場合、瞬間パワー(つまり、単一のサンプル)をしきい値と比較することで、可能な限り単純にすることをお勧めします。つまり、必要ない場合は2乗する必要はありません。絶対値が必要なだけで、事前に計算できる電力しきい値の平方根と比較するだけです。スピーチを検出したら、それをつかみ、その前にある程度の録音を行い、すべてのスピーチを確実に取得します(1/10秒か?)。しきい値を超えるサンプルがない期間が長くなるまで続けます。繰り返しますが、期間の長さは経験的に決定する必要があります。

すすぎ、繰り返します。


4

Javaでアクティビティ検出クラスを作成しました。これは、私のオープンソースのJava DSPコレクションの一部です。テストプログラムWavSplitter.javaを使用して、WAVファイルを入力としてチェックアウトできます。


クマの心にOPは、特に彼はC.でアルゴリズム自分自身を書き込む必要があると言う
サム・マローニー

これは、CにJavaからそのようなアルゴリズムを変換することは非常に簡単です
クリスチャン・ドールHeureuse

サー、パイソンでこれを達成する方法は?
kRazzy R
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.