How Can I Avoid This 'clicking' Sound When I Stop Playing A Sound?
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.
- Create your sound source (in my example an oscillator)
- Create a gain node and connect it with the sound source.
- 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
- 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?"