Web オーディオ API を使用して、いくつかのエフェクトを備えた fm シンセを構築しています。すべてが正常に機能しますが、オーディオにかなりの不具合があり、フリーズして途切れ始めます。これは、ブラウザーがすべてのオーディオ情報を一度に処理する能力を持っていないためだと思います。
ノートが再生されるたびに多くのオーディオ ノードがオーディオ コンテキストに追加されるので、未使用のノードがオーディオ コンテキストを遅くするかどうか疑問に思っています。
私のコード:
play = function(s, p) {
//setup
var now = AudioContext.currentTime;
var osc1 = AudioContext.createOscillator(),
osc2 = AudioContext.createOscillator(),
osc3 = AudioContext.createOscillator(),
osc4 = AudioContext.createOscillator(),
gain1 = AudioContext.createGain(),
gain2 = AudioContext.createGain(),
gain3 = AudioContext.createGain(),
gain4 = AudioContext.createGain(),
filter = new tuna.Filter(),
phaser = new tuna.Chorus();
convolver = new tuna.Convolver();
var pitch = p
osc1.type = 'sine';
osc2.type = 'square';
osc3.type = 'triangle';
osc4.type = 'sine';
osc1.frequency.value = pitch * 1.5
osc2.frequency.value = pitch * 8
osc3.frequency.value = pitch
osc4.frequency.value = pitch/2
gain1.gain.setValueAtTime(0,now)
gain2.gain.setValueAtTime(0,now)
gain3.gain.setValueAtTime(0,now)
gain4.gain.setValueAtTime(0,now)
gain1.gain.linearRampToValueAtTime(s[1].value * 1500,now + s[4].value)
gain2.gain.linearRampToValueAtTime(s[0].value * 1500,now + s[4].value)
gain3.gain.linearRampToValueAtTime(1,now + s[4].value)
gain4.gain.linearRampToValueAtTime(s[1].value/2,now + s[4].value)
gain1.gain.linearRampToValueAtTime(0,now + s[4].value + s[5].value)
gain2.gain.linearRampToValueAtTime(0,now + s[4].value + s[5].value)
gain3.gain.linearRampToValueAtTime(0,now + s[4].value + s[5].value)
gain4.gain.linearRampToValueAtTime(0,now + s[4].value + s[5].value)
filter.frequency = s[2].value * 2200
filter.Q = s[0].value * 10
convolver.wetLevel = s[3].value/10
phaser.rate = s[3].value/10
osc3.frequency.value = pitch * 0.666
osc1.connect(gain1);
osc2.connect(gain2);
osc3.connect(gain3);
osc4.connect(gain4);
gain1.connect(osc2.frequency);
gain2.connect(osc3.frequency);
gain3.connect(filter.input);
gain4.connect(filter.input)
filter.output.connect(convolver.input);
convolver.output.connect(phaser.input);
phaser.output.connect(AudioContext.destination);
osc1.start();
osc2.start();
osc3.start();
osc4.start();
setTimeout(function(){
osc1.stop();
osc2.stop();
osc3.stop();
osc4.stop();
}, (s[4].value+s[5].value)*1000)
}
play([0.4, 0.4, 0.4, 0.4, 0.4],440);
非常に醜いように見えますが、サウンドを再生する別の方法が思い浮かびません。
tuna js を使用してコーラス、リバーブ、フィルターを作成しています。
さらに、JavaScript を低レベルで最適化する方法に関する情報があれば幸いです。