如果在过滤器同时被信封调制的过程中,如果在攻击或释放期间截断频率或包络调制量发生变化,我将暂停如何处理更新过滤器. That code is located around here.目前的实现没有回应模拟合成器的方式,但我不太清楚如何计算它.
在实际合成器上,滤波器根据频率截止,包络调制量和信封中的当前级确定立即改变,但斜坡上升或下降也可以顺利延续.
我如何模拟这种行为?
解决方法
您不需要总结自己的这些 – Web Audio AudioParams总结其输入,因此,如果您有潜在的音频调制源,如LFO(连接到GainNode的OscillatorNode),则只需将其连接到AudioParam即可.
这是关键 – AudioParams能够连接()编辑到 – 并且与节点或AudioParam的多个输入连接相加.所以你一般想要一个模型
filter cutoff = (cutoff from envelope) + (cutoff from mod/LFO) + (cutoff from cutoff knob)
由于截止频率是一个频率,因此在对数刻度上不是一个线性的,你想要对数地做这个加法(否则,在440Hz处将截止频率提高一个八度音阶的包络线将仅在880Hz等级增加一个八度音阶. ) – 幸运的是,通过BiquadFilter上的“detune”参数很容易做到.
Detune以分(1200 / octave)为单位,因此您必须使用增益节点来调整值(例如,如果您希望调制具有1 / -1倍频程范围,请确保振荡器输出在-1200和1200之间) .您可以在我的Web音频合成器(https://github.com/cwilso/midi-synth)中看到如何做到这一点:特别是从500行开始,查看synth.js:https://github.com/cwilso/midi-synth/blob/master/js/synth.js#L497-L519.注意modFilterGain.connect(this.filter1.detune);尤其是.
您不想直接为调制设置任何值,因为实际值将以潜在的快速速率更改 – 您要使用参数调度程序并从LFO输入求和.您可以根据需要在时间上设置旋钮值,但事实证明,设置值将与相同的AudioParam上的设置值进行交互,因此您需要在AudioParam中输入一个单独的(相加)输入.这是一个棘手的一点,老实说,我的合成器今天没有这样好(我应该把它改成下面描述的方法).
处理旋钮设置的正确方法是创建一个根据旋钮设置而变化的音频通道 – 即,它可以连接()到Filter.detune的AudioNode,尽管该AudioNode产生的样本值只有正,仅当更改旋钮时更改值.为此,您需要一个直流偏移源 – 即一个产生恒定采样值流的AudioNode.我可以想到的最简单的方法是使用一个AudioBufferSourceNode,生成的缓冲区为1:
function createDCOffset() { var buffer=audioContext.createBuffer(1,1,audioContext.sampleRate); var data = buffer.getChannelData(0); data[0]=1; var bufferSource=audioContext.createBufferSource(); bufferSource.buffer=buffer; bufferSource.loop=true; bufferSource.start(0); return bufferSource; }
然后,只需将该DCOffset连接到一个增益节点,并将“旋钮”连接到该增益的值.使用增益节点来缩放值(请记住,八度音阶中有1200美分,所以如果您希望旋钮代表六度八度的截止范围,该值应该在零到7200之间).然后将DCOffsetGain节点连接到过滤器的.detune中(它与LFO的连接相加而不是替换,并且还与AudioParam上的计划值相加)(请记住,您需要将调度值缩放为分,也)).这种方法BTW使得也可以轻松翻转包络极性(Juno 106上的VCF ENV开关) – 只是反转在调度程序中设置的值.
希望这可以帮助.我现在有点喷射,所以希望这是清醒的.