WebAudio播放声音在开始和结束时弹出

时间:2017-12-27 17:14:51

标签: javascript html5 audio

每当我使用

等代码播放声音时
// 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);
});

每个播放的剪辑之间都有一个非常可听的咔嗒声或弹出声。忘记我试图用这个系统播放实时音频的事实;为什么在每个声音片段的开头和结尾都有一个小故障噪音?我不明白2017年音频播放设备是如何接受这种行为的......有什么办法可以减轻或消除这种情况?

答案

根据下面的答案,这里有一组很好的#s用来减少点击基本没什么。我并不是说这对音调来说很有用,但它的声音完美无缺。

// 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);

这会产生斜坡上升和斜坡下降。

1 个答案:

答案 0 :(得分:3)

使用exponentialRampToValueAtTime()删除(或至少减少)点击噪音。

这里有一个很好的解释:Web Audio, the ugly click and the human ear

完整示例

基本示例取自: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>