Skip to content Skip to sidebar Skip to footer

How Can I Avoid This 'clicking' Sound When I Stop Playing A Sound?

I really hope this question stays a programming question and do not end up an Sound Mechanics question... Here goes... I am doing some experiments in order to figure out how the We

Solution 1:

This is an audio issue, not a programming problem. The click you hear occurs when a waveform is stopped/cut in the middle of a wave, rather than at a zero-crossing.

The best simple solution from a audio paradigm is to very quickly fade-out, instead of just stopping playback.

A slightly more complex solution is to find the next zero-crossing and stop playback at precisely that point.

Solution 2:

There's a brief explanation of why we hear the clicking sound (it's a human ear thing) and good examples of how to get around that using the Web audio API here: http://alemangui.github.io/blog//2015/12/26/ramp-to-value.html

The main takeaway from the article is that the exponential methods to remove the click work better; exponentialRampToValueAtTime and setTargetAtTime.

Using setTargetAtTime to remove the click

var context = newAudioContext();
var oscillator = context.createOscillator();
var gainNode = context.createGain();

oscillator.connect(gainNode);
gainNode.connect(context.destination)
oscillator.start();

stopButton.addEventListener('click', function() {
    gainNode.gain.setTargetAtTime(0, context.currentTime, 0.015);
});

Using exponentialRampToValueAtTime to remove the click

var context = newAudioContext();
var oscillator = context.createOscillator();
var gainNode = context.createGain();

oscillator.connect(gainNode);
gainNode.connect(context.destination)

oscillator.start();

stopButton.addEventListener('click', function() {
    // Important! Setting a scheduled parameter value
    gainNode.gain.setValueAtTime(gainNode.gain.value, context.currentTime); 

    gainNode.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + 0.03);
});

Both of these worked for me in my use case, with exponentialRampToValueAtTime working slightly better. I could still hear a faint click using setTargetAtTime.

Solution 3:

Looks like the Web Audio API gives the developer an easy way of stopping a sound source from playing without abruptly stopping the waveform and avoid any noise and sound artifacts.

  1. Create your sound source (in my example an oscillator)
  2. Create a gain node and connect it with the sound source.
  3. Start the sound source and set the gain value to 0. That way, you won't listen to the sound even if it's technically playing
  4. Set the gain value to 1 when you want the source to play and to 0 when it should not play. The gain node will handle the rest, and no clicking will be heard

var audioContext = new(AudioContext || webkitAudioContext)();

var frequencyOffset = 0// Our sound source is a simple triangle oscillatorvar oscillator = audioContext.createOscillator(); // Create sound source  
oscillator.type = 'triangle';

// Adding a gain node just to lower the volume a bit and to make the// sound less ear-piercing. It will also allow us to mute and replay// our sound on demandvar gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);

gainNode.gain.value = 0;
oscillator.frequency.value = 200;
oscillator.start(0);

functionboop() {
  gainNode.gain.value = 0.1;
  // The sound should last for 250mssetTimeout(function() {
    gainNode.gain.value = 0;
  }, 250);
  oscillator.frequency.value++;
}

setInterval(boop, 500);

Post a Comment for "How Can I Avoid This 'clicking' Sound When I Stop Playing A Sound?"