2017-10-21 134 views
0

我正在使用C#WPF進行實時FFT。如何延遲音頻播放以與FFT同步

我使用NAudio的WaveIn和BufferedWaveProvider來捕捉立體聲混音錄製的任何聲音。我每秒多次對緩衝區進行FFT處理,並使用位圖顯示,以便顯示屏顯示通過揚聲器播放的任何音頻的實時傅里葉變換。

我的問題是,正如所料,顯示的FFT滯後於來自揚聲器的音頻少量(可能是200毫秒)。

有什麼方法可以記錄應該從揚聲器播放的當前音頻,以便我可以在其上執行FFT,然後稍後(稍後200毫秒)播放它,同時靜音原始實時音頻。

最終結果只是爲了有效地消除顯示的FFT的感知延遲。例如,來自YouTube視頻的音頻會在我的程序運行時略微落後於視頻。

下面是從我現在所擁有的相關的方法:

public MainWindow() 
    { 
     sampleSize = (int)Math.Pow(2, 13); 
     BUFFERSIZE = sampleSize * 2; 

     InitializeComponent(); 

     // get the WaveIn class started 
     WaveIn wi = new WaveIn(); 
     wi.DeviceNumber = deviceNo; 
     wi.WaveFormat = new NAudio.Wave.WaveFormat(RATE, WaveIn.GetCapabilities(wi.DeviceNumber).Channels); 

     // create a wave buffer and start the recording 
     wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable); 
     bwp = new BufferedWaveProvider(wi.WaveFormat); 

     bwp.BufferLength = BUFFERSIZE; //each sample is 2 bytes 
     bwp.DiscardOnBufferOverflow = true; 
     wi.StartRecording(); 
    } 

    public void UpdateFFT() 
    { 
     // read the bytes from the stream    
     byte[] buffer = new byte[BUFFERSIZE]; 
     bwp.Read(buffer, 0, BUFFERSIZE); 
     if (buffer[BUFFERSIZE - 2] == 0) return; 

     Int32[] vals = new Int32[sampleSize]; 
     Ys = new double[sampleSize]; 
     for (int i = 0; i < vals.Length; i++) 
     { 
      // bit shift the byte buffer into the right variable format 
      byte hByte = buffer[i * 2 + 1]; 
      byte lByte = buffer[i * 2 + 0]; 
      vals[i] = (short)((hByte << 8) | lByte); 
      Ys[i] = vals[i]; 
     } 

      FFT(Ys); 
    } 

我還是新的音頻處理 - 任何幫助,將不勝感激。

+0

您使用的是WriteableBitmap嗎? – Clemens

+0

@Clemens是的,我已經安裝了WriteableBitmapEx軟件包 –

回答

0

延遲的原因是WaveIn的延遲,默認大約是200ms。你可以減少它,但有輟學的風險。

雖然您可以通過WasapiCapture捕捉系統正在播放的音頻,但無法使用NAudio更改音頻或延遲播放。

+0

感謝Mark的回答。我相信你已經回答了這麼多次,但我怎樣才能減少WaveIn的延遲?我沒有看到WaveIn似乎這樣做的任何屬性。 –

+0

將'BufferMilliseconds'設置爲較低的值 –