2017-02-15 212 views
6

我已經成功地使用n音訊順利拿到音頻數據要輸出設備(揚聲器)流:轉換音頻流頻率

private void OnDataAvailable(object sender, WaveInEventArgs e) 
     { 
      var buffer = e.Buffer; 
      var bytesRecorded = e.BytesRecorded; 
      Debug.WriteLine($"Bytes {bytesRecorded}"); 

和樣本輸出:

Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 23040 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 

然後我變換(FFT),這樣,x和y值使用https://stackoverflow.com/a/20414331

var buffer = e.Buffer; 
      var bytesRecorded = e.BytesRecorded; 
      //Debug.WriteLine($"Bytes {bytesRecorded}"); 
      var bufferIncrement = _waveIn.WaveFormat.BlockAlign; 

      for (var index = 0; index < bytesRecorded; index += bufferIncrement) 
      { 
       var sample32 = BitConverter.ToSingle(buffer, index); 
       _sampleAggregator.Add(sample32); 
      } 

隨着一個示例輸出:

x: -9.79634E-05, y: -9.212703E-05 
x: 6.897306E-05, y: 2.489315E-05 
x: 0.0002080683, y: 0.0004317867 
x: -0.0001720883, y: -6.681971E-05 
x: -0.0001245111, y: 0.0002880402 
x: -0.0005751926, y: -0.0002682915 
x: -5.280507E-06, y: 7.297558E-05 
x: -0.0001143928, y: -0.0001156801 
x: 0.0005231025, y: -0.000153206 
x: 0.0001011164, y: 7.681748E-05 
x: 0.000330695, y: 0.0002293986 

不知道這甚至有可能,或者如果我只是誤解是什麼流回來,但我想獲得的音頻流的頻率,以做一些東西與飛利浦色相。上面的x,y值是小到在CIE色彩空間中使用的方式。我做錯了什麼或者我完全誤解了OnDataAvailable中緩衝區中的數據?

謝謝!

編輯:

我基於改進的意見我OnDataAvailable代碼和自動調整程序的教程是如下:

private void OnDataAvailable(object sender, WaveInEventArgs e) 
     { 
      var buffer = e.Buffer; 
      float sample32 = 0; 

      for (var index = buffer.Length > 1024 ? buffer.Length - 1024 : buffer.Length; index < e.BytesRecorded; index += 2) 
      { 
       var sample = (short) ((buffer[index + 1] << 8) | buffer[index + 0]); 
       sample32 = sample/32768f; 
       Debug.WriteLine(sample32); 
       LightsController.SetLights(Convert.ToByte(Math.Abs(sample32) * 255)); 
       _sampleAggregator.Add(sample32); 
      } 
      var floats = BytesToFloats(buffer); 

      if (sample32 != 0.0f) 
      { 
       var pitchDetect = new FftPitchDetector(sample32); 
       var pitch = pitchDetect.DetectPitch(floats, floats.Length); 
       Debug.WriteLine($"Pitch {pitch}"); 
      } 
     } 

希望的是,我只用了最後一組元素來自緩衝區,因爲它似乎沒有清除自己,我只對可用的最新數據集感興趣,以便獲取當前音頻的頻率。然而,當DetectPitch方法被調用時,我還是非常地得到一個索引異常。我哪裏錯了?我希望能夠使用這個頻率來改變色調燈泡的顏色和亮度。

+1

你見過這個帖子:http://stackoverflow.com/questions/15009084/implementing-fftpitchdetector-in-c-sharp? –

+0

@DavidTansey我沒有。將調查並報告。 –

+0

@DavidTansey我修改了我的OnDataAvailable代碼來匹配並傳入「float」和「floats.Length」到pitchDetect.DetectPitch,但我在SmbPitchShift.smbFft(fftBuffer,frames,-1)處得到了一個超出範圍的異常;''如果註釋掉了,在'float real = fftBuffer [bin * 2];'。有任何想法嗎? –

回答

1

使用

fPeak = SamplingRate * BinNumberOfPeak/FFTLength ;

+0

什麼是「BinNumberOfPeak」? 「FFTLength」在哪裏?你的答案沒有提供太多的細節。我想了解NAudio返回的數據以及如何從數據中獲取頻率? –

+0

FFT長度= 4096(= N個計算點數)並且Bin數目是FFT數組0,1,2中的索引。基於單側或雙側頻譜的頻率峯值計算非常棘手。你必須遵循[第4點](http://www.gaussianwaves.com/2014/07/how-to-plot-fft-using-matlab-fft-of-basic-signals-sine-and-cosine-waves /)瞭解真實計算。 – SACn