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