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

Unhandled Exception in NAudio.dll

Apr 28, 2011 at 5:16 PM

I am getting unhanded exceptions from the NAudio.dll while decoding MP3's  This is random and the MP3 files that it breaks on are not corrupt.

If i recall its dealing with a read next byte out of range index something for decoding an MP3.

Im running my application right now trying to have this raised again.

The NAudio.dll was built from the latest source because the 1.4 dll was doing the same thing but even more often.

 

Im about to add the project directly into my solution so i can have an exact line where its raised as well but if any one knows why this is happening i would appreciate it.

 

Thanks

-Largo Usagi

Coordinator
Apr 28, 2011 at 7:00 PM

if you could test against the code that would be great. there might be an edge case that the MP3 frame parser is not dealing with

Apr 28, 2011 at 10:04 PM

A first chance exception of type 'System.FormatException' occurred in NAudio.dll
A first chance exception of type 'System.IO.EndOfStreamException' occurred in mscorlib.dll
A first chance exception of type 'System.IO.EndOfStreamException' occurred in mscorlib.dll
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>CerberusLanJukeboxDeamon.vshost.exe</AppDomain><Exception><ExceptionType>System.IO.EndOfStreamException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Unable to read beyond the end of the stream.</Message><StackTrace>   at System.IO.BinaryReader.ReadByte()
   at NAudio.Wave.Mp3Frame..ctor(Stream input, Boolean readData)
   at NAudio.Wave.Mp3FileReader.ReadNextFrame(Boolean readData)
   at NAudio.Wave.Mp3FileReader.ReadNextFrame()
   at NAudio.Wave.Mp3FileReader.Read(Byte[] sampleBuffer, Int32 offset, Int32 numBytes)
   at NAudio.Wave.SampleProviders.Stereo16SampleProvider.LoadNextChunk(IWaveProvider source, Int32 samplePairsRequired)
   at NAudio.Wave.WaveChannel32.Read(Byte[] destBuffer, Int32 offset, Int32 numBytes)
   at NAudio.Wave.WaveOutBuffer.OnDone()
   at NAudio.Wave.WaveOut.Callback(IntPtr hWaveOut, WaveMessage uMsg, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved)</StackTrace><ExceptionString>System.IO.EndOfStreamException: Unable to read beyond the end of the stream.
   at System.IO.BinaryReader.ReadByte()
   at NAudio.Wave.Mp3Frame..ctor(Stream input, Boolean readData)
   at NAudio.Wave.Mp3FileReader.ReadNextFrame(Boolean readData)
   at NAudio.Wave.Mp3FileReader.ReadNextFrame()
   at NAudio.Wave.Mp3FileReader.Read(Byte[] sampleBuffer, Int32 offset, Int32 numBytes)
   at NAudio.Wave.SampleProviders.Stereo16SampleProvider.LoadNextChunk(IWaveProvider source, Int32 samplePairsRequired)
   at NAudio.Wave.WaveChannel32.Read(Byte[] destBuffer, Int32 offset, Int32 numBytes)
   at NAudio.Wave.WaveOutBuffer.OnDone()
   at NAudio.Wave.WaveOut.Callback(IntPtr hWaveOut, WaveMessage uMsg, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved)</ExceptionString></Exception></TraceRecord>
An unhandled exception of type 'System.IO.EndOfStreamException' occurred in mscorlib.dll

Additional information: Unable to read beyond the end of the stream.

 

this is the dissasembly

 

00000000  push        ebp
00000001  mov         ebp,esp
00000003  push        esi
00000004  mov         esi,ecx
00000006  cmp         dword ptr [esi+4],0
0000000a  je          0092BC08
00000010  mov         ecx,dword ptr [esi+4]
00000013  mov         eax,dword ptr [ecx]
00000015  mov         eax,dword ptr [eax+34h]
00000018  call        dword ptr [eax+18h]
0000001b  cmp         eax,0FFFFFFFFh
0000001e  je          0092BC21
00000024  and         eax,0FFh
00000029  pop         esi
0000002a  pop         ebp
0000002b  ret
0000002c  call        FFC8D820
00000031  mov         ecx,dword ptr [esi+4]
00000034  mov         eax,dword ptr [ecx]
00000036  mov         eax,dword ptr [eax+34h]
00000039  call        dword ptr [eax+18h]
0000003c  cmp         eax,0FFFFFFFFh
0000003f  jne         FF6D4448
00000045  mov         ecx,6C99302Ch
0000004a  call        FF66C644
0000004f  mov         esi,eax
00000051  mov         edx,6C681000h
00000056  mov         ecx,70019429h
0000005b  call        FF66C6C4
00000060  mov         ecx,eax
00000062  call        FF66DA4C
00000067  mov         edx,eax
00000069  mov         ecx,esi
0000006b  call        FFDCA51C
00000070  mov         ecx,esi
00000072  call        FF66C6CC
00000077  int         3

Call stack location of mscorlib.dll!System.IO.BinaryReader.ReadByte() + 0x77 bytes

Coordinator
Apr 29, 2011 at 8:23 AM

are you able to share the MP3?

Apr 29, 2011 at 4:22 PM

Yah i can run the application again until it its an MP3 that does this to it.

 

I also got a new error in stress testing

Destination array was not long enough check destIndex and length, and the array's lower bounds.

 

This is the function that the related call was made under

 

public bool Play()
        {
            if (!IsPlaying)
            {
                if (fileSet)
                {
                    try
                    {
                        waveOutDevice.Init(mainOutputStream);
                        waveOutDevice.Play();
                        Console.WriteLine("Playing: " + mp3File);
                        if (SongPlayed != null) SongPlayed(this);
                        return true;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Error Playing: " + e.Message);
                        return false;
                    }
                }
                else
                {
                    Console.WriteLine("You need to set a file before trying to play one");
                    return false;
                }
            }
            else
            {
                Console.WriteLine("Allready playing file");
                return false;
            }
        }

 

 

and for the betterment because hell maybe im using this wrong here is the mp3 player class i have written thus far

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using NAudio;
using NAudio.Wave;
using NAudio.CoreAudioApi;

namespace JukeboxLib
{
    public class MP3Player
    {

        public delegate void PlayerEvents(object sender);

        public event PlayerEvents PlaybackFinished;
        public event PlayerEvents SongSkipped;
        public event PlayerEvents SongStopped;
        public event PlayerEvents SongPaused;
        public event PlayerEvents SongPlayed;

        public event PlayerEvents OutputChanged;

        private IWavePlayer waveOutDevice;
        private WaveStream mainOutputStream;
        private WaveChannel32 volumeStream;
        private Timer updateTimer;

        private float precentThrough;
        private int outputDevice;
        private bool fileSet;
        private String mp3File;
        private ArrayList outputDevices;

        /// <summary>
        /// Is the MP3 Player Currently Playing a Song
        /// </summary>
        public bool IsPlaying
        {
            get
            {
                if (waveOutDevice.PlaybackState == PlaybackState.Playing)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        /// <summary>
        /// Is the MP3 player paused during playback
        /// </summary>
        public bool IsPaused
        {
            get
            {
                if (waveOutDevice.PlaybackState == PlaybackState.Paused)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        /// <summary>
        /// Is the MP3 Player stopped
        /// </summary>
        public bool IsStopped
        {
            get
            {
                if (waveOutDevice.PlaybackState == PlaybackState.Stopped)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        /// <summary>
        /// Get or Set the output device
        /// </summary>
        public int OutputDevice
        {
            get
            {
                return outputDevice;
            }
            set
            {
                if (value <= WaveOut.DeviceCount)
                {
                    float vol = waveOutDevice.Volume;
                    outputDevice = value;
                    if (IsPlaying)
                    {
                        Pause();
                    }
                    createWavePlayer();
                    waveOutDevice.Volume = vol;
                    Play();
                    OutputChanged(this);
                }
            }
        }

        /// <summary>
        /// The current playback state of the MP3 Player
        /// </summary>
        public PlaybackState PlayerState
        {
            get
            {
                if (waveOutDevice != null)
                {
                    return waveOutDevice.PlaybackState;
                }
                else
                {
                    Console.WriteLine("Playstate is stopped because it hasnt been initialzed");
                    return PlaybackState.Stopped;
                }
            }
        }
        /// <summary>
        /// The location of the file loaded to the MP3 player
        /// </summary>
        public String MP3File
        {
            get
            {
                return mp3File;
            }
            set
            {
                mp3File = value;
                if (value != null)
                {
                    fileSet = true;
                }
                else
                {
                    fileSet = false;
                }
                mainOutputStream = CreateInputStream(mp3File);
            }
        }
        /// <summary>
        /// Volume where 1.0 = 100% and .01 = 1%
        /// </summary>
        public float Volume
        {
            get
            {
                return waveOutDevice.Volume;
            }
            set
            {
                if (value <= 1.0f)
                {
                    waveOutDevice.Volume = value;
                }
                else
                {
                    waveOutDevice.Volume = 1.0f;
                }
            }
        }

        public MP3Player()
        {
            setDefaults();
        }

        private void setDefaults()
        {
            outputDevices = new ArrayList();

            for (int deviceId = 0; deviceId < WaveOut.DeviceCount; deviceId++)
            {
                var capabilities = WaveOut.GetCapabilities(deviceId);
                outputDevices.Add(String.Format("Device {0} ({1})", deviceId, capabilities.ProductName));
            }
            for (int x = 0; x < outputDevices.Count; x++)
            {
                Console.WriteLine(outputDevices[x].ToString());
            }

            createWavePlayer();

            fileSet = false;
            precentThrough = 0.0f;

            updateTimer = new Timer(500);
            updateTimer.Elapsed += new ElapsedEventHandler(updateTimer_Elapsed);
            updateTimer.Start();
        }
        private void createWavePlayer()
        {
            WaveOut derp = new WaveOut(WaveCallbackInfo.FunctionCallback());
            derp.DesiredLatency = 200;
            derp.DeviceNumber = outputDevice;
            waveOutDevice = derp;

            waveOutDevice.PlaybackStopped += new EventHandler(waveOutDevice_PlaybackStopped);
        }

        private void updateTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (waveOutDevice != null && mainOutputStream != null)
            {
                TimeSpan currentTime = mainOutputStream.CurrentTime;
                if (mainOutputStream.Position >= mainOutputStream.Length)
                {
                    waveOutDevice.Stop();
                    PlaybackFinished(this);
                }
                else
                {
                    precentThrough = mainOutputStream.Position / mainOutputStream.Length;
                }
            }
        }
        private void waveOutDevice_PlaybackStopped(object sender, EventArgs e)
        {
            if (PlaybackFinished != null) PlaybackFinished(this);
        }

        private WaveStream CreateInputStream(string fileName)
        {
            try
            {
                WaveChannel32 inputStream;
                if (fileName.ToLower().EndsWith(".mp3"))
                {
                    WaveStream mp3Reader = new Mp3FileReader(fileName);
                    inputStream = new WaveChannel32(mp3Reader);
                }
                else
                {
                    throw new InvalidOperationException("Unsupported extension");
                }
                volumeStream = inputStream;
                return volumeStream;
            }
            catch(Exception ee)
            {
                Console.WriteLine("Error creating inputstream");
                Console.WriteLine(ee.Message);
                return null;
            }
            return null;
        }

        public void ThreadStartPlay()
        {
            Play();
        }
        public bool Play()
        {
            if (!IsPlaying)
            {
                if (fileSet)
                {
                    try
                    {
                        waveOutDevice.Init(mainOutputStream);
                        waveOutDevice.Play();
                        Console.WriteLine("Playing: " + mp3File);
                        if (SongPlayed != null) SongPlayed(this);
                        return true;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Error Playing: " + e.Message);
                        return false;
                    }
                }
                else
                {
                    Console.WriteLine("You need to set a file before trying to play one");
                    return false;
                }
            }
            else
            {
                Console.WriteLine("Allready playing file");
                return false;
            }
        }
        public bool Pause()
        {
            if (IsPaused)
            {
                Play();
            }
            else
            {
                waveOutDevice.Pause();
                if (SongPaused != null) SongPaused(this);
            }
            return true;
        }
        public bool Stop()
        {
            if (!IsStopped)
            {
                waveOutDevice.Stop();
                mainOutputStream = CreateInputStream(mp3File);
                if (SongStopped != null) SongStopped(this);
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool Skip()
        {
            waveOutDevice.Stop();
            mainOutputStream = null;
            if (SongSkipped != null) SongSkipped(this);
            return true;
        }

    }
}

May 1, 2011 at 2:41 AM

https://rapidshare.com/files/460017756/thows_exception.mp3

Here is an mp3 that raises an exception

Coordinator
May 2, 2011 at 8:27 PM

thanks for the link. I will test with the file and report back if I can find what is wrong.

Mark

Coordinator
May 7, 2011 at 10:00 AM

OK, it's just getting to the end of file sooner than expected. I'll probably update future versions of NAudio to just ignore that kind of error with MP3 playback.

May 7, 2011 at 12:54 PM

Is this something that will be revision i can download and build from source, this is the only error keeping me from using this in an application.  I would like to be using this very soon as well.

 

Any ways thanks for looking over this and i cant wait to see this get patched, i have found about 50 or so MP3's that do that, the dll is being tested against over 30k mp3's so any other errors i find i will pass on to you.

 

-Largo Usagi

Coordinator
May 7, 2011 at 7:40 PM

hi largo, can you test with the latest in souce control? I have made a bunch of refactoring improvements (more to follow)

May 8, 2011 at 12:45 AM

Hell yah i can,

Ill get on this in the next few hours here, and have something posted back within 48 hours (probably tomorrow though)

Oct 25, 2011 at 8:30 PM

Does anyone know if this is resolved. We are getting the same problem here, very random. 

 

Thx

Oct 25, 2011 at 8:30 PM

Does anyone know if this is resolved. We are getting the same problem here, very random. 

 

Thx

Oct 25, 2011 at 8:31 PM

Just a note the issue is coming from streams off of pandora. 

Coordinator
Oct 26, 2011 at 9:50 AM

@EvanW - are you using the latest code from Source Control?

Oct 26, 2011 at 1:55 PM

I am using the latest release. Is the issue fixed in Source ? Is there a version in source control you consider production stable that I can get ?

Thanks !!

Coordinator
Oct 26, 2011 at 1:57 PM

Well I don't know exactly what issue you are seeing, so I can't say if it is fixed. The latest version is source code is more stable than 1.4 was, and will probably only get minor tweaks before 1.5 is released

Oct 26, 2011 at 2:07 PM

The exact issue is randomly PlaybackStopped on interface IWavePlayer created using DirectSoundOut just fires before the audio is played. This happens I'd say 10% of the time.  These are 128K mp3 streams. It would be a none issue but pandoras workflow opens a new stream per song and it's noticeable when it happens. 

If you think getting the latest version will help , I'll give it a go . 

Thx

Oct 28, 2011 at 2:02 AM

Got the latest source, samples wont build and the Mp3Frame.StreamEnded isn't defined anymore. Any advice ? Really want to use this library but we're still experiencing studdering occasionally and that is going to make problems when we go to production. 

 

Thx

 

Evan

Coordinator
Nov 1, 2011 at 4:23 PM

what build errors are you getting?

Nov 1, 2011 at 4:32 PM

Apologies for not updating this thread , it was a visual studio thing.