OpenAL crashing the game

Some players reported that my game was crashing without even opening the window, so I managed to reproduce the problem on an old computer and debugged it with WinDbg and got the following stack trace:

0:000> !clrstack
OS Thread Id: 0x193c (0)
        Child SP               IP Call Site
000000000022e1e8 000007fefd379e5d [HelperMethodFrame: 000000000022e1e8] 
000000000022e2d0 000007fe8309071c Microsoft.Xna.Framework.Audio.OpenALSoundController.ReserveSource()
000000000022e330 000007fe8309051c Microsoft.Xna.Framework.Audio.OggStream..ctor(System.String, System.Action, Int32)
000000000022e380 000007fe82fae842 Microsoft.Xna.Framework.Media.Song.PlatformInitialize(System.String)
000000000022e3d0 000007fe82fae0b4 Microsoft.Xna.Framework.Media.Song..ctor(System.String, Int32)
000000000022e410 000007fe82fadc9e Microsoft.Xna.Framework.Content.SongReader.Read(Microsoft.Xna.Framework.Content.ContentReader, Microsoft.Xna.Framework.Media.Song)
000000000022e450 000007fe82fa6c58 Microsoft.Xna.Framework.Content.ContentTypeReader`1[[System.__Canon, mscorlib]].Read(Microsoft.Xna.Framework.Content.ContentReader, System.Object)
000000000022e490 000007fe82fa6b72 Microsoft.Xna.Framework.Content.ContentReader.InnerReadObject[[System.__Canon, mscorlib]](System.__Canon)
000000000022e4e0 000007fe82fa6aea Microsoft.Xna.Framework.Content.ContentReader.ReadObject[[System.__Canon, mscorlib]]()
000000000022e520 000007fe82fa1ff3 Microsoft.Xna.Framework.Content.ContentReader.ReadAsset[[System.__Canon, mscorlib]]()
000000000022e560 000007fe82fa0ee5 Microsoft.Xna.Framework.Content.ContentManager.ReadAsset[[System.__Canon, mscorlib]](System.String, System.Action`1)
000000000022e600 000007fe82fa0c8b Microsoft.Xna.Framework.Content.ContentManager.Load[[System.__Canon, mscorlib]](System.String)
000000000022e670 000007fe82fadb68 *** WARNING: Unable to verify checksum for C:\Users\Rafael\Desktop\LudumDare38\LudumDare38\bin\DesktopGL\AnyCPU\Debug\LudumDare38.exe
LudumDare38.Managers.SoundManager.LoadBgm(System.String) [C:\Users\Rafael\Documents\Visual Studio 2015\Projects\LudumDare38\LudumDare38\Managers\SoundManager.cs @ 86]
000000000022e6e0 000007fe82fac782 LudumDare38.Managers.SoundManager.Initialize() [C:\Users\Rafael\Documents\Visual Studio 2015\Projects\LudumDare38\LudumDare38\Managers\SoundManager.cs @ 58]
000000000022e770 000007fe82f9f517 LudumDare38.Managers.SceneManager.LoadContent(Microsoft.Xna.Framework.Content.ContentManager) [C:\Users\Rafael\Documents\Visual Studio 2015\Projects\LudumDare38\LudumDare38\Managers\SceneManager.cs @ 151]
000000000022e8d0 000007fe82f9909d LudumDare38.GameMain.LoadContent() [C:\Users\Rafael\Documents\Visual Studio 2015\Projects\LudumDare38\LudumDare38\GameMain.cs @ 65]
000000000022e950 000007fe82f986ac Microsoft.Xna.Framework.Game.Initialize()
000000000022e990 000007fe82f984ca LudumDare38.GameMain.Initialize() [C:\Users\Rafael\Documents\Visual Studio 2015\Projects\LudumDare38\LudumDare38\GameMain.cs @ 53]
000000000022ea00 000007fe82f96f4a Microsoft.Xna.Framework.Game.DoInitialize()
000000000022ea40 000007fe82f96be7 Microsoft.Xna.Framework.Game.Run(Microsoft.Xna.Framework.GameRunBehavior)
000000000022eac0 000007fe82f70a2d LudumDare38.Program.Main() [C:\Users\Rafael\Documents\Visual Studio 2015\Projects\LudumDare38\LudumDare38\Program.cs @ 17]
000000000022edd0 000007fee25f3753 [GCFrame: 000000000022edd0] 

Then I compiled the game on the same PC and tried to run it through Visual Studio, I got this error:

I placed a breakpoint in this line and the Song is loaded only once, and it is never played (the error happens before that), I can’t understand why it is raising an InstancePlayLimitException.

After that I compiled the Release binaries and when I run it on my main PC, it does crash while the Debug binaries doesn’t. I openned the dump on Visual Studio and it leaded me to this line: https://github.com/Phantom-Ignition/LudumDare38/blob/master/LudumDare38/Managers/SoundManager.cs#L54
All it does is call a funcion that loads a SoundEffect using the Content Manager: https://github.com/Phantom-Ignition/LudumDare38/blob/master/LudumDare38/Managers/SoundManager.cs#L95

The platform of the project is Cross Platform Desktop Project, I’m using MonoGame 3.6. Does someone have any idea what the problem can be? Thanks in advance.

Hey Rafael,

public static SoundEffect LoadSe(string filename)

trys to load your “Cancel” sound effect from your sound effect dicitonary “_seCache” and failed.

I inspected your “public static void Initialize()” method of your SoundManager and saw that you didn’t add the sound effects to your dictionary before as you do this with your Song files afterwards. I also wonder why your “Sound Effect Loading Method” is different from your “Song Loading Method”.

I would suggest to load your Sound Effects the same way you are loading your Songs (in a dictionary).

I moved the _seCache initialization to the Initialize method, now the Release version works on my main pc, but the principal issue is still occurring, everytime I call _contentManager.Load<Song>("sounds/bgm/" + filename) the game crashes raising an InstancePlayLimitException even when I never play the song.

Edit: I changed all the Song to SoundEffectInstance and when I play it, the exeption is raised. Then I tested with the default sound effects, like this:

_cancelSe = _contentManager.Load<SoundEffect>("sounds/se/Confirm");
_cancelSe.Play();

When the code arrives at Play(), the game throws an InstancePlayLimitException again, and this is the very first sound that is played on the entire game.

Edit 2:
I created a new project, this simple code crashes at _se.Play(); with the same exception:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Sound_Test
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        private SoundEffect _se;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            _se = Content.Load<SoundEffect>("Confirm");
            _se.Play();
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// game-specific content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}

Edit 3: the same code does work on a DirectX project, perhaps the issue is related with OpenGL?

When I create a new DesktopGL project (MonoGame 3.6) and try to do the same like you, then everything works without a problem.

Please try the following and tell me if this worked for you:

Create a new bool in Game1.cs -> bool SoundPlayed = false;
Create a new SoundEffectInstance in Game1.cs -> SoundEffectInstance TestInstance;

Then in your LoadContent():

  1. TestInstance = _se.CreateInstance();
  2. Delete ‘_se.Play();’

Then in your Update();

if (!SoundPlayed) { SoundPlayed = true; TestInstance.Play(); }

See if it works. When this does not work, then something on your machine / project / monogame installation maybe corrupted. This is at least my opinion, because on my machine and fresh monogame 3.6 setup this solution is working without problems.

An unhandled exception of type ‘Microsoft.Xna.Framework.Audio.InstancePlayLimitException’ occurred in MonoGame.Framework.dll

On the line TestInstance.Play();

When this does not work, then something on your machine / project / monogame installation maybe corrupted.

I don’t think so, this errors happens on players computers and I just installed MonoGame 3.6 here. Remembering that this issue doesn’t happen on every computer, it works on my main computer but not on this one. The MG 3.5 audio was working on all the computers I’ve tested.

You said that your project just failed to start on some computers. Do you know if its OS related? I mean if it fails to start on specific operating systems.

You said you tested it by yourself on two different machines and only one of which is able to start the project. Could you tell us a bit more about this machines?

In the meantime you could try to put the code I posted in a try{}catch{} block. Normally the project should run and enter the catch if the InstancePlayLimitException occured. You would also get a lot of spam in your output log containing the exception information.

It’s maybe worth to open an issue at the official monogame repo. Nevertheless I wasn’t able to reproduce this error so far. Your LudumDare38 project is also running fine on my machines.