繁体   English   中英

Web 音频 API:为什么只能启动一次source?

[英]Web Audio API: Why can you only start sources once?

假设您使用 Web Audio API 播放纯音:

ctx = new AudioContext();
src = ctx.createOscillator();
src.frequency = 261.63; //Play middle C
src.connect(ctx.destination);
src.start();

但是,稍后您决定要停止声音:

src.stop();

从这一点开始, src现在完全没用了; 如果您尝试再次启动它,您会得到:

src.start()
VM564:1 Uncaught DOMException: Failed to execute 'start' on 'AudioScheduledSourceNode': cannot call start more than once.
    at <anonymous>:1:5

例如,如果您正在制作一个小型在线键盘,那么您会不断地打开和关闭音符。 从音频节点图中删除旧的 object 似乎真的很笨重,创建一个全新的 object,然后将其connect()到图中,(然后丢弃 object,稍后打开它会更简单)需要的时候。

Web Audio API 这样做有什么重要原因吗? 还是有一些更干净的方法来重新启动音频源?

这正是网络音频 api 的工作方式。 声音发生器节点(如振荡器节点和音频缓冲源节点)旨在使用一次。 每次你想玩你的振荡器时,你必须创建它并设置它,就像你说的那样。 我知道这看起来很麻烦,但您可以将其抽象为一个play()方法,为您处理这些细节,因此您不必每次玩振荡器时都考虑它。 另外,不要担心创建这么多节点对性能的影响。 网络音频 api 旨在以这种方式使用。

如果您只想在互联网上制作音乐,并且对学习网络音频 api 的来龙去脉不感兴趣,您可能有兴趣使用我编写的库来简化此类操作: https:/ /github.com/rserota/wad

我正在开发一个 12 语音和弦合成器,每个语音 2 振荡器。

我现在从不停止 Osc。 我断开了 Osc 的连接。 你可以通过setTimeout做到这一点。 对于这组 Osc,从放大器 Enveloop 中取出最长的释音阶段(2 个中的 1 个)。 减去AudioContext.currentTime() ,乘以 1000 ( setTimeout使用毫秒,网络音频使用秒。)

使用connect()disconnect() 然后,您可以更改任何AudioNode的值以更改声音。

(该按钮是因为AudioContext需要用户操作才能在 Snippet 中运行。)

 play = () => { d.addEventListener('mouseover',()=>src.connect(ctx.destination)); d.addEventListener('mouseout',()=>src.disconnect(ctx.destination)); ctx = new AudioContext(); src = ctx.createOscillator(); src.frequency = 261.63; //Play middle C src.start(); }
 div { height:32px; width:32px; background-color:red } div:hover { background-color:green }
 <button onclick='play();this.disabled=true;'>play</button> <div id='d'></div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM