0

I finally have a working FFT implemented, but the frequency doesn't seem to work correctly. For example, while playing a musical instrument, the notes give (somewhat) consistent but random frequency values (a "C" on my alto sax gives a 602Hz and an "E" gives a 387hz, should be ~312 and ~397 respectively, at least according to an app I have) Here's the code:

public static void main(final String[] args) throws Exception {
    final AudioFormat format = new AudioFormat(
            AudioFormat.Encoding.PCM_SIGNED,
            44100,
            16,
            1,
            2,
            44100,
            false
    );

    final DataLine.Info info = new DataLine.Info(
            TargetDataLine.class,
            format
    );

    final TargetDataLine targetLine = (TargetDataLine) AudioSystem.getLine(info);
    targetLine.open();
    targetLine.start();

    final AudioInputStream audioInputStream = new AudioInputStream(targetLine);

    final byte[] buf = new byte[1024];
    final int numberOfSamples = buf.length / format.getFrameSize();
    final JavaFFT fft = new JavaFFT(numberOfSamples);

    while (true) {
        audioInputStream.read(buf);

        final float[] samples = decode(buf, format);
        final float[][] transformed = fft.transform(samples);
        final float[] real = transformed[0];
        final float[] imaginary = transformed[1];
        final double[] magnitudes = toMagnitudes(real, imaginary);

        // do something with magnitudes

        printDetectedIndex(magnitudes);
    }
}


private static void printDetectedIndex(double[] magnitudes) {
    int index = maxIndex(magnitudes);
    float frequency = (float) index * 44100 / 1024;
    int fInt = (int) frequency; // remove decimal part
    System.out.println("Frequency: " + frequency + "Hz (" + fInt + "Hz)");
}

// function to return index of the largest element in array
public static int maxIndex(double[] array) {
    int maxIndex = 9;
    for (int i = 9; i < array.length; i++) {
        if (array[i] > array[maxIndex]) {
            maxIndex = i;
        }
    }
    return maxIndex;
}

Any help would be much appreciated!

SprintKeyz
  • 134
  • 8
  • 1
    Does this answer your question? [How to get the fundamental frequency from FFT?](https://stackoverflow.com/questions/4914832/how-to-get-the-fundamental-frequency-from-fft) – tgdavies Sep 24 '22 at 03:39
  • @tgdavies that was very helpful, I tried to implement Harmonic Product Spectrum and it generally seems to work well. That said, it still thinks a G is lower than a D (although every other note works correctly)! – SprintKeyz Sep 24 '22 at 04:10
  • Maybe an interesting test would be to compare your harmonic analysis on a .wav file of your saxophonist, to Audacity's analysis tool. – Phil Freihofner Sep 24 '22 at 17:05

0 Answers0