模拟字节数组上吉他放大器的失真

时间:2015-07-27 00:06:28

标签: java math audio filtering simulation

如果我(在Java中)有一个double[]数组包含音频样本,范围从-1到1,我可以播放,并生成听起来像正在播放的吉他弦,有没有办法通过我可以模拟这些样品放大器失真的影响吗?

我为术语"失真"的含糊不清道歉,但我指的是类似于将吉他放大器设置为"失真"的任何效果。我已经拥有的声音听起来像一把原声吉他,或者一把没有失真的电吉他(设置为#34;清洁"),所以如何改变阵列听起来更像你对电吉他的期望岩石或金属环境?

使用以下方法计算当前样本集:

double[] samples = new double[duration]; //duration = seconds * sampleRate
int period = (float)sampleRate / (float)frequency;
double[] buf = new double[period]; //a ring buffer used for the sound generation
int count = 0, c1 = 1, c2 = 2;
for(int i=0; i<duration; i++){
    if(count <= period)count = 0;
    if(c1 <= period)c1 = 0;
    if(c2 <= period)c2 = 0;
    if(i < period){
        buf[count] = rand.nextDouble() * 2 - 1; //rand being a Random
    }
    else{
        buff[count] = (buff[c1] + buff[c2]) / 2;
    }
    samples[i] = buff[count];
    count++;
    c1++;
    c2++;
}

1 个答案:

答案 0 :(得分:2)

有三种主要的失真类型:

  • 硬失真:信号的简单剪切

    for (int i = 0; i < duration; i++)
    {
        double sample = samples[i] * gain_pre;
        if (sample > clip)
            sample = clip;
        else
        if (sample < -clip)
            sample = -clip;
        samples[i] = sample * gain_post;
    }
    
  • 正常失真:信号的指数平滑缩放

    double max = 1.0 / (1.0 - exp(-gain_pre));
    for (int i = 0; i < duration; i++)
    {
        double sample = samples[i] * gain_pre;
        double z = (sample < 0.0) ? (-1.0 + exp(sample)) :
                                    (1.0 - exp(-sample));   
        samples[i] = z * max * gain_post;
    }
    
  • 软失真:与上述相同,但使用arc-tan(可能更具攻击性)

    double max = 1.0 / atan(gain_pre);
    for (int i = 0; i < duration; i++)
    {
        samples[i] = atan(samples[i] * gain_pre) * max * gain_post;
    }
    

变量:

  • gain_pregain_post:预增益和后增益参数
  • clip:硬失真信号的最大值
  • samples:您计算的样本序列

参考资料/更多信息:

http://cp-gfx.sourceforge.net/(下载源代码并查看/ src / effects /)

https://en.wikipedia.org/wiki/Distortion_(music)#Theory_and_circuits