Playing ALaw memorystream

Dec 20, 2011 at 4:45 PM


I'm stuck with this simple task:

- I have a memorystream containing raw data (ALaw compressed)

- I want to play this memorystream as it is (I don't want to write it to the disk)

How ho I do that?

Dec 21, 2011 at 10:35 AM

1st of all, sorry for the double post, it was not done on purpose.

I managed to save a wave file to disk and this is cool, but it's not my scope.

The raw data comes from MS TTS (Text to speech) and it is working as expected. In order to test the code, please add a reference to System.Speech

and add 

using System.Speech;

using System.Speech.AudioFormat;

using System.Speech.Synthesis;

            MemoryStream memStream = new MemoryStream();

            SpeechSynthesizer speaker = new SpeechSynthesizer();
            speaker.Rate = 0;
            speaker.Volume = 100;
            speaker.SelectVoice("Microsoft Sam");

            SpeechAudioFormatInfo ALawFormat = new SpeechAudioFormatInfo(EncodingFormat.ALaw, 8000, 8, 1, 1, 2, null);

            speaker.SetOutputToAudioStream(memStream, ALawFormat);

            speaker.Speak("Hello world!");

            ByteArrayToFile(@"C:\temp\MyRawFile.raw", memStream.ToArray());

            WaveFormat format = WaveFormat.CreateALawFormat(8000, 1);

            FileStream fs = new FileStream(@"C:\temp\MyRawFile.raw", FileMode.Open);

            using (RawSourceWaveStream reader = new RawSourceWaveStream(fs, format))
                WaveFileWriter.CreateWaveFile(@"C:\temp\MyRawFile.wav", reader);



when speaker.speak() is executed, memStream contains my audio file, raw data, ALaw encoded. If I save the file (using ByteArrayToFile) and then use Audacity, the file plays perfectly well (Microsoft Sam voice is crap, but we overlook it now).

The example provided here is to be clear enough on what kind of audio I'm working with.

So, my question is: what should I do in order to play that memStream with NAudio?

This is a big deal to me, since I can't open the VS solution (I don't have vs 2010, am stuck to 2008) and can't find any kind of documentation around this simple task.

Can anyone please help me? I'm a bit frustrated :(

Dec 21, 2011 at 10:41 AM

Pass your RawSourceStream into WaveFormatConversionStream.CreatePcmStream(). The output from that can be played with WaveOut.


Dec 21, 2011 at 12:07 PM

Thanks Mark!

It works!

Have no idea if this is completely correct, but it works and I'm happy with it.

memStream.Position = 0;
using (RawSourceWaveStream NewReader = new RawSourceWaveStream(memStream, format))
	WaveStream ws = WaveFormatConversionStream.CreatePcmStream(NewReader);
	WaveOut wo = new WaveOut();

Dec 21, 2011 at 12:36 PM

you're on the right lines, but your WaveOut object is in danger of getting garbage collected before playback has finished. wo.Play just starts playback, so you are closing your input stream before it has finished playing it.

Dec 23, 2011 at 3:28 PM

LOL, 2 days later I faced the problem...

I am ashamed to ask, but... what should I do instead?

When closing the form containing the above code I receive am error:

AcmStreamHEader dispose was not called at AcmStreamHeader.Finalize()

I tried to understand as many as I could, but it's really hard. The demo code does not work with VS2010 express (I don't have a vs2010 enterprise license) and, on the other hand, I can't find any specific documentation talking about a simple task (in my eyes) as playing some audio should be.

Any kind of help will be a lot appreciated.

Thanks in advance

Dec 23, 2011 at 3:42 PM

Save ws to a class member variable, and when you have finished playing, call ws.Dispose()

out of interest, what doesn't work in VS2010 express?


Dec 23, 2011 at 4:13 PM

well, I fixed the issue with VS2010, just deleting the Ntest project.

It had something to do with nuget which is not installed in my system