7

我想使用 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);
}

但是这种方法听起来像一团糟(听起来是这样的)。如果我尝试为和弦中的每个音符创建新的 AudioContexts,那么听起来不错(像这样):

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

但我读到你应该只有一个 AudioContext。我究竟做错了什么?

4

2 回答 2

7

不确定这是否是一个解决方案,但我发现插入一个 GainNode 并设置它的值,以便增益总和为 1 消除了这个问题:

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

我在 Chrome 23.0.1271.101 上试过这个

更新为使用新的startstop方法:createOscillator noteOn not working

于 2013-01-17T10:53:41.763 回答
4

noteOn(0)立即启动振荡器/音符。

由于您的 for 循环需要时间来创建振荡器,因此在第一个音符之后的每个音符的开始时间都会稍微延迟。我会初始化每个振荡器,将它们放入一个数组中,然后noteOn()在另一个 for 循环中调用它们中的每一个。

而且你不需要调用setTimeout,这是不可靠的:noteOff将在调用后在一秒钟内执行noteOff(1)

var ac = new (window.AudioContext || window.webkitAudioContext);
// C4, E4, G4
var freqs = [261.63, 329.63, 392.00];
var oscs = [];
// initialize the oscillators
for(var i=0;i<freqs.length;i++) {
    var o = ac.createOscillator();
    o.frequency.value = freqs[i];
    o.connect(ac.destination);
    oscs.push(o);
}
// schedule noteOn and noteOff (deprecated: the methods will be renamed to start() and   stop() soon)
for (i = 0; i < oscs.length; i +=1) {
    oscs[i].noteOn(0);
    oscs[i].noteOff(1);
}
于 2013-01-14T14:04:54.443 回答