WebAudio中的WaveShaper节点 - 如何模拟失真?

Pin*_*ade 12 audio web web-audio-api

使用WebAudio API并尝试扭曲!问题是,我不确定如何进入WaveShaper的"曲线"参数.

简而言之,'oscidis'是程序早期创建的WaveShaper节点.Oscidisv是一个静态设置为0的值,现在:

var wsCurve = new Float32Array();
if ((oscidisv >= -1) && (oscidisv < 1)) {

    var k = 2 * oscidisv / (1 - oscidisv);
    console.log
    for (var i = 0; i < 16; i+=1) {
        // LINEAR INTERPOLATION: x := (c - a) * (z - y) / (b - a) + y
        // a = 0, b = 2048, z = 1, y = -1, c = i
        var x = (i - 0) * (1 - (-1)) / (16 - 0) + (-1);
        wsCurve[i] = (1 + k) * x / (1+ k * Math.abs(x));
    }
}
oscidis.curve.value = wsCurve;
Run Code Online (Sandbox Code Playgroud)

问题 - 无论我在这里放什么,我听不到任何声音上的差异) - =.即使在max(1)处出现失真,我也没有注意到任何真正的失真.你们知道一个更明显的失真波形整形函数吗?或者,如果我在WebAudio API中完全正确地执行此操作?

Kev*_*nis 29

这是我用过的一个基于我在白皮书中发现的一些不同功能的东西:

function makeDistortionCurve( amount ) {
  var k = typeof amount === 'number' ? amount : 50,
    n_samples = 44100,
    curve = new Float32Array(n_samples),
    deg = Math.PI / 180,
    i = 0,
    x;
  for ( ; i < n_samples; ++i ) {
    x = i * 2 / n_samples - 1;
    curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );
  }
  return curve;
};
Run Code Online (Sandbox Code Playgroud)

我是在撒谎,如果我告诉你,我知道在哪里的3 + k或者20是从哪里来的-但它的工作原理.

amount可以基本上是任何正数,但我发现0 - 100是一个非常好的范围,取决于你需要多少失真.

如果您有兴趣了解这些函数的外观,我建立了一个小工具来帮助我在这里看到它们:http://kevincennis.github.io/transfergraph/

  • 如果你选择1弧度(而不是20度)的角度,并使用'PI`而不是幻数3,那么函数会经过(-1,-1)和(1,1),并且函数简化了到'(PI + k)*x /(PI + k*abs(x))`.角度实际上只是一个输出缩放因子(也可能是1),而PI实际上只是一个输入缩放因子,因此可以解析一些功能. (3认同)
  • 他们肯定很难找到.大多数真正好听的效果算法都是专有的.像Amplitube,Line6等公司在这些方面投入了大量的时间和金钱,他们需要保持竞争优势 - 因此很难找到好的信息.当然,真正高端的东西使用的技术比简单的wavehaper复杂得多......但仍然如此.我可以推荐的最好只是运行一些搜索"吉他放大器wavehaper"之类的东西,看看会出现什么.这就是我做的.但那里的情况并不多. (2认同)
  • 凉。谢谢@Grumdrig。顺便说一句,可能对人有帮助的另一件事–对于吉他失真,假设您试图模拟放大器的声音,则添加带有扬声器箱体脉冲响应的`ConvolverNode`会很有帮助。如果您在Google周围逛了一逛,找到它们并不是很难。否则,您会听到类似将吉他插入失真踏板并直接进入调音台的声音,这种声音通常很糟。卷积器将使您实际上在移动一些空气。 (2认同)

ton*_*har 7

我采纳了上面的一些建议并重新考虑了该功能。我还将类型化数组中的样本数从 44K 减少到 256,这让浏览器更开心:-()

let distortionFilter = audioCtx.createWaveShaper();
distortionFilter.curve = makeDistortionCurve();

function makeDistortionCurve(amount=20) {
    let n_samples = 256, curve = new Float32Array(n_samples);
    for (let i = 0 ; i < n_samples; ++i ) {
        let x = i * 2 / n_samples - 1;
        curve[i] = (Math.PI + amount) * x / (Math.PI + amount * Math.abs(x));
    }
    return curve;
} 
Run Code Online (Sandbox Code Playgroud)