编辑:找到修复。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 );
}