10

我正在使用 WebAudio 构建 Roland Juno-106 合成器的仿真。现场 WIP 版本在这里

如果在起音或释放期间改变了截止频率或包络调制量,而滤波器同时被包络调制,我对如何处理更新滤波器感到困惑。该代码位于此处。当前的实现没有像模拟合成器那样响应,但我不太清楚如何计算它。

在真正的合成器中,滤波器会立即改变,这取决于频率截止、包络调制量和包络中的当前阶段,但斜坡上升或下降也会平稳地继续。

我将如何为这种行为建模?

4

1 回答 1

11

很棒的项目!

您不需要自己总结这些 - 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”参数很容易做到这一点。

失谐以美分(1200/八度)为单位,因此您必须使用增益节点来调整值(例如,如果您希望调制具有 +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 的输入求和。您可以根据需要根据时间设置旋钮值,但事实证明,设置 .value 与在同一 AudioParam 上设置预定值的交互效果不佳 - 因此您需要在 AudioParam 中单独(汇总)输入。这是一个棘手的问题,老实说,我的合成器今天做得不好(我应该将其更改为下面描述的方法)。

处理旋钮设置的正确方法是创建一个根据您的旋钮设置而变化的音频通道 - 也就是说,它是一个 AudioNode,您可以将其连接()到 filter.detune,尽管该 AudioNode 生成的样本值仅正,并且仅在更改旋钮时更改值。为此,您需要一个 DC 偏移源 - 即产生恒定样本值流的 AudioNode。我能想到的最简单的方法是使用生成缓冲区为 1 的 AudioBufferSourceNode:

   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 连接到增益节点,并将您的“旋钮”连接到该增益的 .value 以使用增益节点来缩放值(请记住,八度音程中有 1200 美分,所以如果您希望您的旋钮代表一个六倍频程的截止范围,.value 应该在 0 到 7200 之间)。然后将 DCOffsetGain 节点 connect() 到过滤器的 .detune 中(它与来自 LFO 的连接相加,而不是替换,并且还与 AudioParam 上的预定值相加(请记住,您需要以美分为单位缩放预定值, 也))。顺便说一句,这种方法也可以轻松翻转包络极性(即 Juno 106 上的 VCF ENV 开关) - 只需反转您在调度程序中设置的值。

希望这可以帮助。我现在有点时差,所以希望这是清醒的。:)

于 2015-05-04T15:57:02.240 回答