2017-03-21 3 views
0

私はVAD(Voice Activity Detection)アルゴリズムをC#で実装しようとしていますが、これは適切なライブラリが見つからなかったためです。 ImはWAVEファイルで作業していないが、メモリはちょうどこのようにストリームのみで:最初のステップは、10msのフレームに入力信号を分割する場所メモリストリームからのフレームへのオーディオ信号の分割。 (C#)

 NAudio.Wave.WaveFileWriter waveWriter; 

     Stream s1 = new MemoryStream(); 
     WaveInEvent waveSource = new WaveInEvent(); 
     waveSource.WaveFormat = new NAudio.Wave.WaveFormat(16000, 16, 1); 

     waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable); 
     waveWriter = new NAudio.Wave.WaveFileWriter(s1, waveSource.WaveFormat); 

     waveSource.StartRecording(); 
     Console.ReadLine(); 
     waveSource.StopRecording(); 
     s1.Position = 0; 
     var bytes = streamToArray(s1); 

イムつもりはこのtutorialに従ってください。私はファイルの入力からこれを行う方法を知っていますが、バイトの配列で同様のアクションを実行するにはどうすればよいですか? あなたの答えをありがとう!

更新:

short[] sdata = new short[(int)Math.Ceiling(bytes.Length/2.0)]; 
Buffer.BlockCopy(bytes, 0, sdata, 0, bytes.Length); 
for (var i = 0; i < bytes.Length; i += 2) 
      { 
       var b1 = (short)bytes[i]; 
       var b2 = (short)bytes[i + 1]; 
       sListData.Add((short)(b1 | b2 << 8)); 
      } 

私はビッグエンディアンを用いた方法で出力配列を比較した:

Iは、これらの方法を試験しました彼らはすべて平等です。 したがって、BlockCopyはジョブを実行しますが、BEが適切な場合のみです。

答えて

0

オーディオストリームパラメータを16kbp、サンプルあたり16ビット、シングルチャンネルと仮定すると、16000サンプルが10msより1秒の場合は16000/100 = 160サンプル。今16bitは2バイトで160 * 2 = 320バイトになります。 したがって、各320バイトは10msです。 Array.Copy-https://msdn.microsoft.com/en-us/library/z50k9bft(v=vs.110).aspxを使用して、チャンクデータを別の配列にコピーすることができます。以下のコードの

ちょうどビット:

するvar int8Array =新しいバイト[] {0x04の、0x02の、0x08に、0xA1の}。

var int16ArrayLE = new List<short>(); 
var int16ArrayBE = new List<short>(); 

for(var i=0;i<int8Array.Length;i+=2) 
{ 
    var b1 = (short)int8Array[i]; 
    var b2 = (short)int8Array[i+1]; 
    int16ArrayLE.Add((short)((b1 << 8) + b2)); 
    int16ArrayBE.Add((short)(b1 + (b2 << 8))); 
} 

in。short型は16ビット整数で、バイトは8ビット整数です。コードは読みやすくするために少し明白です。リトルエンディアンとビッグエンディアンの2つのコンバージョンを示しました。前者の場合、最初のバイトは後者の2番目のバイトでより重要です。バイト順序はストリーム形式に依存し、いずれかになります。

+0

ありがとうございます。特定のフレームにFFTを適用するには、そのサイズは2のべき乗でなければならないと読んでいます。だから私は320バイトを256に変更することができますか? – Singularum

+0

あなたは間違っています。あなたの場合は、160サンプルのフレームがそれぞれ2バイトです。だから、最初に、各奇数iについてsth like(x [i] +((int)x [i + 1])<< 8)を使って各1バイトサンプルを2バイト値に変換する必要があります。 2つ目のことは、256サンプルで作業する必要がある場合は、それらのサンプルだけで作業することです。あなたのケースでは、各サンプルは0,0625msを表します。したがって、256サンプルは厳密に16msです。リンクした論文は読み込まれませんでしたが、これはアルゴリズムには十分ですか? –

+0

私はあなたの最初の声明が何を意味するのかをはっきりと理解していませんでした。 単純に、出力配列のサイズを2の基数のフレームに分割する必要があると言いました。たとえば256です。 バイト[8500]を複数のバイト[256]に分割する正しい方法かどうかを知りたかっただけです。ベース配列が2で割り切れない場合は、残りの部分を無視してください。 あなたの時間に感謝します。心から感謝する。 – Singularum

関連する問題