This project has moved. For the latest updates, please go here.

Why does AudioFileReader work but WaveFileReader not?

Dec 14, 2013 at 9:28 AM
Edited Dec 14, 2013 at 9:31 AM
I'm using NAudio 1.7 (naudio-f8a517a55f2d)

I have the following code
                   wfr = new WaveFileReader(st.parent.Sounds.GetSound(sound));
                    if (wfr.WaveFormat.Encoding != WaveFormatEncoding.Pcm && wfr.WaveFormat.Encoding != WaveFormatEncoding.IeeeFloat)
                    {
                        wfr = WaveFormatConversionStream.CreatePcmStream(wfr);
                        wfr = new BlockAlignReductionStream(wfr);
                    }                    
                    wout = new WaveOut();
                    wout.Init(wfr);
                    wout.Volume = st.parent.Volume / 100f;
                    player = new WaveOutEvent();
                    player.PlaybackStopped += new EventHandler<StoppedEventArgs>(player_PlaybackStopped);
                    player.Init(wfr);
The st.parent.Sounds.GetSound(sound) call returns
return new FileStream(sr2.resourceName, FileMode.Open, FileAccess.Read);
However this code for certain sounds fails in wout.Init(wfr) with InvalidParameter.

If I follow the code down to;
       internal MmResult WaveOutOpen(out IntPtr waveOutHandle, int deviceNumber, WaveFormat waveFormat, WaveInterop.WaveCallback callback)
        {
            MmResult result;
            if (Strategy == WaveCallbackStrategy.FunctionCallback)
            {
                result = WaveInterop.waveOutOpen(out waveOutHandle, (IntPtr)deviceNumber, waveFormat, callback, IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackFunction);
            }
            else
            {
                result = WaveInterop.waveOutOpenWindow(out waveOutHandle, (IntPtr)deviceNumber, waveFormat, this.Handle, IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackWindow);
            }
            return result;
I can see that the waveFormat is 16 bit PCM, 22KHz 1 channel.


If I use the NAudio demo using the simpleplayback demo and open the same file and play it works. Following that code the waveformat is given is IEEEFloat.

I can't see what the AudioFileReader is doing differently than my code above using WaveFileReader, and no I can;t just use AudioFileReader because I need to use a Stream which AudioFileReader doesn't support.
Coordinator
Dec 19, 2013 at 10:57 AM
it's the soundcard drivers. Try opening WaveOut with different WaveFormat's and see what works. (just make a RawSourceWaveStream as a quick way to try different WaveFormats).
Dec 19, 2013 at 1:56 PM
Edited Dec 19, 2013 at 7:34 PM
Thank you for the reply, I shall have a look at that. What then is the best way to support the sound formats like AudioFileReader but with the ability to take a stream rather than just a filename?

Been looking again and the extra step that AudioFileReader seems to take is to use a ConvertWaveProviderIntoSampleProvider which converts the PCM into IEEEFloat. I suppose I shall try and follow suit and put that in so that I can use WaveProvider with as many formats as possible.
Dec 19, 2013 at 8:04 PM
This change seems to work.
                    wfr = new WaveFileReader(st.parent.Sounds.GetSound(sound));
                    if (wfr.WaveFormat.Encoding != WaveFormatEncoding.Pcm && wfr.WaveFormat.Encoding != WaveFormatEncoding.IeeeFloat)
                    {
                        wfr = WaveFormatConversionStream.CreatePcmStream(wfr);
                        wfr = new BlockAlignReductionStream(wfr);
                    }
                    SampleChannel sampleChannel = new SampleChannel(wfr,false);
                    wout = new WaveOut();
                    wout.Init(sampleChannel);
                    wout.Volume = st.parent.Volume / 100f;
                    player = new WaveOutEvent();
                    player.PlaybackStopped += new EventHandler<StoppedEventArgs>(player_PlaybackStopped);
                    player.Init(sampleChannel);