我遇到了 ScriptProcessorNode 和滞后的问题。即使是在做一个非常简单的过程,只需要样本并执行x %= 0.35
. 为什么这个简单的 ScriptProcessorNode(包括在下面)有这么多延迟?
MDN 没有提及延迟:https ://developer.mozilla.org/en-US/docs/Web/API/ScriptProcessorNode
另外,我知道 ScriptProcessorNode 很快就会被弃用,但 audioWorklets 还没有实现,所以这是最好的。
var baseFreq = 220;
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
var osc = audioCtx.createOscillator();
osc.type = 'sine';
osc.frequency.value = baseFreq;
osc.start();
var intervals = [1, 1.125, 1.25, 1.5, 1.6666666, 1.875, 2, 4]
var index = 0;
function newTone() {
index++;
index %= intervals.length;
osc.frequency.value = intervals[index] * baseFreq;
}
var modulus = audioCtx.createScriptProcessor();
modulus.onaudioprocess = function(audioProcessingEvent) {
var inputBuffer = audioProcessingEvent.inputBuffer;
var outputBuffer = audioProcessingEvent.outputBuffer;
for (var channel = 0; channel < outputBuffer.numberOfChannels; channel++) {
var inputData = inputBuffer.getChannelData(channel);
var outputData = outputBuffer.getChannelData(channel);
for (var sample = 0; sample < inputBuffer.length; sample++) {
outputData[sample] = inputData[sample] % moduAmount;
}
}
}
var moduLow = 0.35;
var moduHigh = 2;
var moduAmount = moduLow;
function turnModulusOnOff() {
if (moduAmount == moduLow)
moduAmount = moduHigh;
else
moduAmount = moduLow;
}
var gain = audioCtx.createGain();
gain.gain.value = 0.05;
gain.connect(audioCtx.destination);
modulus.connect(gain)
osc.connect(modulus);
osc.connect(gain);
document.body.addEventListener("keydown", newTone);
html,
body {
height: 100%;
width: 100%;
font-family: arial;
}
<button onclick="newTone()">Next Tone</button>
<button onclick="turnModulusOnOff()">Mute/Unmute Modulus</button>
<br>
To test, click anywhere and then press any key to change the tone. Notice when Modulus is muted how responsive the tone change is. Notice the lag between the sine frequency change and the modulus effect.
<br>
<b>For Extra Fun: Go crazy on your keyboard</b>