代码之家  ›  专栏  ›  技术社区  ›  TomáÅ¡ Zato

ExponentialRampToValueAttime无法阻止Firefox中的破解

  •  0
  • TomáÅ¡ Zato  · 技术社区  · 7 年前

    当我演奏一个音调,然后停止它,不愉快的“裂纹”是听到的,开始和结束。我寻找了一个解决方案,发现随着时间的推移减少音量应该可以解决这个问题。

    因此,我使用 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 改为使用。

    然而,在火狐中,我仍然能听到令人讨厌的破解。我还注意到使用更长的延迟没有效果-增益立即达到目标值。

    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 回复  |  直到 7 年前
        1
  •  1
  •   rikner    7 年前

    我也注意到 exponentialRampToValueAtTime() 在Firefox中似乎无法正常工作。我也觉得这是一个不正确的实现。

    解决方法可能是 linearRampToValueAtTime 相反。

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