exponentialRampToValueAtTime不能防止Firefox破裂

时间:2018-10-23 15:53:55

标签: javascript firefox html5-audio

当我播放一个音调然后将其停止时,会听到不愉快的“裂纹”,以及开始和结束。我搜索了一个解决方案,发现随着时间的推移减小音量可以解决该问题。

因此,我使用AudioGainMode上下倾斜,而不是突然剪切音频:

controlGain.gain.exponentialRampToValueAtTime(
    1,
    gAudioCtx.currentTime+time_milliseconds/1000
 );
// and later...
controlGain.gain.exponentialRampToValueAtTime(
    0.0001,
    gAudioCtx.currentTime+time_milliseconds/1000
 );

因为没有在0上定义指数函数,所以使用0.0001

但是,在Firefox中,我仍然可以听到讨厌的声音。我还注意到,使用更长的延迟没有效果-增益会立即达到目标值。

function sleep(ms) {
    return new Promise(function (resolve, reject) {
        setTimeout(resolve, ms);
    });
}
function play() {
const AUDIO_RAMP_DELAY = 50;


var gAudioCtx = new AudioContext();
const controlGain = gAudioCtx.createGain();
controlGain.gain.value = 0.00001;
/// Full volume at t+50ms
controlGain.gain.exponentialRampToValueAtTime(
    1,
    gAudioCtx.currentTime+AUDIO_RAMP_DELAY/1000
 );
controlGain.connect(gAudioCtx.destination);

var osc = gAudioCtx.createOscillator();


// create a tone around 440hz
const length = 1024;
var real = new Float32Array(length);
var imag = new Float32Array(length);
real[440]=1;
//real[512]=1;
var wave = gAudioCtx.createPeriodicWave(real, imag, {disableNormalization: true});
osc.frequency.value = 1;
osc.setPeriodicWave(wave);
osc.connect(controlGain);
osc.start();

(async function() {
    await sleep(AUDIO_RAMP_DELAY+1);
    // now we're at full volume, wait another 2 seconds
    await sleep(2000);
    controlGain.gain.exponentialRampToValueAtTime(
        0.00001,
        gAudioCtx.currentTime+50/1000
    );
    await sleep(2000);
    osc.stop();
    document.querySelector("button").disabled = false;
})();
}
<h2>Warning: this demo makes loud sounds!</h2>
<button onclick="play(); this.disabled=true">Click to play</button>

如何使其也可以在Firefox中使用?

1 个答案:

答案 0 :(得分:0)

我也注意到exponentialRampToValueAtTime()似乎在Firefox中无法正常工作。对我来说,这似乎是一个错误的实现。

一种解决方法是改为使用linearRampToValueAtTime

或者,您也可以使用setValueCurveAtTime定义自己的曲线。