From naudio.Wave.WaveIn to Stream ?

2020-08-09 04:56发布

问题:

I copied this code and i don't understand it but i know what it does when it's finished (output -- sourceStream) ...

 NAudio.Wave.WaveIn sourceStream = null;
 NAudio.Wave.DirectSoundOut waveOut = null;
  NAudio.Wave.WaveFileWriter waveWriter = null;

        sourceStream = new NAudio.Wave.WaveIn();
    sourceStream.DeviceNumber = 2;
    sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(16000, NAudio.Wave.WaveIn.GetCapabilities(2).Channels);

    NAudio.Wave.WaveInProvider waveIn = new NAudio.Wave.WaveInProvider(sourceStream);

    waveOut = new NAudio.Wave.DirectSoundOut();
    waveOut.Init(waveIn);
    //sourceStream.DataAvailable.
    sourceStream.StartRecording();
    waveOut.Play();
    sourceStream.StopRecording();

What I know that this code records sound from a selected microphone and it gives an output for it (sourceStream)

So the first thing I need is -- > How can i get a stream out from this code (Like instead of WaveIn a Stream [Convert from WaveIn to Stream]) ?

And can you guys please Explain the code ... I tried the NAudio website for the explanation but i didn't understand --> I'm a beginner for audio and Streams...

回答1:

You need to capture the DataAvailable event provided by WaveIn, something like this

//Initialization of the event handler for event DataAvailable
sourceStream.DataAvailable += new EventHandler<WaveInEventArgs>(sourceStream_DataAvailable); 

And provide the event handler, the data that you need is in the WaveInEventArgs input argument of the event handler. Note that the data type of the audio is short so I would normally do like this,

private void sourceStream_DataAvailable(object sender, WaveInEventArgs e) {
  if (sourceStream == null)
    return;
  try {
    short[] audioData = new short[e.Buffer.Length / 2]; //this is your data! by default is in the short format
    Buffer.BlockCopy(e.Buffer, 0, audioData, 0, e.Buffer.Length);
    float[] audioFloat = Array.ConvertAll(audioData, x => (float)x); //I typically like to convert it to float for graphical purpose
    //Do something with audioData (short) or audioFloat (float)          
  } catch (Exception exc) { //if some happens along the way...
  }
}

However, if you want to convert get it in the byte[] format, then you should simply use e.Buffer directly or copying it to some short of byte[] whichever is more appropriate. As for me copying to byte[] array and then process it somewhere else is often more appropriate because the WaveIn stream is alive.

byte[] bytes = new short[e.Buffer.Length]; //your local byte[]
byteList.AddRange(bytes); //your global var, to be processed by timer or some other methods, I prefer to use List or Queue of byte[] Array

Then to convert your byteList to Stream, you can simply use MemoryStream with input of byte[]

Stream stream = new MemoryStream(byteList.ToArray()); //here is your stream!