2

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

0 回答 0