SharpAudio icon indicating copy to clipboard operation
SharpAudio copied to clipboard

Null Reference Exception after disposing and re-initializing object

Open Eightvo opened this issue 4 years ago • 6 comments

if (!String.IsNullOrEmpty(_nextSongToPlay))
            {
                if (activeMusic!=null && activeMusic.State== SoundStreamState.Playing)
                {
                    activeMusic.Stop();
                    activeMusic.Dispose();
                }
                activeMusic = new SoundStream(System.IO.File.OpenRead(_nextSongToPlay), musicEngine);
                    System.Threading.Thread.Sleep(100);
                    activeMusic.Volume = currentVolume;
                        activeMusic.Play();
                _nextSongToPlay = null;
            }

It seems that there is some kind of race condition that is triggered by calling the activeMusic.Stop(); method... without putting a System.Threading.Thread.Sleep setting the volume on the activeMusic soundstream causes a null exception to be thrown.

This exception occurs if the activeMusic soundstream is or is not disposed, but only if it was not null before creating the New soundStream

Eightvo avatar Jun 10 '21 03:06 Eightvo

I created a TestCase like this and can't reproduce it:

        [BackendFact(AudioBackend.OpenAL, AudioBackend.XAudio2)]
        public void Reuse()
        {
            var mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");

            var engine = AudioEngine.CreateDefault();
            var soundStream = new SoundStream(mp3Stream, new SoundSink(engine));

            soundStream.Play();
            soundStream.Dispose();
            
            mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");
            soundStream = new SoundStream(mp3Stream, new SoundSink(engine));
            soundStream.Volume = 1.0f;
        }

Could you share which testfile you're using?

feliwir avatar Jun 10 '21 12:06 feliwir

I have created a smaller source that is causing issue

    public static void Main(String[] args)
    {

        var sfxEngine = AudioEngine.CreateDefault();
        var done = false;
        var assetname = "BareE.Harness.Assets.sfx.sfx_wpn_cannon1.wav";
        var data = new List<byte>();
        System.IO.Stream stream=null;
        using (var rdr =

Assembly.GetEntryAssembly().GetManifestResourceStream(assetname)) { if (rdr != null) { int nxt = rdr.ReadByte(); while (nxt != -1) { data.Add((byte)nxt); nxt = rdr.ReadByte(); } stream = new MemoryStream(data.ToArray()); } } if (stream==null) { Console.WriteLine("Stream not found."); } while (!done) { var ss = new SoundStream(stream, new SoundSink(sfxEngine, null), false); ss.Volume = 1; ss.Play(); //ss.Dispose(); done = Console.ReadKey().Key == ConsoleKey.Escape; } }

This code... produces a different error... I have attached a screen shot, also I have attached the files that I had been using in both issues.

[image: image.png]

There are two use cases. The first is the music system, the plan is to have one SoundStream which the system is careful to schedule events for. Only a maximum of two sound streams will be loaded at a time (The current song and the next song). The sound streams will not be played to overlap.

The second in the soundboard where each distinct sound is meant to be loaded into memory once, the sounds are meant to be fired without concern for clean up or scheduling. Distinct sounds are meant to overlap. Also, sounds are meant to overlap music system. It would be preferred but not required that individual sounds are also able to be played and overlap from one soundstream in memory.

Thank you for your responsiveness. Also, thank you for the library. It was difficult to find a .net core sound solution.

On Thu, Jun 10, 2021 at 8:48 AM Stephan Vedder @.***> wrote:

I created a TestCase like this and can't reproduce it:

    [BackendFact(AudioBackend.OpenAL, AudioBackend.XAudio2)]
    public void Reuse()
    {
        var mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");

        var engine = AudioEngine.CreateDefault();
        var soundStream = new SoundStream(mp3Stream, new SoundSink(engine));

        soundStream.Play();
        soundStream.Dispose();

        mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");
        soundStream = new SoundStream(mp3Stream, new SoundSink(engine));
        soundStream.Volume = 1.0f;
    }

Could you share which testfile you're using?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/feliwir/SharpAudio/issues/21#issuecomment-858592613, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHDLNMQBBMQFK42TKFXDZR3TSCYCZANCNFSM46NGZAUA .

Eightvo avatar Jun 10 '21 16:06 Eightvo

Sorry, a note about the previous email. A) The sound does play correctly one time... the second attempt to play the sound produces the exception provided. B) The line ss.Dispose() is commented out. Otherwise, the loop executes one time without emitting sound, then executes a second time causing exception.

On Thu, Jun 10, 2021 at 12:08 PM Eightvo 8080 @.***> wrote:

I have created a smaller source that is causing issue

    public static void Main(String[] args)
    {

        var sfxEngine = AudioEngine.CreateDefault();
        var done = false;
        var assetname = "BareE.Harness.Assets.sfx.sfx_wpn_cannon1.wav";
        var data = new List<byte>();
        System.IO.Stream stream=null;
        using (var rdr =

Assembly.GetEntryAssembly().GetManifestResourceStream(assetname)) { if (rdr != null) { int nxt = rdr.ReadByte(); while (nxt != -1) { data.Add((byte)nxt); nxt = rdr.ReadByte(); } stream = new MemoryStream(data.ToArray()); } } if (stream==null) { Console.WriteLine("Stream not found."); } while (!done) { var ss = new SoundStream(stream, new SoundSink(sfxEngine, null), false); ss.Volume = 1; ss.Play(); //ss.Dispose(); done = Console.ReadKey().Key == ConsoleKey.Escape; } }

This code... produces a different error... I have attached a screen shot, also I have attached the files that I had been using in both issues.

[image: image.png]

There are two use cases. The first is the music system, the plan is to have one SoundStream which the system is careful to schedule events for. Only a maximum of two sound streams will be loaded at a time (The current song and the next song). The sound streams will not be played to overlap.

The second in the soundboard where each distinct sound is meant to be loaded into memory once, the sounds are meant to be fired without concern for clean up or scheduling. Distinct sounds are meant to overlap. Also, sounds are meant to overlap music system. It would be preferred but not required that individual sounds are also able to be played and overlap from one soundstream in memory.

Thank you for your responsiveness. Also, thank you for the library. It was difficult to find a .net core sound solution.

On Thu, Jun 10, 2021 at 8:48 AM Stephan Vedder @.***> wrote:

I created a TestCase like this and can't reproduce it:

    [BackendFact(AudioBackend.OpenAL, AudioBackend.XAudio2)]
    public void Reuse()
    {
        var mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");

        var engine = AudioEngine.CreateDefault();
        var soundStream = new SoundStream(mp3Stream, new SoundSink(engine));

        soundStream.Play();
        soundStream.Dispose();

        mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");
        soundStream = new SoundStream(mp3Stream, new SoundSink(engine));
        soundStream.Volume = 1.0f;
    }

Could you share which testfile you're using?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/feliwir/SharpAudio/issues/21#issuecomment-858592613, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHDLNMQBBMQFK42TKFXDZR3TSCYCZANCNFSM46NGZAUA .

Eightvo avatar Jun 10 '21 16:06 Eightvo

Additional Debug information... In the File SoundStream.cs I placed a breakpoint at line 41. This breakpoint is hit in both the first and second iteration of the loop. In the first iteration, the value of stream.CanSeek is False and line 52 is not executed. On the second iteration the value of Stream.CanSeek is True and line 52 is executed and the exception occurs.

On Thu, Jun 10, 2021 at 12:17 PM Eightvo 8080 @.***> wrote:

Sorry, a note about the previous email. A) The sound does play correctly one time... the second attempt to play the sound produces the exception provided. B) The line ss.Dispose() is commented out. Otherwise, the loop executes one time without emitting sound, then executes a second time causing exception.

On Thu, Jun 10, 2021 at 12:08 PM Eightvo 8080 @.***> wrote:

I have created a smaller source that is causing issue

    public static void Main(String[] args)
    {

        var sfxEngine = AudioEngine.CreateDefault();
        var done = false;
        var assetname =

"BareE.Harness.Assets.sfx.sfx_wpn_cannon1.wav"; var data = new List(); System.IO.Stream stream=null; using (var rdr = Assembly.GetEntryAssembly().GetManifestResourceStream(assetname)) { if (rdr != null) { int nxt = rdr.ReadByte(); while (nxt != -1) { data.Add((byte)nxt); nxt = rdr.ReadByte(); } stream = new MemoryStream(data.ToArray()); } } if (stream==null) { Console.WriteLine("Stream not found."); } while (!done) { var ss = new SoundStream(stream, new SoundSink(sfxEngine, null), false); ss.Volume = 1; ss.Play(); //ss.Dispose(); done = Console.ReadKey().Key == ConsoleKey.Escape; } }

This code... produces a different error... I have attached a screen shot, also I have attached the files that I had been using in both issues.

[image: image.png]

There are two use cases. The first is the music system, the plan is to have one SoundStream which the system is careful to schedule events for. Only a maximum of two sound streams will be loaded at a time (The current song and the next song). The sound streams will not be played to overlap.

The second in the soundboard where each distinct sound is meant to be loaded into memory once, the sounds are meant to be fired without concern for clean up or scheduling. Distinct sounds are meant to overlap. Also, sounds are meant to overlap music system. It would be preferred but not required that individual sounds are also able to be played and overlap from one soundstream in memory.

Thank you for your responsiveness. Also, thank you for the library. It was difficult to find a .net core sound solution.

On Thu, Jun 10, 2021 at 8:48 AM Stephan Vedder @.***> wrote:

I created a TestCase like this and can't reproduce it:

    [BackendFact(AudioBackend.OpenAL, AudioBackend.XAudio2)]
    public void Reuse()
    {
        var mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");

        var engine = AudioEngine.CreateDefault();
        var soundStream = new SoundStream(mp3Stream, new SoundSink(engine));

        soundStream.Play();
        soundStream.Dispose();

        mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");
        soundStream = new SoundStream(mp3Stream, new SoundSink(engine));
        soundStream.Volume = 1.0f;
    }

Could you share which testfile you're using?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/feliwir/SharpAudio/issues/21#issuecomment-858592613, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHDLNMQBBMQFK42TKFXDZR3TSCYCZANCNFSM46NGZAUA .

Eightvo avatar Jun 10 '21 16:06 Eightvo

I am sorry if I am sending a ton of info very quickly. I do appreciate your library...but I have found more information. I had added a "ForceNoSeek" parameter to ensure that the condition would always specify that the file could not seek...in such a case line 52 is not executed on any iteration. The exception that is received in such a case is: [image: image.png]

On Thu, Jun 10, 2021 at 12:24 PM Eightvo 8080 @.***> wrote:

Additional Debug information... In the File SoundStream.cs I placed a breakpoint at line 41. This breakpoint is hit in both the first and second iteration of the loop. In the first iteration, the value of stream.CanSeek is False and line 52 is not executed. On the second iteration the value of Stream.CanSeek is True and line 52 is executed and the exception occurs.

On Thu, Jun 10, 2021 at 12:17 PM Eightvo 8080 @.***> wrote:

Sorry, a note about the previous email. A) The sound does play correctly one time... the second attempt to play the sound produces the exception provided. B) The line ss.Dispose() is commented out. Otherwise, the loop executes one time without emitting sound, then executes a second time causing exception.

On Thu, Jun 10, 2021 at 12:08 PM Eightvo 8080 @.***> wrote:

I have created a smaller source that is causing issue

    public static void Main(String[] args)
    {

        var sfxEngine = AudioEngine.CreateDefault();
        var done = false;
        var assetname =

"BareE.Harness.Assets.sfx.sfx_wpn_cannon1.wav"; var data = new List(); System.IO.Stream stream=null; using (var rdr = Assembly.GetEntryAssembly().GetManifestResourceStream(assetname)) { if (rdr != null) { int nxt = rdr.ReadByte(); while (nxt != -1) { data.Add((byte)nxt); nxt = rdr.ReadByte(); } stream = new MemoryStream(data.ToArray()); } } if (stream==null) { Console.WriteLine("Stream not found."); } while (!done) { var ss = new SoundStream(stream, new SoundSink(sfxEngine, null), false); ss.Volume = 1; ss.Play(); //ss.Dispose(); done = Console.ReadKey().Key == ConsoleKey.Escape; } }

This code... produces a different error... I have attached a screen shot, also I have attached the files that I had been using in both issues.

[image: image.png]

There are two use cases. The first is the music system, the plan is to have one SoundStream which the system is careful to schedule events for. Only a maximum of two sound streams will be loaded at a time (The current song and the next song). The sound streams will not be played to overlap.

The second in the soundboard where each distinct sound is meant to be loaded into memory once, the sounds are meant to be fired without concern for clean up or scheduling. Distinct sounds are meant to overlap. Also, sounds are meant to overlap music system. It would be preferred but not required that individual sounds are also able to be played and overlap from one soundstream in memory.

Thank you for your responsiveness. Also, thank you for the library. It was difficult to find a .net core sound solution.

On Thu, Jun 10, 2021 at 8:48 AM Stephan Vedder @.***> wrote:

I created a TestCase like this and can't reproduce it:

    [BackendFact(AudioBackend.OpenAL, AudioBackend.XAudio2)]
    public void Reuse()
    {
        var mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");

        var engine = AudioEngine.CreateDefault();
        var soundStream = new SoundStream(mp3Stream, new SoundSink(engine));

        soundStream.Play();
        soundStream.Dispose();

        mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");
        soundStream = new SoundStream(mp3Stream, new SoundSink(engine));
        soundStream.Volume = 1.0f;
    }

Could you share which testfile you're using?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/feliwir/SharpAudio/issues/21#issuecomment-858592613, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHDLNMQBBMQFK42TKFXDZR3TSCYCZANCNFSM46NGZAUA .

Eightvo avatar Jun 10 '21 16:06 Eightvo

Ok... This snippet most closely matches the original Issue. In this example, the sound does play correctly multiple time under the conditions that A) the line ss.Dispose() is not called after ss.Play(); B) System.Threading.Sleep is called after creating a new soundstream but before modifying the volume or requesting the sound stream to play.

If A is not respected then there is no exceptions thrown, but neither is any sound played. If B is not respected a null reference exception is thrown at the line ss.Volume = 0.5f;

    public static void Main(String[] args)
    {

        var sfxEngine = AudioEngine.CreateDefault();
        var done = false;
        var assetname = "BareE.Harness.Assets.sfx.sfx_wpn_cannon1.wav";
        var data = new List<byte>();
        System.IO.Stream stream=null;
        using (var rdr =

Assembly.GetEntryAssembly().GetManifestResourceStream(assetname)) { if (rdr != null) { int nxt = rdr.ReadByte(); while (nxt != -1) { data.Add((byte)nxt); nxt = rdr.ReadByte(); } stream = new MemoryStream(data.ToArray()); } } if (stream==null) { Console.WriteLine("Stream not found."); } while (!done) { MemoryStream strmCopy = new MemoryStream(((MemoryStream)stream).ToArray()); strmCopy.Seek(0, SeekOrigin.Begin); var ss = new SoundStream(strmCopy, new SoundSink(sfxEngine, null), false); System.Threading.Thread.Sleep(100); ss.Volume = 0.5f; ss.Play(); //ss.Dispose(); done = Console.ReadKey().Key == ConsoleKey.Escape; } }

On Thu, Jun 10, 2021 at 12:33 PM Eightvo 8080 @.***> wrote:

I am sorry if I am sending a ton of info very quickly. I do appreciate your library...but I have found more information. I had added a "ForceNoSeek" parameter to ensure that the condition would always specify that the file could not seek...in such a case line 52 is not executed on any iteration. The exception that is received in such a case is: [image: image.png]

On Thu, Jun 10, 2021 at 12:24 PM Eightvo 8080 @.***> wrote:

Additional Debug information... In the File SoundStream.cs I placed a breakpoint at line 41. This breakpoint is hit in both the first and second iteration of the loop. In the first iteration, the value of stream.CanSeek is False and line 52 is not executed. On the second iteration the value of Stream.CanSeek is True and line 52 is executed and the exception occurs.

On Thu, Jun 10, 2021 at 12:17 PM Eightvo 8080 @.***> wrote:

Sorry, a note about the previous email. A) The sound does play correctly one time... the second attempt to play the sound produces the exception provided. B) The line ss.Dispose() is commented out. Otherwise, the loop executes one time without emitting sound, then executes a second time causing exception.

On Thu, Jun 10, 2021 at 12:08 PM Eightvo 8080 @.***> wrote:

I have created a smaller source that is causing issue

    public static void Main(String[] args)
    {

        var sfxEngine = AudioEngine.CreateDefault();
        var done = false;
        var assetname =

"BareE.Harness.Assets.sfx.sfx_wpn_cannon1.wav"; var data = new List(); System.IO.Stream stream=null; using (var rdr = Assembly.GetEntryAssembly().GetManifestResourceStream(assetname)) { if (rdr != null) { int nxt = rdr.ReadByte(); while (nxt != -1) { data.Add((byte)nxt); nxt = rdr.ReadByte(); } stream = new MemoryStream(data.ToArray()); } } if (stream==null) { Console.WriteLine("Stream not found."); } while (!done) { var ss = new SoundStream(stream, new SoundSink(sfxEngine, null), false); ss.Volume = 1; ss.Play(); //ss.Dispose(); done = Console.ReadKey().Key == ConsoleKey.Escape; } }

This code... produces a different error... I have attached a screen shot, also I have attached the files that I had been using in both issues.

[image: image.png]

There are two use cases. The first is the music system, the plan is to have one SoundStream which the system is careful to schedule events for. Only a maximum of two sound streams will be loaded at a time (The current song and the next song). The sound streams will not be played to overlap.

The second in the soundboard where each distinct sound is meant to be loaded into memory once, the sounds are meant to be fired without concern for clean up or scheduling. Distinct sounds are meant to overlap. Also, sounds are meant to overlap music system. It would be preferred but not required that individual sounds are also able to be played and overlap from one soundstream in memory.

Thank you for your responsiveness. Also, thank you for the library. It was difficult to find a .net core sound solution.

On Thu, Jun 10, 2021 at 8:48 AM Stephan Vedder < @.***> wrote:

I created a TestCase like this and can't reproduce it:

    [BackendFact(AudioBackend.OpenAL, AudioBackend.XAudio2)]
    public void Reuse()
    {
        var mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");

        var engine = AudioEngine.CreateDefault();
        var soundStream = new SoundStream(mp3Stream, new SoundSink(engine));

        soundStream.Play();
        soundStream.Dispose();

        mp3Stream = typeof(SoundStreams).Assembly.GetManifestResourceStream("SharpAudio.Tests.Assets.test.mp3");
        soundStream = new SoundStream(mp3Stream, new SoundSink(engine));
        soundStream.Volume = 1.0f;
    }

Could you share which testfile you're using?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/feliwir/SharpAudio/issues/21#issuecomment-858592613, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHDLNMQBBMQFK42TKFXDZR3TSCYCZANCNFSM46NGZAUA .

Eightvo avatar Jun 10 '21 16:06 Eightvo