2017-06-02 21 views
0

低周波数、中周波数、高周波数を.wavファイルから分離したいと考えています。 私は時間領域から周波数領域にデータを変換するためにFFTを使用しています。ファイルを読み取り、高速フーリエNAudioの助けを借りて変換を適用するためのオーディオファイル(.wav)から周波数を分離する方法

コードは、今私は、周波数領域のデータを持って、私はXにY軸と周波数に振幅とZedGraph上にプロットされている

OpenFileDialog file = new OpenFileDialog(); 
     file.ShowDialog(); 
     WaveFileReader reader = new WaveFileReader(file.FileName); 
     int samepleRate = reader.WaveFormat.SampleRate; 
     double ts = 1.0/samepleRate; 
     int _fftLength = 4096; 
     double time = reader.TotalTime.TotalSeconds; 
     int channels = reader.WaveFormat.Channels; 
     int _m = (int)Math.Log(_fftLength, 2.0); 
     float fileSize = (float)reader.Length/1048576; 
     if (fileSize < 2) 
      window = 8; 
     else if (fileSize > 2 && fileSize < 4) 
      window = 16; 
     else if (fileSize > 4 && fileSize < 8) 
      window = 32; 
     else if (fileSize > 8 && fileSize < 12) 
      window = 128; 
     else if (fileSize > 12 && fileSize < 20) 
      window = 256; 
     else if (fileSize > 20 && fileSize < 30) 
      window = 512; 
     else 
      window = 2048; 


     byte[] readBuffer = new byte[reader.Length]; 

     reader.Read(readBuffer,0,readBuffer.Length); 
     float[] data = ConvertByteToFloat(readBuffer,readBuffer.Length);    

     Complex[] fftBuffer= new Complex[_fftLength]; 
     int fftPos = 0; 
     for (int i = 0; i < _fftLength; i++) 
     { 
      fftBuffer[fftPos].X = (float)(data[i] * NAudio.Dsp.FastFourierTransform.HammingWindow(i,_fftLength)); 
      fftBuffer[fftPos].Y = 0; 
      fftPos++; 
     } 
     NAudio.Dsp.FastFourierTransform.FFT(true, _m, fftBuffer); 

private float[] ConvertByteToFloat(byte[] array, int length) 
    { 
     int samplesNeeded = length/4; 
     float[] floatArr = new float[samplesNeeded]; 

     for (int i = 0; i < samplesNeeded; i++) 
     { 
      floatArr[i] = (float)BitConverter.ToInt32(array, i * 4); 
     } 

     return floatArr; 
    } 

//ZedGraph code 
     GraphPane myPane = zedGraphControl1.GraphPane; 
     myPane.Title.Text = "Frequency domain output"; 
     PointPairList list1 = new PointPairList(); 
     PointPairList list2 = new PointPairList(); 
     for (int i = 0; i < fftBuffer.Length; i++) 
     { 
      list1.Add(i, fftBuffer[i].Y); 
     } 
     list2.Add(0, 0); 
     //list2.Add(time, 0);uncomment this and remove below to plot time domain graph 
     var maxIndex = -1; 
     var maxValue = 0f; 
     for (var j = 0; j < _fftLength/2; j++) 
     { 
      var value = fftBuffer[j].X * fftBuffer[j].X 
       + fftBuffer[j].Y * fftBuffer[j].Y; 

      if (value > maxValue) 
      { 
       maxIndex = j; 
       maxValue = value; 
      } 
      var freq = maxIndex == -1 ? 0 
      : (ushort)Math.Round((_fftLength - maxIndex)/(_fftLength * ts)); 
      list2.Add(freq, 0); 
     } 
     if (myCurve1 != null && myCurve2 != null) 
     { 
      myCurve1.Clear(); 
      myCurve2.Clear(); 
     } 

     myCurve1 = myPane.AddCurve(null, list1, Color.Blue, SymbolType.None); 
     myCurve1.IsX2Axis = true; 
     myCurve2 = myPane.AddCurve(null, list2, Color.Black, SymbolType.None); 
     myPane.XAxis.Scale.MaxAuto = true; 
     myPane.XAxis.Scale.MinAuto = true; 
     myPane.YAxis.Title.Text = "Amplitude"; 
     myPane.XAxis.Title.Text = "Frequency"; 
     zedGraphControl1.AxisChange(); 
     zedGraphControl1.Invalidate(); 

のようなものです-軸。 FFT output on ZedGraph

今、私は私と一緒にFFTなどの複雑なデータを持っていますが、どのように与えられたデータから、リストされている周波数の下に分離し、どのように特定の周波数のファイルを生成したり、プレイします。

  1. 低 - 500Hzの
  2. 20Hzから
  3. ミッド - 500Hzの4kHzの
  4. ハイ4kHzのに20KHzの

に任意の助言や指導をいただければ幸いです..!

答えて

0

オーディオストリームをフィルタリングしたいだけなら、計算コストの高い方法を検討しています。 FFTはスペクトルシグネチャを識別するのに最適です。しかし、あなたが時間を追って時間を追っていくことを望むなら、それは数多くの(そしてあなたが聞いているものが気に入らない可能性が高い)数値です。現在指定されているパスを保持している場合は、周波数ドメインで何らかの形式のマスキングを行い、その後に変換する必要があります。時間(実際の製品)に戻って変換するときは、「ダーティ」と発音します(実際のマージには何らかの形の仮想を実装する必要があります)。あなたのコードでは、あなたは振幅を二乗してリアルタイム系列に戻します(注:これは整流された信号を与えます)。

特定の帯域を分離する場合は、FIR帯域通過フィルタの何らかの形式で開始します。開発中の結果を聞きたい場合は、Android AudioTrackクラスの使用例をご覧ください。

+0

これらの周波数を分離してミキサーアプリケーションで使用する目的(DJミキシングを行うため)。私はいくつかのローパスとハイパスフィルタ関数を試してきましたが、このフィルタ関数が有効であるかどうかの後にデータが得られるかどうかは確かではありません。また、フィルタリングされたデータから.wavファイルを作成しようとしましたが、すべてのオーディオプレーヤーと。 .wavを保存して音声を再生することは私の目標ではありませんが、データが有効かどうかを確認する必要があります。私はちょうど低=>低、中=>中と高=高と2つの曲をミックスすることができるようにプレイ位置(基本的に時間領域)でデータ配列をフィルタリングする必要があります。 – Nitin

関連する問題