0

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.

Yaakov Schectman
  • 181
  • 1
  • 1
  • 8
  • so is `int[] guitar` meant to be a level for each of the harmonics? – jaket Dec 10 '14 at 23:36
  • Yes. As I'm dividing by "total", I think they just have to be in the right ratio. Right? – Yaakov Schectman Dec 10 '14 at 23:42
  • Yes, that's correct. Have you had a look at the Karplus-Strong algorithm? http://www.cs.princeton.edu/courses/archive/fall07/cos126/assignments/guitar.html – jaket Dec 10 '14 at 23:51
  • @jaket *what* is correct? My code to reproduce a guitar sound, or my hypothesis as to why it doesn't sound quite right? – Yaakov Schectman Dec 10 '14 at 23:58
  • sorry, I was responding to your comment about the relative level of the peaks. – jaket Dec 10 '14 at 23:59
  • @jaket I see. I don't quite understand everything in that page you sent, what is the output of the RingBuffer for? Would simulating the excitation of the string make it sound closer to a guitar? – Yaakov Schectman Dec 11 '14 at 00:03
  • I don't understand it completely either but it looks like the output of the RingBuffer probably has something to do with delay and feedback. There is some more stuff on the web about the algorithm. I don't really have much more I can add otherwise I'd provide and answer. – jaket Dec 11 '14 at 00:14

1 Answers1

0

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.

Dawood ibn Kareem
  • 68,796
  • 13
  • 85
  • 101