2017-01-11 68 views
0

我想打開一個波形文件並在繪製圖表上的幅度和頻率響應時進行回放。在播放nAudio時繪製.wav文件

我有一個函數,需要字節或浮點數組,併爲我做這件事。

我想要做的是採樣音頻從我上次採樣它傳遞一個浮點數組表示該函數的時間。

我想使用ISampleProvider與它的讀取方法,但我似乎無法得到它的工作。第一次讀取完美,但隨後的線程在後續讀取時崩潰(偶爾會在第一次讀取時崩潰)。

這是我如何設置的音頻文件播放就好了:

   _waveOut = new WaveOutEvent(); 
       _waveReader = new WaveFileReader(_cncFilePath.Substring(0, _cncFilePath.Length - 4) + "wav"); 
       _waveOutSampleProvider = new SampleChannel(_waveReader, true); 
       _waveOut.Init(_waveOutSampleProvider); 
       _waveOut.Play(); 

這是100ms的定時器運行,它會很好地工作在第一跳,第二個會崩潰,鎖保持打開狀態,所有其他呼叫都會備份,直到整個程序崩潰。

private void WavOutChartTimeInterrupt(object waveReader) 
    { 
     lock (AudioLock) //todo add skipto code, use audio lock to do it. 
     { 
      try 
      { 
       var curPos = _waveOut.GetPositionTimeSpan(); //get currentPos 
       if (curPos <= AudioCurrentPosition) 
       { 
        AudioCurrentPosition = curPos; 
        return; 
       } 
       var bufferLength = (curPos - AudioCurrentPosition); 
       var samplesSec = _waveOutSampleProvider.WaveFormat.SampleRate; 
       var channels = _waveOut.OutputWaveFormat.Channels; 
       var length = (int) (bufferLength.TotalSeconds * samplesSec * channels) % (samplesSec * channels); 
       var wavOutBuffer = new float[length]; 
       _waveOutSampleProvider.Read(wavOutBuffer, 0, length); 

       AudioCurrentPosition = curPos; //update for vCNC with where we are 
      } 
      catch (Exception e) 
      { 
       string WTF = e.StackTrace; 

       throw new ArgumentException(@"Wave out buffer crashed" + e.StackTrace.ToString()); 
      } 
     } 

堆棧跟蹤添加(希望我正確地做了它)

at NAudio.Wave.WaveFileReader.Read(Byte[] array, Int32 offset, Int32 count)\r\n  
at NAudio.Wave.SampleProviders.Pcm16BitToSampleProvider.Read(Single[] buffer, Int32 offset, Int32 count)\r\n  
at NAudio.Wave.SampleProviders.MeteringSampleProvider.Read(Single[] buffer, Int32 offset, Int32 count)\r\n 
at NAudio.Wave.SampleProviders.VolumeSampleProvider.Read(Single[] buffer, Int32 offset, Int32 sampleCount)\r\n 
at RecordCNC.Form1.WavOutChartTimeInterrupt(Object waveReader) in C:\\Cloud\\ITRI\\Visual Studio\\RecordCNC\\RecordCNC\\Form1.cs:line 715 

Haydan

+0

您是否有崩潰時的堆棧跟蹤/異常數據? – SynerCoder

+0

你可以發佈e.ToString(),比我們還可以看到異常類型。 – SynerCoder

+0

啊是的,我認爲你已經使我能夠解決我自己的問題,我不確保讀取長度是塊對齊的倍數! (以爲我是,但我沒有)e.ToString()必須是塊對齊的多個... –

回答

0

的問題是,我沒有正確檢查我請求緩衝區的長度。緩衝區總是必須是塊對齊的倍數。

private void WavOutChartTimeInterrupt(object waveReader) 
{ 
    lock (AudioLock) //todo add skipto code, use audio lock to do it. 
    { 
     try 
     { 
      var curPos = _waveOut.GetPositionTimeSpan(); //get currentPos 
      if (curPos <= AudioCurrentPosition) 
      { 
       AudioCurrentPosition = curPos; 
       return; 
      } 
      var bufferLength = (curPos - AudioCurrentPosition); 
      var samplesSec = _waveOutSampleProvider.WaveFormat.SampleRate; 
      var channels = _waveOut.OutputWaveFormat.Channels; 
      var length = (int) (bufferLength.TotalSeconds * samplesSec * channels) % (samplesSec * channels); 
      length -= length% (blockAlign/channels); //<- THIS FIXED IT 
      var wavOutBuffer = new float[length]; 
      _waveOutSampleProvider.Read(wavOutBuffer, 0, length); 

      AudioCurrentPosition = curPos; //update for vCNC with where we are 
     } 
     catch (Exception e) 
     { 
      string WTF = e.StackTrace; 

      throw new ArgumentException(@"Wave out buffer crashed" + e.StackTrace.ToString()); 
     } 
    }