你可以同步/绑定一个OscillatorNode的频率吗?

时间:2017-10-06 05:35:40

标签: javascript audio web-audio web-audio-api

所以,我正在使用Web Audio API创建两个oscillators

let audioCtx = new (window.AudioContext || window.webkitAudioContext)();

let o1 = audioCtx.createOscillator();
o1.type = "sawtooth";
o1.frequency.value = 220;
o1.connect(audioCtx.destination);
o1.start();

let o2 = audioCtx.createOscillator();
o2.type = "square";
o2.frequency.value = o1.frequency.value;
o2.connect(audioCtx.destination);
o2.start();

o1.frequency.setValueAtTime(392, audioCtx.currentTime + 3);

如您所见,我使用第一个振荡器的频率来设置第二个振荡器的频率。这是因为我想将这些振荡器的声音有效地结合在一起。我在3秒后更改了第一个振荡器的频率,但正如您所听到的那样,第二个振荡器的频率也没有更新。

Web Audio API提供了一个我可以订阅的事件(例如onfrequencychange)或其他什么东西,只要第一个振荡器发生变化,我就可以自动更新第二个振荡器的频率?也许某种绑定/连接方式  OscillatorNode.frequency(这是AudioParam)?

当然,我可以这样做:

o1.frequency.setValueAtTime(392, audioCtx.currentTime + 3);
o2.frequency.setValueAtTime(392, audioCtx.currentTime + 3);

...但是为了这个问题,让我们假设在我更新第一个振荡器的频率时,我的应用程序丢失了对第二个振荡器的引用。

基本上,我试图让两个振荡器表现为一个。

1 个答案:

答案 0 :(得分:2)

为什么你想要两个具有完全相同频率的振荡器,但实现这一点的一种方法并不是很清楚:

let s = new ConstantSourceNode(audioCtx, {offset: 220});
s.connect(o1.frequency);
s.connect(o2.frequency);
s.start();
...
s.offset.setValueAtTime(392, audioCtx.currentTime + 3);

因此s控制两个振荡器的频率。

并且没有onfrequencychange事件。当你可以自动化频率以改变每个样本帧时,如果你使用linearRampToValueAtTime或其他自动化会发生什么,那会怎样呢?