I would like to play a chord using OscillatorNodes:
var ac = new (window.AudioContext || window.webkitAudioContext);
// C4, E4, G4
var freqs = [261.63, 329.63, 392.00];
for(var i=0;i<freqs.length;i++) {
var o = ac.createOscillator();
o.frequency.value = freqs[i];
o.connect(ac.destination);
o.noteOn(0);
setTimeout(function() {o.noteOff(0)}, 1000);
}
But this approach sounds like a mess (here's what it sounds like). If I try creating new AudioContexts for each note in the chord, then it sounds fine (like this):
// C4, E4, G4
var freqs = [261.63, 329.63, 392.00];
for(var i=0;i<freqs.length;i++) {
var ac = new (window.AudioContext || window.webkitAudioContext);
var o = ac.createOscillator();
o.frequency.value = freqs[i];
o.connect(ac.destination);
o.noteOn(0);
setTimeout(function() {o.noteOff(0)}, 1000);
}
But I read that you're only supposed to have one AudioContext. What am I doing wrong?
Not sure this can be a solution, but I found out inserting a GainNode and setting it's value so that the gain will sum to 1 eliminates the issue:
var ac = new (window.AudioContext || window.webkitAudioContext);
// C4, E4, G4
var freqs = [261.63, 329.63, 392.00];
for(var i=0;i<freqs.length;i++) {
var o = ac.createOscillator();
var g = ac.createGainNode();
o.frequency.value = freqs[i];
o.connect(g);
g.gain.value = 1/freqs.length;
g.connect(ac.destination);
o.start(0);
setTimeout(function(s) {s.stop(0)}, 1000, o);
}
I tried this on Chrome 23.0.1271.101
Updated to use the new start
and stop
methods: createOscillator noteOn not working