![](/img/trans.png)
[英]Web audio API, problem using the panNode, the sounds only play once
[英]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.