Web Audio API:为什么只能启动一次源?

问题描述 投票:0回答:3

假设您使用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

如果您正在制作一个小型在线键盘,您就会不断地打开和关闭音符。从音频节点图中删除旧对象,创建一个全新的对象,并将其

connect()
放入图中(然后稍后丢弃该对象)似乎非常笨重,而只需打开和关闭它会更简单当需要时。

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

javascript web audio
3个回答
1
投票

使用

connect()
disconnect()
。然后,您可以更改任意
AudioNode
的值来更改声音。

(该按钮是因为

AudioContext
需要用户操作才能在代码片段中运行。)

play = () => {
d.addEventListener('mouseover',()=>src.connect(ctx.destination));
d.addEventListener('mouseout',()=>src.disconnect(ctx.destination));
ctx = new AudioContext();
src = ctx.createOscillator();
src.frequency.value = 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>


0
投票

这正是网络音频 API 的工作原理。声音生成器节点(例如振荡器节点和音频缓冲区源节点)旨在一次性使用。每次您想要播放振荡器时,您都必须创建它并设置它,就像您所说的那样。我知道这看起来很麻烦,但是您可以将其抽象为一个

play()
方法来为您处理这些细节,这样您就不必每次玩振荡器时都考虑它。另外,不必担心创建这么多节点对性能的影响。网络音频 api 旨在以这种方式使用。

如果您只是想在互联网上制作音乐,并且对学习网络音频 api 的细节不那么感兴趣,您可能有兴趣使用我编写的一个库,它可以让事情变得更容易:https ://github.com/rserota/wad


0
投票

我正在开发一个 12 音色和弦合成器,每个音色有 2 个 Osc。

我现在再也不会停止 Osc 了。我断开了 Osc 的连接。您可以通过

setTimeout
来做到这一点。目前,从这组 Osc 的放大器包络中选取最长的释放阶段(第 1 阶段,共 2 阶段)。减去
AudioContext.currentTime()
,乘以 1000(
setTimeout
适用于毫秒,网络音频适用于秒。)

© www.soinside.com 2019 - 2024. All rights reserved.