I have a small problem with audio engine initialization in my game. My frontend audio manager initialization is currently like this (audio manager is my custom wrapper)
// Custom audio manager init
this.audioManager = new AudioManager({
masterVolume: 3.0,
duckingFactor: 0.5,
audioEngine: await CreateAudioEngineAsync(),
scene: this.scene,
assetPath: assetPath,
})
// This next call just has
// this.audioEngine.listener.attach(this.scene.activeCamera)
// await this.audioEngine.unlockAsync()
await this.audioManager.boot()
However, the await calls seem to block any further code execution until the first gesture is provided, and this causes some problems, like rendering of stuff not starting before the gesture.
What I would like to do is this:
Just init audio engine v2 without waiting
Eventually there will be user gesture => start playing sounds/music after that
Not big deal if there are no sounds/music before the gesture
Any advices on what would be the correct way to achieve the above? Ruthlessly pinging @docEdub again
You’ll probably still want to await the call to CreateAudioEngineAsync(), which resolves without a user gesture, but you are correct that the call to audioEngine.unlockAsync() will not resolve until a user gesture occurs. The way it’s handled in the examples is to call the audio init code from an async function that is not awaited, so it doesn’t block the renderer:
var createScene = async function () {
var scene = new BABYLON.Scene(engine);
// Init scene here...
// Init audio with async function that is not awaited so we don't block.
(async () => {
const audioEngine = await BABYLON.CreateAudioEngineAsync();
const gunshot = await BABYLON.CreateSoundAsync("gunshot", "https://playground.babylonjs.com/sounds/gunshot.wav");
// Wait for the audio engine to unlock
await audioEngine.unlockAsync();
gunshot.play();
})();
return scene;
}
So the idea here is to init all the sounds and buses before awaiting audioEngine.unlockAsync, and then call play on them after unlockAsync resolves from a user gesture and unblocks. You can init the sounds after unlockAsync resolves, but there will be more lag time between unlockAsync and play if you do that, and it’s not necessary. The sound can be created just fine before a user gesture, it just can’t be played until after a user gesture.
Sorry for slow reply, doing so much stuff for my game simultaneously…
I pretty much did what you instructed and it seems to work! There is a slight weird thing though; I think the CreateAudioEngineAsync does something with the dom, since I see some “wobblyness” in the UI for a split second. My whole app/game is pretty much in the position absolute/fixed, and there seems to be something happening in the bottom of that div. Do you create some custom elements or something that might effect the dom?
Edit:
Here is an example of the flash, this is bottom of the browser screen, happened after page refresh: