2
votes

If I(in Java) have a double[] array containing audio samples, ranging from -1 to 1, which I can play, and have generated to sound like a guitar string being played, is there any way through which I can simulate the effect of distortion from an amplifier on these samples?

I apologize for the vagueness of the term "distortion", but I'm referring to any effect similar to setting a guitar amplifier to "distortion". What I already have sounds like an acoustic guitar, or an electric guitar with no distortion(set to "clean"), so how can I alter the array to sound more like what you would expect from an electric guitar in a rock or metal setting?

The current set of samples is calculated using the following method:

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

1 Answers

2
votes

There are three main types of distortion:

  • Hard distortion: simple clipping of the signal

    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;
    }
    
  • Normal distortion: exponential smooth scaling of the signal

    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;
    }
    
  • Soft distortion: same as above, but using arc-tan (presumably more aggressive)

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

Variables:

  • gain_pre and gain_post: Pre-gain and Post-gain parameters
  • clip: maximum value for hard-distortion signal
  • samples: the sample sequence you calculate

References / more info:

http://cp-gfx.sourceforge.net/ (download the source code and look in /src/effects/)

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