【问题标题】:AudioBufferSourceNode starts playing only after being connectedAudioBufferSourceNode 连接后才开始播放
【发布时间】:2013-02-01 06:22:20
【问题描述】:

在我的对象中,我有一个 AudioBufferSourceNode 对象 (this.bSrc),它连接到一个增益节点 (this.audioDestination),该节点播放已存储在对象 (this.audioBuffer) 中的(有效)AudioBuffer

如果this.audioDestination 连接到音频上下文最终目的地this.mainContext.destination 并且我在我的AudioBufferSourceNode 对象(this.bSrc) 上调用start(0) 方法,它将正常播放。

相反,如果this.audioDestination尚未连接到音频上下文最终目的地,则缓冲区将不会播放(这没关系),但其播放将延迟到连接完成制作(因此使任何关于 AudioBufferSourceNode 何时结束播放的假设无效)。

我目前正在实现一个插件架构,其中每个插件都有其 audioDestination 增益节点,并且不(也不能)知道它是否间接连接到最终的音频上下文目标。在我看来合乎逻辑的是 AudioBufferSourceNode 应该立即“播放”并完成,即使它没有连接到最终的音频上下文目标。但它似乎不像这样工作。我是对的还是我弄错了?有什么方法可以改变这种行为吗?

代码:

/* Create the audio Context. */
this.mainContext = new webkitAudioContext;

/* Create an audio gain node */
this.audioDestination = this.mainContext.createGainNode();

/* [...] An AudioBuffer gets decoded and stored into this.audioBuffer*/

/* Create an AudioBufferSourceNode and try to play it immediately */
this.bSrc = this.audioContext.createBufferSource();
this.bSrc.connect (this.audioDestination);
this.bSrc.buffer = this.audioBuffer;
this.bSrc.start(0);

/* Create a callback for when the AudioBufferSourceNode finishes playing */
if (!this.bSrc.loop) {
       var pbTimer = setTimeout(function() {
            this.playFinishedCallback();
        }.bind(this), this.audioBuffer.duration * 1000 / this.bSrc.playbackRate.value);
    }

 /* Connect this.audioDestination to the final AudioContext destination */
 /* If this statement is executed after the previous ones, playback will start NOW */
 this.audioDestination.connect(this.mainContext.destination);

【问题讨论】:

    标签: javascript html web-audio-api


    【解决方案1】:

    这是当前在 Chrome 中实现 Web Audio API 的方式,以及其中使用的设计。有人说要改变它;实际上,我是您描述的“音频电缆模型”的支持者。 :) 不过,这不是唯一理智的模型。在当前的实现中没有任何方法可以改变这种行为。

    但是,有一个简单的解决方法 - 只需保持一个归零的增益节点连接到 context.destination,然后将所有 ABSN 连接到该节点以及它们(最终)连接到 context.destination。

    【讨论】:

    • 是的,想想我以前见过类似的模型。我认为 context.destination 是“拉”数据的那个,所以如果节点没有连接到连接图中的目标,则不会被询问任何内容。优点是,例如,任何密集的 ScriptNode 在连接之前都不会占用 CPU,缺点是模型不能很好地适应典型的音频环境。不过,该解决方法似乎合乎逻辑(至少从编程的角度来看)并且易于实施。谢谢!
    • 顺便说一句,你是克里斯·威尔逊!感谢您对 html5rocks 的贡献,您的 Web Audio Playground 是我当前项目(基于 Web 音频 api 构建的音频插件主机)的灵感来源。很高兴认识你。
    【解决方案2】:

    这是有道理的。将 context.destination 视为标准输出。如果没有连接到 context.destination,音频就无处可去。如果您将最后一行(连接到 context.destination)移动到刚刚创建增益节点之后,我认为您不会有延迟。

    【讨论】:

    • 这是您的猜测,还是您有证据表明 Web Audio API 是这样设计的?对我来说,这没什么意义。将连接视为电缆,将音频节点视为乐器/效果,将上下文目标视为一对扬声器。如果您断开从乐器(例如音乐键盘)到扬声器的电缆,当您按下琴键时乐器实际上会“播放”(尽管您听不到任何声音),它不会等待电缆连接连接以播放您一次按下的所有键。仪器的行为不像 Unix 管道。
    • 我没有意识到它实际上延迟了播放的开始。这有点奇怪,似乎您仍然可以通过在尝试玩之前连接到您的目的地来解决它。
    猜你喜欢
    • 2012-03-15
    • 2022-01-21
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    相关资源
    最近更新 更多