Perhaps I just don’t understand what is happening here (if it is intentional or some such), but I can’t seem to figure out why sounds’ Pause function breaks down if you fire .Pause() and .Stop() on them (if the sound was playing). Doing so disables the .Pause() function from then on.
Source code to reproduce this below. Super simple, just load a sound effect with a decent play length and press enter. I would expect the sound to stop, but it doesn’t. This is just a demo of the problem, but it’s causing quite a bit of grief in our new game (after porting to OpenGL and MonoGame 3.8 - DX didn’t seem to do this).
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
namespace SoundTest
{
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
KeyboardState prevKeyboardState, keyboardState;
SoundEffectInstance soundInstance;
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
soundInstance = Content.Load<SoundEffect>("sound").CreateInstance();
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Enter) && !prevKeyboardState.IsKeyDown(Keys.Enter))
{
soundInstance.Play();
soundInstance.Pause();
soundInstance.Stop();
soundInstance.Play();
soundInstance.Pause();
// !! if the sound is playing, once Pause then Stop (right after each other) are fired on the sound, Pause will never work again
}
if (keyboardState.IsKeyDown(Keys.Q) && !prevKeyboardState.IsKeyDown(Keys.Q))
soundInstance.Play();
if (keyboardState.IsKeyDown(Keys.W) && !prevKeyboardState.IsKeyDown(Keys.W))
soundInstance.Pause();
if (keyboardState.IsKeyDown(Keys.E) && !prevKeyboardState.IsKeyDown(Keys.E))
soundInstance.Stop();
if (keyboardState.IsKeyDown(Keys.R) && !prevKeyboardState.IsKeyDown(Keys.R))
soundInstance.Resume();
prevKeyboardState = keyboardState;
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
}
}
}
When looking for others having this problem, I found several posts from back in 2017, some of which seem to be showing the same results as me, but no solutions or even really any other investigation from there.
Any insight here would be awesome. I need the sounds to continue where they left off the next time they’re resumed, so firing .Stop() is not an option.
Only guess is if it has something to do with the pauseCounter variable. Not even sure what that would be good for anyway to be honest, but I couldn’t get MonoGame source to build so I couldn’t test that deep. As a side note: Does anyone have a use-case for why you’d want to have to .Resume() X number of times as you fired .Pause() for it to Pause/Resume successfully anyhow?
Update
Github issue (created by someone else a couple hours before I created this thread lol what are the chances): https://github.com/MonoGame/MonoGame/issues/7372
This is an issue because sometimes we need to restart a sound instance (and sometimes its playing, sometimes its paused - thus the Pause/Stop/Play scenario).
A simple, albeit janky, solution to this problem appears to be just firing .Play() before any call to .Stop()