Skip to content

Howler

Created: 2017-04-25 15:07:09 -0700 Modified: 2019-01-28 11:44:42 -0800

TL;DR: webm with a fallback to mp3

  1. You call “play” on a sound.
  2. The “play” function will check to see if it has an available sound. An available sound is one that is paused or one that is unused from the pool of sounds. If that doesn’t work, it will call “_inactiveSound()” which will create a Sound object.
  3. Making a sound calls its init() function.
  4. init() adds the created sound to the parent’s pool. The pool is really just “_sounds”, which is an array of Sound objects.

The API is basic enough:

howl.pause();

howl.play();

The only thing worth commenting on is that you can’t do “howl.play(spriteId);”, because by passing in a specific spriteId, it’ll always try to play a new sound.

By default, creating a Howl object has “preload” set to true, so all you need to do is make a new Howl to load a sound:

const soundSrc = ["sounds/dozing.webm", "sounds/dozing.mp3"];
const sprite = {"dozing":[0,114755.91836734694]};
const howl = new Howl({
src: soundSrc,
sprite
}); // this kicks off a network request for sounds/dozing.webm on Chrome

If you don’t want to use “preload”, you can set it to false and manually call load.

It seems like doing this is all you need:

howl.seek(0);
howl.stop();
howl.play();

A “Howl” sound only has to be created once, then it can be played back multiple times. Doing so will cause them to overlap. If you then call “stop” on the sound, it will stop all instances of that sound. Incomplete sample code:

this.testSound = new Howl({
src: ['test.wav'],
rate: 0.25
});
this.counter++;
if (this.counter === 4) {
this.testSound.stop();
} else {
this.testSound.play();
}

The reason this happens is that every time you call “play”, a new Sound is added to the pool. When you call “stop”, Howler iterates over its “_sounds” and stops each one.

If you want control over each individual sound, you can use the return value of “play” to get an ID that you can later refer to in “stop”.

Stopping all sounds that are playing

Section titled Stopping all sounds that are playing

It doesn’t look like Howler exposes a global “stop” function. They have an “unload” function, but that will delete all of the sounds from the cache in addition to stopping them. The best way I found to stop all sounds is to keep track of Howl instances myself and call stop() on them with no specific ID.

  1. When a new Howl is constructed, init() is called.
  2. At the bottom of init(), create() is called.
  3. create() potentially calls load() based on whether the parent has _webAudio set to true.

The way that Howler adds the “fade” event is such that it only triggers once before being removed. Stopping a sound may not even be necessary, but here’s the full code that I used when I was testing this:

musicHowl.fade(volume, 0, 250);

musicHowl.on(‘fade’, () => {

musicHowl.stop();

});

// No need to worry about removing the “fade” event now