2017-01-11 1 views
0

Je souhaite ouvrir un fichier wave et le lire en traçant sa réponse en amplitude et en fréquence sur les graphiques.Tracer un fichier .wav tout en jouant avec nAudio

J'ai une fonction qui prend des tableaux d'octets ou de flottants et fait cela pour moi. Ce que j'essaie de faire est d'échantillonner l'audio de la dernière fois que j'ai échantillonné, passer un tableau de flottants représentant cette heure à la fonction.

J'essaie d'utiliser un ISampleProvider avec sa méthode de lecture pour cela, mais je n'arrive pas à le faire fonctionner. La première lecture fonctionne parfaitement, mais le fil se bloque lors des lectures suivantes (parfois, elle se bloque également lors de la première lecture).

Voici comment je configurer le son, le fichier joue très bien:

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

Ceci est en cours d'exécution sur une minuterie 100ms, il fonctionnera parfaitement pour la première tique, le second se bloque, le verrou reste allumé et tous les autres appels sont sauvegardés jusqu'à ce que tout le programme se bloque.

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

Stack Trace ajoutée (espoir je l'ai fait correctement)

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

Avez-vous une trace de pile/des données d'exception du crash? – SynerCoder

+0

Pouvez-vous poster e.ToString(), que nous pouvons également voir le type d'exception. – SynerCoder

+0

Ah oui je pense que vous m'avez permis de résoudre mon propre problème, je ne m'assurais pas que la longueur de lecture était un multiple du bloc aligner! (pensé que j'étais mais je ne étais pas) e.ToString() était doit être multiple de bloc align ... –

Répondre

0

La question était que je ne vérifiait pas correctement la longueur du tampon, je lui ai demandé. Les tampons doivent toujours être un multiple de block align.

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