0

I have code to apply an FFT to mic audio and get an array of magnitudes out of it, but how would I go about converting these magnitudes to a frequency?

Here's my code:

final double[] magnitudes = toMagnitudes(real, imaginary);

System.out.println("Largest index: " + maxIndex(magnitudes));

And the functions:

public static int maxIndex(double[] array) {
    int maxIndex = 0;
    for (int i = 0; i < array.length; i++) {
        if (array[i] > array[maxIndex]) {
            maxIndex = i;
        }
    }
    return maxIndex;
}

private static double[] toMagnitudes(final float[] realPart, final float[] imaginaryPart) {
    final double[] powers = new double[realPart.length / 2];
    for (int i = 0; i < powers.length; i++) {
            powers[i] = Math.sqrt(realPart[i] * realPart[i] + imaginaryPart[i] * imaginaryPart[i]);
    }
    return powers;
}

Currently, the largest index of the array is always 0. I have no idea how I'd resolve this (or convert this to a frequency), but it is annoying me quite a bit. Thanks for any help!

SprintKeyz
  • 134
  • 8
  • 1
    This all depends on the code that generates that array. What are the indexes of the array supposed to be? If you're doing an FFT, I'd expect each index to represent a different frequency; and all you have to do is select the index of the largest number in the array. – Dawood ibn Kareem Sep 22 '22 at 00:28
  • 1
    Incidentally, it's really better if you _don't_ delete your previous questions as you do more work on this project. They might just be useful to somebody else. Also, somebody might be partway through answering at the time you do the delete. – Dawood ibn Kareem Sep 22 '22 at 00:36
  • @DawoodibnKareem Sorry for deleting those old questions, I assumed they weren't specific enough for StackOverflow. Yes, the indexes do represent frequencies! My problem is (was) that the Largest index is always zero. To fix this, I tried forcing the largest index to 64 or greater, but it was then spitting out random values. However, I have now tried setting the largest index to be a minimum of 1, and it seems to be working better. If I find a full solution that works well, I will be sure to post it as a solution here for others to benefit from. Thanks for the help! – SprintKeyz Sep 22 '22 at 01:37
  • It's OK. I was only keeping an eye on your questions because I intend to do something related to this myself, at some point in the future. I wonder if [this question](https://stackoverflow.com/q/4364823/1081110) might have some answers that are useful to you, even though it's not in Java. – Dawood ibn Kareem Sep 22 '22 at 01:55
  • That question is actually extremely helpful, I can now convert my array indexes to frequencies. However, for some reason, the frequency doesn't change when I play certain frequencies to the mic via a saxophone. Talking, however, does change it. Is there a reason for this? I have a pretty good mic. – SprintKeyz Sep 22 '22 at 12:32
  • I don't know. I'm wondering if, when you talk, you're picking up formant frequencies rather than the fundamental. Does the frequency change if you speak or sing the same vowel at a higher pitch? How about if you speak or sing a different vowel at the same pitch? Very roughly speaking, for human speech or song, the fundamental frequency gives you the pitch, and the first two formant frequencies tell you the vowel. – Dawood ibn Kareem Sep 23 '22 at 02:43
  • Also, be aware that a change in pitch of one semitone is only about a 5.9% increase in frequency, and it's possible that you don't have enough array indexes to measure it accurately enough. So for example, if you have a tenor sax and you play the B that's notated on the third line of the treble stave, this corresponds to a frequency of 220Hz. Now if you go up a semitone, and play C, you're getting a frequency of 233Hz. Do you have enough indexes to distinguish these? – Dawood ibn Kareem Sep 23 '22 at 02:52

0 Answers0