Play a music just after another without delay

Hello everyone :slight_smile:

I have a theme with an intro and a loopable part that I decomposed intro 2 differents OGG file, and I would like to play the intro part then, when the intro is finished, I would like to play the loopable part without any delay.

I’ve already did some searches, and I found 2 things:

  • MP3 are bad for looping
  • There is always a delay when we loop a music using MediaManager

So, it seems wrong, but I use SoundEffect for my musics, and I can loop them seamlessly thanks to SoundEffectInstance.

But if I try to play a music just after another one, there is still a little delay (tested on Windows and Android, the behaviour is the same).

Here is what I do:

SoundEffectInstance intro;
SoundEffectInstance loop;

private void PlayMusic()
{
  intro.Play();
}

// Called every frame
private void Update()
{
  if (intro.State == SoundState.Stopped)
      loop.Play();
}

I think that when the SoundState is set to Stopped for the intro part, it’s already too late, but I don’t really know how I can fix that :confused:

The SoundEffectInstance is pretty simple, it doesn’t seem to be possible to get the current progress.

Did you already encounter thie issue? Do you have any idea to fix it?

Thanks a lot in advance :slight_smile:

Note: I use MonoGame 3.6.

I’m don’t really proud of it, but I found a working solution using a custom progress variable:

SoundEffect intro;
SoundEffect loop;
SoundEffectInstance introInstance;
SoundEffectInstance loopInstance;

enum MusicState { None, Intro, Loop };
MusicState currentState;

private void LoadContent()
{
  intro = content.Load<SoundEffect>("Audio/BGM/intro");
  loop = content.Load<SoundEffect>("Audio/BGM/loop");

  introInstance = intro.CreateInstance();
  loopInstance = loop.CreateInstance();
  currentState = MusicState.None;
}

private void PlayMusic()
{
  intro.Play();
  introProgress = TimeSpan.Zero;
  currentState = MusicState.Intro;
}

// Called every frame
private void Update(GameTime gameTime)
{
  if (currentState == MusicState.Intro)
  {
    introProgress += gameTime.ElapsedGameTime;

    if (introProgress.TotalMilliseconds >= intro.Duration.TotalMilliseconds * 0.97f)
    {
        loop.Play();
        currentState = MusicState.Loop;
    }
  }
}

I don’t know if waiting 97% of the total duration is enough for all musics, but it works as expected for my case.

1 Like