4
votes

I am able to capture audio using naudio into file, now i want it on byte[] or Stream in c#.

this.writer = new WaveFileWriter(this.outputFilename, this.waveIn.WaveFormat);

What i tried so far is instead of passing output filename in WaveFileWriter constructor, passed MemoryStream object. With reference to stream object i try to play it using Soundplayer once recording gets over.

private IWaveIn waveIn;
private WaveFileWriter writer;
private string outputFilename;

private Stream memoryStream;

public void onRecord(object inputDevice, string fileName)
{
    if (this.waveIn == null)
    {
            this.outputFilename = fileName;
            this.waveIn = new WasapiLoopbackCapture((MMDevice)inputDevice);

            if(memoryStream == null)
                   memoryStream = new MemoryStream();

            this.writer = new WaveFileWriter(this.memoryStream,this.waveIn.WaveFormat);
            this.waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(this.OnDataAvailable);
            this.waveIn.RecordingStopped += new EventHandler<StoppedEventArgs>(this.OnRecordingStopped);
            this.waveIn.StartRecording();
    }
}

private void OnDataAvailable(object sender, WaveInEventArgs e)
{
    this.writer.Write(e.Buffer, 0, e.BytesRecorded);
}

public void OnRecordingStopped(object sender, StoppedEventArgs e)
{
    if (this.waveIn != null)
    {
            this.waveIn.Dispose();
        this.waveIn = null;
    }

    if (this.writer != null)
    {
        this.writer.Close();
        this.writer = null;
    } 
}

For testing purpose, i created this below code to check whether it able to play the recorded audio.

System.Media.SoundPlayer soundPlayer = new System.Media.SoundPlayer();

memoryStream.Position = 0; 
soundPlayer.Stream = null;
soundPlayer.Stream = memoryStream;
soundPlayer.Play();

But when i try with above manner, i got System.ObjectDisposedException: Cannot access a closed Stream. On the line memoryStream.Position = 0; .I didn't dispose the stream object, Don't know where exactly it gets disposed.

3
Please show the relevant parts of the code you're using at the moment.Jon Skeet
it gets disposed when you dispose the writer. For this situation, I quite often make an "IgnoreDisposeStream" to wrap the MemoryStream with. Also, why are you using NAudio only for record and not playback also?Mark Heath
@MarkHeath Thanks for Info. The code snippet i used for playback is for testing purpose only. Originally i am using naudio for playback in my code, just tried with Soundplayer which i didn't used before.Sivakumar

3 Answers

6
votes

As Mark suggests, i wrapped the memoryStream with IgnoreDisposeStream and it works.

this.writer = new WaveFileWriter(new IgnoreDisposeStream(memoryStream),this.waveIn.WaveFormat);
0
votes

Do not create Memory stream. Use your System.Media.SoundPlayer as Stream.

byte[] buff = new byte[1024];   //or bigger...
System.Media.SoundPlayer soundPlayer = new System.Media.SoundPlayer();
soundPlayer.Stream.Read(buff, 0, (buff.Length - 1));
0
votes

The SoundPlayer class is not great for this since it reads the entire stream before starting playback. It also requires the stream to be in Wave file format, so you'll have to use the WaveFileWriter to write out all your audio data before you can use the stream with the SoundPlayer.

I would recommend that you use NAudio's WaveOutEvent (or similar) to do your audio output. Doing so removes the need for a Stream and allows you to play back the recorded audio in near real-time (it'll have a delay; how much depends on your hardware and on the size of all the buffers involved).