SFML community forums

Bindings - other languages => DotNet => Topic started by: s.baus on September 05, 2014, 11:56:41 am

Title: Problems with NLayer: System.IO.EndOfStreamException
Post by: s.baus on September 05, 2014, 11:56:41 am
Hello,

I implemented a SoundStream which can read MP3 Codec via Nlayer (https://nlayer.codeplex.com/ (https://nlayer.codeplex.com/)). It works fine, but sometimes I get a System.IO.EndOfStreamException from NLayer. It appers randomly and the developer is not shure, where it comes from, so I wanted to ask here, if you see any errors in my implementation:

namespace AudioCuesheetEditor.AudioBackend.SFML
{
    /// <summary>
    /// Class for mp3 decoded audio files to use in SFML as Soundstream, since SFML doesn't support mp3 decoding (for legal reasons).
    /// </summary>
    public class Mp3StreamSFML : SoundStream
    {
        private static readonly Logfile log = Logfile.getLogfile(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private MpegFile mp3file;
        private Mutex mutex;

        /// <summary>
        /// Initializes a new instance of the <see cref="AudioCuesheetEditor.AudioBackend.SFML.Mp3StreamSFML"/> class.
        /// </summary>
        /// <param name="_filename">Full path to the file</param>
        public Mp3StreamSFML(String _filename)
        {
            log.debug("Constructor called with " + _filename);
            this.mp3file = new MpegFile(_filename);
            this.Initialize((uint)this.mp3file.Channels, (uint)this.mp3file.SampleRate);
            this.mutex = new Mutex();
        }

        public TimeSpan Duration
        {
            get
            {
                log.debug("Duration = " + this.mp3file.Duration);
                return this.mp3file.Duration;
            }
        }

        #region implemented abstract members of SoundStream

        protected override bool OnGetData(out short[] samples)
        {
            log.debug("OnGetData called");
            this.mutex.WaitOne();
            //Buffer data for about 1 second
            float[] normalizedaudiodata = new float[48000];
            int readSamples = this.mp3file.ReadSamples(normalizedaudiodata, 0, normalizedaudiodata.Length);
            short[] pcmaudiodata;
            if (readSamples > 0)
            {
                pcmaudiodata = new short[readSamples]; // converted data
                for (int i = 0; i < readSamples; i++)
                {
                    // clip the data
                    if (normalizedaudiodata[i] > 1.0f)
                    {
                        normalizedaudiodata[i] = 1.0f;
                    }
                    else
                    {
                        if (normalizedaudiodata[i] < -1.0f)
                        {
                            normalizedaudiodata[i] = -1.0f;
                        }
                    }
                    // convert to pcm data
                    pcmaudiodata[i] = (short)(normalizedaudiodata[i] * short.MaxValue);
                }
                samples = pcmaudiodata;
                this.mutex.ReleaseMutex();
                return true;
            }
            else
            {
                samples = null;
                this.mutex.ReleaseMutex();
                return false;
            }
        }

        protected override void OnSeek(TimeSpan timeOffset)
        {
            log.debug("OnSeek called with " + timeOffset);
            this.mutex.WaitOne();
            if ((timeOffset <= this.mp3file.Duration) && (timeOffset >= TimeSpan.Zero))
            {
                while (this.mp3file.CanSeek == false)
                {
                    Thread.Sleep(100);
                }
                this.mp3file.Time = timeOffset;
            }
            this.mutex.ReleaseMutex();
        }

        #endregion
    }
}

Exception:

Quote
16.07.2014 15:47:37 AudioCuesheetEditor.AudioBackend.SFML.Mp3StreamSFML: ERROR | System.IO.EndOfStreamException: Es wurde versucht, über das Ende des Datenstroms hinaus zu lesen.
bei NLayer.Decoder.MpegFrame.ReadBits(Int32 bitCount) in d:\tmp\AudioCuesheetEditor\src\NLayer\Decoder\MpegFrame.cs:Zeile 528.
bei NLayer.Decoder.LayerIIIDecoder.ReadSideInfo(IMpegFrame frame) in d:\tmp\AudioCuesheetEditor\src\NLayer\Decoder\LayerIIIDecoder.cs:Zeile 687.
bei NLayer.Decoder.LayerIIIDecoder.DecodeFrame(IMpegFrame frame, Single[] ch0, Single[] ch1) in d:\tmp\AudioCuesheetEditor\src\NLayer\Decoder\LayerIIIDecoder.cs:Zeile 502.
bei NLayer.MpegFrameDecoder.DecodeFrameImpl(IMpegFrame frame, Array dest, Int32 destOffset) in d:\tmp\AudioCuesheetEditor\src\NLayer\MpegFrameDecoder.cs:Zeile 110.
bei NLayer.MpegFrameDecoder.DecodeFrame(IMpegFrame frame, Single[] dest, Int32 destOffset) in d:\tmp\AudioCuesheetEditor\src\NLayer\MpegFrameDecoder.cs:Zeile 74.
bei NLayer.MpegFile.set_Position(Int64 value) in d:\tmp\AudioCuesheetEditor\src\NLayer\MpegFile.cs:Zeile 92.
bei NLayer.MpegFile.set_Time(TimeSpan value) in d:\tmp\AudioCuesheetEditor\src\NLayer\MpegFile.cs:Zeile 107.
bei AudioCuesheetEditor.AudioBackend.SFML.Mp3StreamSFML.OnSeek(TimeSpan timeOffset) in d:\tmp\AudioCuesheetEditor\src\AudioCuesheetEditor\AudioBackend\SFML\Mp3StreamSFML.cs:Zeile 92.

My code can be found here (for further searching): http://sourceforge.net/p/audiocuesheet/code/HEAD/tree/trunk/ (http://sourceforge.net/p/audiocuesheet/code/HEAD/tree/trunk/)

I'm looking forward to hearing from you ;).

Greets
Sven
Title: Re: Problems with NLayer: System.IO.EndOfStreamException
Post by: s.baus on September 09, 2014, 07:24:55 pm
No one any idea? We are searching for the problem, but have no idea, why it sometimes works, sometimes not :(.
Title: Re: Problems with NLayer: System.IO.EndOfStreamException
Post by: zsbzsb on September 09, 2014, 08:01:55 pm
It really has nothing to do with SFML... I don't know enough of this other library, but it really sounds like you should be checking if the EOF has been reached before trying to read data.
Title: Re: Problems with NLayer: System.IO.EndOfStreamException
Post by: s.baus on September 11, 2014, 07:53:02 pm
Thanks for your help. But I already check if the seeking is beyond the end of the file.

What I found out, is that it works, if I reset the reference of this.mp3file everytime "OnSeek" is called. But that is a bit bad, to throw the object away everytime. Also the error comes more often if I trigger seeking faster (more times a second) than if I seek just once every ten seconds. Maybe it has something to do with the threads of SFML? I doesn't really know, how the multithreading of SFML works. Any idea?

Thanks for every help.
Title: Re: Problems with NLayer: System.IO.EndOfStreamException
Post by: s.baus on September 14, 2014, 07:04:58 pm
NLayer had a bug with seeking, so the problem was there. Just for your information, everybody having this problem needs to update NLayer ;).