2017-01-11 8 views
0

波のファイルを開いて再生し、グラフの振幅と周波数の応答をプロットします。nAudioで再生中の.wavファイルをプロットする

私はバイトまたは浮動小数点数の配列をとり、これを私のために行う関数を持っています。

私がしようとしているのは、サンプリングした最後の時間からオーディオをサンプリングすることです。その時間を表す浮動小数点数の配列を関数に渡します。

私はISampleProviderを使ってこのメソッドを読み込もうとしていますが、動作させることができません。最初の読み取りは完全に動作しますが、その後の読み取りでスレッドがクラッシュします(最初の読み取りでもクラッシュすることがあります)。

これは私がオーディオを設定してい、ファイルがうまく再生する方法である:これは100msのタイマーで実行されている

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

、それは最初の目盛りのために完璧に動作しますが、二つ目はクラッシュします、ロックがオンのままで、プログラム全体がクラッシュするまで、他のすべてのコールがバックアップされます。スタックトレースが追加

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

ああ私はあなた自身の問題を解決するために私を有効にしたと思う、私は読んだ長さがブロックアライメントの倍数であることを保証していなかった!私は思っていたが、私はそうではなかったと思った。eToString()はブロックアラインメントの倍数でなければならなかった... –

答えて

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()); 
     } 
    } 
関連する問題