goldfire / howler.js

Javascript audio library for the modern web.
https://howlerjs.com
MIT License
23.94k stars 2.23k forks source link

annoying intermittent pop sound #1209

Open patrick99e99 opened 5 years ago

patrick99e99 commented 5 years ago

I am using howler for a web video game that I created, and every now and then I am extremely upset by hearing my sound effects start with an awful pop sound.

I have captured my system audio to demonstrate what I am talking about: http://collinatorstudios.com/audio/howler-pop-bug.aif

I have a sound sprite defined such as:

    const sprite = new Howl({
      src: [
      'sfx.ogg',
      ],
      sprite: {
        zoom: [
          372000,
          684.3764172335796
        ],
        explode: [
          198000,
          2971.156462585043
        ],
      },
    });

and I'm just alternating between playing these two sounds, each having their own volume.

var explode = sprite.play('explode');
sprite.volume(0.5, explode);

// after a delay..

var zoom = sprite.play('zoom');
sprite.volume(0.05, zoom);

And as you can see/hear in my example, after a few times of playing these two sounds, when the zoom sound is eventually played, there is an obnoxious pop at the beginning of it. I am suspecting perhaps the volume change is being delayed for some reason and the pop is actually an abrupt change from 0.5 to 0.05... Maybe?

StephenTanksley commented 5 years ago

If I were to guess, there's not enough space between the decay of one sound and the beginning of another.

Is there a way to bake in some tiny little fades at the beginnings and ends of your SFX? From an audio standpoint, that should solve your problem.

If you wanted to do that programmatically, you could control the amplification envelope of the sound and set the duration of the fade-in from 0-2 ms and that should take care of it. I'm pretty new to coding audio properties, but the audio itself is something I'm familiar with, so let me know if that works.

patrick99e99 commented 5 years ago

@StephenTanksley if that were the case then this would be happening all the time. It's an intermittent problem. Also, my sprite has 1s gaps between each sound...

StephenTanksley commented 5 years ago

Hm. If you're fading all the way down to 0.0 dB between each sound, then it's probably a programmatic issue that I'm not gonna be much help with. : /

Good luck getting it fixed, though!

patrick99e99 commented 5 years ago

@StephenTanksley There is no fade happening. This is simply playing soundA at volume 0.5, and then later playing soundB at volume 0.05.

st-h commented 5 years ago

@patrick99e99 Does this happen with a particular browser?

patrick99e99 commented 5 years ago

@st-h Chrome (76.0.3809.100) is the browser that I use.

monsterkodi commented 4 years ago

I have the same problem in the latest electron version (7.0.1)

But it seems to only occur when I use the distance attenuation via the pannerAttr.

patrick99e99 commented 4 years ago

@monsterkodi, I ended up abandoning sprites as this seems to be a bug with them.. as soon as I switched to individual files the problem no longer occurs.

monsterkodi commented 4 years ago

thanks, @patrick99e99 i didn't use sprites, so I ended up abandoning the distance attenuation ;-)

singfisher commented 1 week ago

@patrick99e99 @monsterkodi, and for anyone else who had this same issue coming across this thread, I was able to fix the issue by building a custom version of Howler that accepts a volume parameter in the play function. My sense is that the issue occurs because node.gain.setValueAtTime(vol, Howler.ctx.currentTime) happens at play, then happens again when you try to set the volume for that sound. But by the time you set the volume, Howler.ctx.currentTime may have increased a little bit, causing a jarring change in volume during playback (the pop). This seems like it is a problem with setting volume on a specific ID in general - you cannot set the volume before calling play because you need to know the id returned by play, but setting it afterwards leads to popping.