WebAudio播放声音在开始和结束时会出现爆裂声

4
每当我使用代码播放声音时,例如:
// 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年从音频播放设备中是如何被接受的...有没有办法减轻或消除这种情况?
以下是一组很好的#,可以将点击噪声减少到基本上为零。我不是说这对于音调效果很好,但对于语音来说完美无瑕。
// 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个回答

4
使用exponentialRampToValueAtTime()函数可以消除(或减少)噪声。以下链接有很好的解释:Web Audio, the ugly click and the human ear

完整示例

示例来源: https://developer.mozilla.org/zh-CN/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>

更新的文章链接:https://alemangui.github.io/ramp-to-value - Nick Fisher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接