【问题标题】:Audio API setValueCurveAtTime() Firefox音频 API setValueCurveAtTime() Firefox
【发布时间】:2016-08-29 21:20:47
【问题描述】:

我正在加载一个带有 XMLHttpRequest 的音乐文件,我使用它进行解码 audioCtx.decodeAudioData(response).

完成后,我创建一个AudioBufferSourceNode,通过gainNode 连接到audioCtx.destination

之后,我希望轨道开始缓慢,并使用 setValueCurveAtTime 将速度提高到 2 倍: source.playbackRate.setValueCurveAtTime(new Float32Array([0, 2]), audioCtx.currentTime, 3);

我希望曲目的播放速率从 0 开始,然后在 3 秒内增加到 2。这在 Chrome 中完美运行。但在 Firefox 中,曲目以 1 的播放率开始,3 秒后立即切换到 2。所以没有过渡。

请注意,这是与 Web Audio API Firefox setValueCurveAtTime() 不同的问题

代码:

let audioCtx = new AudioContext();
let url  ='http://mdn.github.io/decode-audio-data/viper.ogg';

loadBuffer(url);

function loadBuffer(url) {
    console.log('loading buffer...');

    let request = new XMLHttpRequest();

    request.open('GET', url, true);
    request.responseType = 'arraybuffer';

    request.addEventListener('load', (e) => {
        decodeAudioData(e.target.response);
    });

    request.send();
}

function decodeAudioData(response) {;
    audioCtx.decodeAudioData(response).then((decodedBuffer) => {
        console.log(`Decoding audio done`);

        let source = audioCtx.createBufferSource();
        source.buffer = decodedBuffer;

        let gainNode = audioCtx.createGain();
        source.connect(gainNode);
        gainNode.connect(audioCtx.destination);

        source.start(0);
        source.playbackRate.setValueCurveAtTime(new Float32Array([0, 2]), audioCtx.currentTime, 3);
    });
}

Demo

当我替换这一行时也会发生同样的情况:

source.playbackRate.setValueCurveAtTime(new Float32Array([0, 2]), audioCtx.currentTime, 3);

有了这个:

source.playbackRate.value = 1;
source.playbackRate.linearRampToValueAtTime(2, audioCtx.currentTime + 3);

【问题讨论】:

    标签: javascript firefox web-audio-api


    【解决方案1】:

    一些较旧的 Web Audio API 实现在遍历曲线值时使用最近邻而不是线性插值。 linearRampToValueAtTime 需要两个点,在这两个点之间可以计算当前值:

    source.playbackRate.linearRampToValueAtTime(1, audioCtx.currentTime);
    source.playbackRate.linearRampToValueAtTime(2, audioCtx.currentTime + 3);
    

    为了简化操作,您可以改用setTargetAtTime,使用它您可以定义过渡时间常数,而不必添加斜坡点:

    source.playbackRate.setTargetAtTime(2, audioCtx.currentTime, 3); // To 2, now, over 3 secs.
    

    【讨论】:

    • 对于 0 的播放率,这应该模拟暂停,就像在 Chrome 中一样。对于较旧的实现:'Chrome 46.0.2490 使用线性插值;早期版本使用最近邻(MDN)所以我猜 Firefox 也使用早期版本?
    • @Pimmol 是的,这是我的假设。
    猜你喜欢
    • 1970-01-01
    • 2015-02-10
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    相关资源
    最近更新 更多