Inconsistent Sound Fade In Tween

Hello,

I’m still trying to understand the best way to play my audio in Phaser.

I have a single audio file that’s a 5 second consistent “bleep” for debugging.

In a preloading scene, I load my audio with:

preloadingScene.load.audio("key", "url");

In a game scene, I play my audio with:

  gameScene.sound.play("key", {volume: 0});

  const currentSound = gameScene.sound.get("key");

  if (currentSound) {
      const tween = gameScene.tweens.add({
          targets: currentSound,
          volume: 1,
          duration: 4000,
          onStart: () => { console.log("audio started");},
          onComplete: () => {console.log("audio complete");},
      });

      currentSound.on("complete", () => {
        tween.stop();
      });
  }

It’s strange since I can run my game and sometimes when the audio starts the audio fade in does work. However out of 10 times I run my game, the fade in fails about 75% of the time and I just hear a consistent “bleep” without any sign of fading in.

When the fade in doesn’t work, I still see my “audio started” and “audio complete” logs appear with the correct timing ("audio started’ is displayed and I can count to 4 until the “audio complete” appears). It’s as if volume variable of the tween is stuck to 1.

  • Is there a some sort of tween reset I’m missing to make sure the tween values are being set correctly?
  • I’ve been seeing a variety of examples of how to play audio. For my two scene environment, is this the best way to handle playing audio?
  • Is there a way to log what the “volume” property is doing during the tween? Perhaps that might give me some clues as to why it appears to be stuck at ‘1’.

Thank you.

You could receive the wrong sound from sound.get(). I would try it like this

const currentSound = gameScene.sound.add('key', { volume: 0 });

currentSound.play();

const tween = gameScene.tweens.add({
  targets: currentSound,
  volume: 1,
  duration: 4000,
  onStart: () => {
    console.log('tween started');
  },
  onComplete: () => {
    console.log('tween complete');
  },
  onUpdate: () => {
    console.log('volume', currentSound.volume);
  },
});

currentSound.on('complete', () => {
  console.log('sound complete');
  currentSound.destroy();
  tween.stop();
});

@samme Thanks for the reply!

I’ve tried your method of moving away from sound.get and just using sound.add.

This continues to work for sound clips without fading. Both methods seem to be retrieving the same key so I don’t think the wrong sound is being retrieved since I only have a single sound in my scene.

Unfortunately, I still run into my issue of lack of audio fading in.

However, your suggestion of using the onUpdate callback has proven to be very useful and has shown that the volume appears to be stuck at a value of 1.

Here’s roughly what the logs look like when I play the audio with a fade:

tween started
volume WebAudioSound.volume: 1
volume WebAudioSound.volume: 1
volume WebAudioSound.volume: 1
volume WebAudioSound.volume: 1
... more of this for the duration of 4 seconds
tween completed

So even though the volume is initially set to 0, the tween immediate sets it to 1 for the duration of the tween.

Question 1:
This is the only tween in my scene. Is there something I need to do to make sure a tween is reset so it actually performs the tween from 0 to 1?

Question 2:
I did have to modify your suggested code a bit:

onUpdate: () => {
    console.log('volume', currentSound.volume);
  },

When I perform the sound.add, the return value assigned to currentSound is a of type BaseSound.
Therefore, I am unable to access currentSound.volume. Instead, I’m logging I update the log to this:

console.log('volume', currentSound);

I see the log of the entire BaseSound object of currentSound from which I can drill into the volume property and view it. Is this expected? Am I not using the correct version of Phaser 3? I’m currently using 3.24.1.

Try

volume: { from: 0, to: 1 }

In Web Audio sound volume changes are scheduled, so it was still 1 when the tween started.

If you’re using TypeScript and BaseSound#volume is missing then that must be an error in Phaser’s definitions.

Amazing!

Putting this in the tween:

volume: { from: 0, to: 1 }

seems to do the trick!

I’m still not sure why this problem doesn’t occur during sound fade outs. With a fade out I can just set volume to 0 in the tween and the fade will perform normally.

This issue only seems to occur during fade ins.

Good to know and thanks again!

For fade outs the volume is already at 1 so the tween’s starting value is correct.

You can see the issue in

const currentSound = gameScene.sound.add('key', { volume: 0 });

console.assert(currentSound.volume === 0);