编辑:找到了修复程序。我在线前缺少g.gain.setValueAtTime(0,now);
将攻击斜坡设置在下方。添加后g.gain.value = 0;
也是多余的。
所以我有一个奇怪的问题。让我给出一些背景知识:我正在实现一个复音合成器,其中音符以一种一次性的方式创建和播放 - 每次触发一个键时都会创建一个新的振荡器。
我首先在全球范围内实现了音量信封,但是当新音符被触发时,结果就是过去音符的衰减/释放,但是单声道地,攻击,衰减和释放信封都按预期工作。
所以我的解决方法是在触发按键时即时创建振荡器和信封。这很好地解决了一点奇怪之处:衰变和释放都像以前一样工作,唯一包围音符音量的好处,但是攻击包络不会线性上升。相反,它会延迟指定任何攻击时间并立即全部射击。
任何人都可以看到为什么攻击范围会延迟并立即采取行动,而不是像线程那样线性地修改增益?
以下是相关功能:
synth.prototype.playNote = function(i, freq) {
// create oscillator
var o = this.context.createOscillator();
o.frequency.value = freq * Math.pow( 2, this.osc[i].oct-4 );
o.type = this.osc[i].type; o.start( 0 );
// create envelope node and connect
var g = this.context.createGainNode(); g.gain.value = 0;
o.connect( g ); g.connect( this.master_gain );
// enveloping
now = this.context.currentTime;
// the line below delays for the attack time at 0 gain and
// shoots to volume 1 after (now + this.amp_env.attack) rather than curving linearly
g.gain.linearRampToValueAtTime(1, now + this.amp_env.attack );
g.gain.linearRampToValueAtTime(this.amp_env.decay, now + this.amp_env.attack + this.amp_env.decay + this.amp_env.release );
g.gain.linearRampToValueAtTime(0, now + this.amp_env.attack + this.amp_env.decay + this.amp_env.release );
// kill note after envelopes are done;
o.stop( now + this.amp_env.attack + this.amp_env.release + this.amp_env.release );
}