WebAudio play sound pops at start and end

javascript html5 audio

405 观看

1回复

104 作者的声誉

Whenever I play a sound using code such as

// binaryData = a wave file from a websocket
let ctx = new AudioContext();
ctx.decodeAudioData(binaryData, function(audioData){
   let source = ctx.createBufferSource();
   source.buffer = audioData;
   source.connect(ctx.destination);
   source.start(0);
});

There is a very audible click or pop between each clip played. Forget the fact that I'm trying to play real-time audio with this system; why is it that there is a glitchy noise at the beginning and end of each sound clip played? I'm not understanding how this is acceptable behaviour in 2017 from an audio playing device... Is there any way to mitigate or eliminate this?


Answer

Following the answer below here is a good set of #s to use to reduce clicking to basically nothing. I'm not saying this works great for a tone, but its flawless for voice.

// start of clip
// clipPlayTime may be 0 or your scheduled play time
gain.setValueAtTime(0.01, clipPlayTime);
gain.exponentialRampToValueAtTime(1, clipPlayTime + 0.001);
// end of clip
gain.setValueAtTime(1, clipPlayTime + clipLength - 0.001);
gain.exponentialRampToValueAtTime(0.01, clipPlayTime + clipLength);

This creates a ramp up and a ramp down.

作者: J Doe. 的来源 发布者: 2017 年 12 月 27 日

回应 1


3

231 作者的声誉

决定

Use a exponentialRampToValueAtTime() to remove (or atleast reduce) the clicking noise.

Here's a great explanation: Web Audio, the ugly click and the human ear


Full Example

Base example taken from: https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/decodeAudioData

<button class="play">Play</button>
<button class="stop">Stop</button>

<script type="text/javascript">
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
var source;
var play = document.querySelector('.play');
var stop = document.querySelector('.stop');
var gainNode = audioCtx.createGain();


function getData() {
    source = audioCtx.createBufferSource();
    var request = new XMLHttpRequest();
    request.open('GET', './sample.wav', true);
    request.responseType = 'arraybuffer';
    request.onload = function() {
        var audioData = request.response;

        audioCtx.decodeAudioData(audioData, function(buffer) {
                source.buffer = buffer;
                source.connect(gainNode);
                gainNode.connect(audioCtx.destination);
                gainNode.gain.setValueAtTime(1, audioCtx.currentTime);
            },

            function(e) {
                console.log("Error with decoding audio data" + e.err);
            });
    }
    request.send();
}


play.onclick = function() {
    getData();
    source.start(0);
    play.setAttribute('disabled', 'disabled');
}

stop.onclick = function() {
    gainNode.gain.setValueAtTime(gainNode.gain.value, audioCtx.currentTime);
    gainNode.gain.exponentialRampToValueAtTime(0.0001, audioCtx.currentTime + 1);
    setTimeout(function() {
        source.stop();
    }, 1000)
    play.removeAttribute('disabled');
}
</script>
作者: Marco 发布者: 2017 年 12 月 27 日
32x32