Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write NAudio WaveStream to a Memory Stream?

Tags:

c#

stream

naudio

I have a program that takes in mp3 data in a byte array. It has to convert that mp3 data into wav format and store it in a byte data. I am trying to use NAudio for this purpose. I am using the following code for this purpose.

Stream inputStream = ...;
Stream outputStream = ...;

using (WaveStream waveStream = WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader(inputStream)))
using (WaveFileWriter waveFileWriter = new WaveFileWriter(outputStream, waveStream.WaveFormat))
{
    byte[] bytes = new byte[waveStream.Length];
    waveStream.Read(bytes, 0, waveStream.Length);
    waveFileWriter.WriteData(bytes, 0, bytes.Length);
    waveFileWriter.Flush();
}

When I run the above code, all I receive is 0 in the byte array. But if use WaveFileWriter to write the data directly to a file, the file receives the correct data. Any reasons?

like image 704
gibraltar Avatar asked Jul 16 '12 07:07

gibraltar


2 Answers

Give this a try:

using (WaveStream waveStream = WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader(inputStream))) 
using (WaveFileWriter waveFileWriter = new WaveFileWriter(outputStream, waveStream.WaveFormat)) 
{ 
    byte[] bytes = new byte[waveStream.Length]; 
    waveStream.Position = 0;
    waveStream.Read(bytes, 0, waveStream.Length); 
    waveFileWriter.WriteData(bytes, 0, bytes.Length); 
    waveFileWriter.Flush(); 
} 
like image 180
Chris Gessler Avatar answered Oct 11 '22 03:10

Chris Gessler


If you are writing to a MemoryStream, you need to be aware that WaveFileWriter will dispose that MemoryStream after you dispose the WaveFileWriter.

Here's a workaround using the IgnoreDisposeStream. (Also note that WaveFormatConversionStream.CreatePcmStream is unnecessary - Mp3FileReader already returns PCM from Read). I also prefer to read in smaller chunks that trying to pass through the whole file.

var path = @"mytestFile.mp3";
var mp3ByteArray = File.ReadAllBytes(path);

var outputStream = new MemoryStream();
using (var mp3Stream = new MemoryStream(mp3ByteArray))
using (var reader = new Mp3FileReader(mp3Stream))
using (var waveFileWriter = new WaveFileWriter(new IgnoreDisposeStream(outputStream), 
                                               reader.WaveFormat))
{
    byte[] buffer = new byte[reader.WaveFormat.AverageBytesPerSecond];
    int read;
    while((read = reader.Read(buffer,0, buffer.Length)) > 0)
    {
        waveFileWriter.Write(buffer, 0, read);
    }
}

// outputStream has not yet been disposed so we can get the byte array from it
var wavBytes = outputStream.GetBuffer();

// or we could play it like this
outputStream.Position = 0;
using (var player = new WaveOutEvent())
using (var reader = new WaveFileReader(outputStream))
{
    player.Init(reader);
    player.Play();
    while(player.PlaybackState != PlaybackState.Stopped)
    {
        Thread.Sleep(1000);
    }
}
like image 37
Mark Heath Avatar answered Oct 11 '22 03:10

Mark Heath