2017-08-06 6 views
1

J'utilise NAudio et j'essaie d'enregistrer ce qui est lu sur mon pc avec WasapiLoopbackCapture. Le problème que j'ai est que j'ai besoin des données enregistrées comme PCM 16bit 44100khz Mono. Pour que j'ai construit ceci:Enregistrement et conversion de NAudio Wasapi

using System; 
using System.Diagnostics; 

using NAudio.Wave; 
using NAudio.CoreAudioApi; 

namespace soundtest 
{ 
    class Program { 

     static void Main(string[] args) { 
      try { 
       var deviceToRecord = (new MMDeviceEnumerator().EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active))[0]; 

       var recorder = new CustomWasapiLoopbackCapture(deviceToRecord, false, 1000/5); 
       recorder.ShareMode = AudioClientShareMode.Shared; 
       recorder.DataAvailable += recorderDataAvailable; 

       var inprov = new WaveInProvider(recorder); 
       var fto16prov = new WaveFloatTo16Provider(inprov); 
       var stomprov = new StereoToMonoProvider16(fto16prov); 

       Console.WriteLine("Press something to stop recording."); 
       recorder.StartRecording(); 
       Console.ReadKey(); 
       recorder.StopRecording(); 

      } catch (Exception e) { 
       Console.WriteLine("!!! EXCEPTION !!!" + 
        "\nMessage:\n " + e.Message + 
        "\nSource:\n " + e.Source + 
        "\nStack:\n" + e.StackTrace); 
      } 

      Console.WriteLine("Press something to close."); 
      Console.ReadKey(); 
     } 

     static void recorderDataAvailable(object sender, WaveInEventArgs args) { 
      // how do I access PCM 16bit here? 
      // It's not args.Buffer, or am I wrong? 
      // additional calculation is done here with the PCM data 
     } 
    } 


    class CustomWasapiLoopbackCapture : WasapiCapture 
    { 
     public CustomWasapiLoopbackCapture() 
      : this(GetDefaultLoopbackCaptureDevice()){ } 
     public CustomWasapiLoopbackCapture(MMDevice captureDevice) 
      : this(captureDevice, false){ } 
     public CustomWasapiLoopbackCapture(MMDevice captureDevice, bool useEventSync) 
      : this(captureDevice, useEventSync, 100){ } 
     public CustomWasapiLoopbackCapture(MMDevice captureDevice, bool useEventSync, int audioBufferMillisecondsLength) 
      : base(captureDevice, useEventSync, audioBufferMillisecondsLength){ } 

     public static MMDevice GetDefaultLoopbackCaptureDevice() { 
      MMDeviceEnumerator devices = new MMDeviceEnumerator(); 
      return devices.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); 
     } 

     public override WaveFormat WaveFormat 
     { 
      get { return base.WaveFormat; } 
      set { throw new InvalidOperationException("WaveFormat cannot be set for WASAPI Loopback Capture"); } 
     } 

     protected override AudioClientStreamFlags GetAudioClientStreamFlags() { 
      return AudioClientStreamFlags.Loopback; 
     } 
    } 
} 

Comment puis-je accéder à l'enregistrement converti? Je pensais qu'en ajoutant ces fournisseurs, je pourrais obtenir les données pour d'autres calculs. Mon hypothèse selon laquelle args.Buffer ne fournit pas les données PCM 16bit 44100 kHz attendues de PCM provient de résultats irréalistes du traitement supplémentaire que je fais dans la méthode recorderDataAvailable. J'ai testé cela avec un simple WaveInEvent sur une autre entrée de ma table de mixage avec laquelle j'ai rebouclé le son en lecture.

Répondre

1

WASAPI enregistre toujours l'audio en tant qu'échantillons flottants IEEE. Donc, dans le tampon enregistré vous obtenez dans le rappel, tous les 4 octets est un float. Un moyen simple d'accéder à des échantillons individuels est avec BitConverter.ToSingle. Cela vous donnera une valeur dans la plage +/- 1.0. Multipliez donc par 32767, puis convertissez-le en Int16 pour le convertir en une valeur d'échantillon de 16 bits.

+0

Pouvez-vous élaborer? J'essaye de copier le tampon enregistré à un System.IO.Stream afin que je puisse le passer à un SpeechRecognitionEngine.SetInputToAudioStream(). J'ai essayé de rééchantillonner AcmStream, mais j'ai l'impression que ce n'est peut-être même pas nécessaire. Le SRE n'accepte que des échantillons de 8 ou 16 bits. Essayant fondamentalement de faire [ceci] (https://stackoverflow.com/questions/1682902/streaming-input-to-system-speech-recognition-speechrecognitionengine) mais avec un WasapiLoopbackCapture(). – javon27