2017-01-11 14 views
0

Я хочу открыть волновой файл и воспроизвести его при построении его амплитудной и частотной характеристики на графиках.Построение файла .wav во время игры с nAudio

У меня есть функция, которая берет массивы байтов или плавает и делает это для меня.

То, что я пытаюсь сделать, это образец звука из последнего, когда я пробовал его, передавая массив поплавков, представляющих это время для функции.

Я пытаюсь использовать ISampleProvider с его методом чтения для этого, но я просто не могу заставить его работать. Первое чтение отлично работает, но затем поток вылетает при последующих чтениях (иногда он также срабатывает при первом чтении).

Это, как я настройка аудио файл играет просто отлично:

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

Это работает на 100мс таймер, он будет работать отлично для первого тика, то второй будет врезаться, блокировка остается включенной, а все остальные вызовы восстанавливаются до тех пор, пока вся программа не сработает.

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() должен быть кратным блоку align ... –

ответ

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()); 
     } 
    }