timetocode

Play same sound multiple times without additional webrequests?

Recommended Posts

Hello there.

What is intended method of playing the same sound multiple times *concurrently* without re-downloading the sound file from the server?

const gunshot = new BABYLON.Sound('foo', "sounds/gun_semi_etc.wav", scene, null, { volume: 1 })

If I have multiple players or bots in my game, any of them can produce gunfire. As each of them shoots, I end up with a separate web request per entity:

image.png.e9eafb7fac217265d9d1afc9a67ffa15.png

I'm accustomed to howler, where the first time a sound is created, like 'foo.wav' it will load it from the server.  Any subsequent sound objects created that play 'foo.wav'  will build themselves from the same sound data without an xhr. How do I accomplish the equivalent?

TY TY :D

Share this post


Link to post
Share on other sites

I use the AssetsManager to load all my sounds, and put them into an array at predictable indexes. This way, I can clone the sounds and attach them to all players.

 

 

 

/////Task
var gunshotSound3 = assetsManager.addBinaryFileTask("soundTask3", "sounds/gs3.ogg");

/////onSuccess callback
gunshotSound3.onSuccess = function (task){
	var gs3 = new BABYLON.Sound("gunshotSound3", task.data, scene, null, { loop: false, autoplay: false, spatialSound: true });
	sounds[2] = gs3;
	gs3.setVolume(0.6);
}

/////Player creation
function player(gunIndex, ..., ..., ...){
///gunIndex = 2;
...
......
...
...


    this.gunSound = sounds[gunIndex].clone("gunSound");
    this.gunSound.attachToMesh(this.mesh);	
}
	
/////Gunshot sound needed
player.gunSound.play();				
			

/////New weapon etc.
player.gunSound.dispose();
player.gunSound = null;
player.gunSound = sounds[x].clone("gunSound");

 

Share this post


Link to post
Share on other sites

Thanks Raggar that looks good!

I wonder if anyone would be interested in having this behavior added to the api. Or maybe just tacked on by including a file. The following is all pseudo code, but I will probably implement it for real on Monday.

Usage:

BABYLON.SoundAtlas.add('filename.ext') // etc for all sounds
BABYLON.SoundAtlas.load(scene, callback) // starts loading

// using a sound from the atlas, while mimicking the original BJS api
const gunshot = BABYLON.Sound.FromAtlas('gunshot', 'filename.ext', scene, { volume: 1 })

 

Possible extension to babylon Sound:

BABYLON.Sound.prototype.FromAtlas = (name, filepath, scene, options) => {
    const cachedSound = BABYLON.SoundAtlas.get(filepath)
    if (!cachedSound) {
        throw new Error('Sound not found in SoundAtlas')
    }

    const sound = cachedSound.clone()
    sound.name = name
    sound.updateOptions(options) // autoplay won't work without some minor modification
}

Presumably would not work with multiple scenes. Everything I've made is all single scene with programmatically spawned meshes, so I'm not sure what would have to change.

Sound atlas:

/* Sound Atlas */
const BABYLON = require('babylonjs')
const basePath = './sounds/' // should be modifiable instead

const sounds = new Map()
const soundFilenames = []

const queueSounds = (assetsManager, scene) => {
    soundFilenames.forEach(soundFilename => {
        const path = `${basePath}`
        const name = `${basePath}${soundFileName}`

        const binaryTask = assetsManager.addBinaryFileTask(name '', path, soundFilename)
        binaryTask.onSuccess = (task) => {
            const sound = new BABYLON.Sound(task.name, task.data, scene, null, {})
            sounds.set(task.name, sound)
        }
    })
}

const add = (soundFilename) => {
    soundFilenames.push(soundFilename)
}


const load = (scene, cb) => {
    const assetsManager = new BABYLON.AssetsManager(scene)
    queueSounds(assetsManager, scene)
    assetsManager.onFinish = () => { cb() }
    assetsManager.onTaskError = (task) => { console.log('error loading task', task) }
    assetsManager.load()
}

module.exports.add = add
module.exports.load = load

Haven't tried it yet, but that's the gist of it.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.