Recreating guitar string with harmonies through raw audio

114 views Asked by At

I recorded a guitar string playing a note, then took the amplitudes of each harmony, and put it through a prgram(android) to recreate a similar sound, but the sound doesn't sound much like a guitar.

public void setToHarmonies(int[] harmonies, int frequency){
        int total = 0;
        int size = harmonies.length;
        for(int i=0; i<size; i++){
            total+=harmonies[i];
        }
        for(int i=0; i<numSamples; i++){
            samples[i] = 0;
        }
        float[] effHarm = new float[size];
        double[][] hwaves = new double[size][numSamples];
        for(int i=0; i<size; i++){
            effHarm[i] = ((float)(harmonies[i]-.2)) / (float)total;
            hwaves[i] = genSinWave(numSamples, frequency * i);


for(int e=0; e<numSamples; e++){
            samples[e] += effHarm[i] * hwaves[i][e] * Math.exp((float)((float)e / (float)15000) * -1);
        }
    }
}

public double[] genSinWave(int size, int freq){
    double[] samplesOut = new double[size];
    float period = (float)sampleRate / (float)freq;
    for(int i=0; i<samplesOut.length; i++){
        samplesOut[i] = Math.sin(2 * i * Math.PI / period);
    }
    return samplesOut;
}
private static final int[] guitar = {699, 602, 465, 407, 544, 457, 443, 307, 283, 357, 342, 224};

Plot spectrum on Audacity gave me nagative values, the minimum at -72.7, so I subtracted the value at each peak from 72.7, then multiplied by 10 to get the above values. Is the programming wrong? Is the harmony content/timbre values wrong? Is there no way to make it sound guitar-y without making a specific attack and decay modification to the wave? All help is appreciated.

1

There are 1 answers

0
Dawood ibn Kareem On

The thing that give musical instruments distinctive sounds is a combination of

  • the waveform, which is roughly speaking the relative amplitude of the various harmonics
  • the envelope, which is the variation of amplitude over time - roughly speaking, you've got the amount of time it takes for the sound to build up to a peak level after it begins, the amount of time it takes to drop from its peak level to its sustained level, the ratio of the sustained level to the peak level, then the manner in which it decays down from the sustained level.

These are both important in distinguishing one instrument from another. For example, a violin and a trumpet tend to have identical or almost-identical waveforms, but very different envelopes.

Your general method seems to be focussing on the waveform, and ignoring the envelope entirely.

You can probably get more help on this from a different site - maybe the "physics" stack exchange or even the "music" stack exchange. But your problem at this point is nothing to do with Java programming.