Luke Horvat
Luke Horvat

Reputation: 337

Can you sync/bind one OscillatorNode's frequency with another?

So, I am creating two oscillators using the Web Audio API:

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);

As you can see, I use the first oscillator's frequency to set the frequency of the second oscillator. This is because I would like to effectively combine the sound of these oscillators together. I change the frequency of the first oscillator 3 seconds later, but as you can hear, the frequency of the second is not updated as well.

So does the Web Audio API provide an event that I can subscribe to (e.g. onfrequencychange) or something else that will allow me to auto-update the frequency of the second oscillator whenever the first one is changed? Maybe some way of binding/connecting to OscillatorNode.frequency (which is an AudioParam)?

Sure, I could do this:

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

...but for the sake of this question, let's assume that at the point when I'm updating the first oscillator's frequency, my application has lost a reference to the second oscillator.

Essentially, I'm trying to make the two oscillators behave as one.

Upvotes: 2

Views: 319

Answers (1)

Raymond Toy
Raymond Toy

Reputation: 6048

It's not really clear why you want two oscillators with exactly the same frequency, but one way to achieve that:

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

Thus s controls the frequency of both oscillators.

And there's no onfrequencychange event. How would that work when you can automate the frequency such that it changes every sample frame, like what happens if you use a linearRampToValueAtTime or other automation?

Upvotes: 3

Related Questions