A few overview questions about FFT. Relationships between input, buffer size, and expected output?

I have a FFT set up and I've found that it responds very differently based on the buffer size and input. The output varies wildly, with magnitude of the peak frequency ranging from 500 to <1.

I have two tests in particular I'm running, the first being a sine wave at amplitude 1.0 with an LFO sweeping it's frequency at 0.1Hz. I've found that smaller buffers are more accurate in their ability to track the frequency. The magnitude of the frequency playing reaches 300 pretty easily.

The next test is with a mic, and it responds incredibly differently. If I whistle or hum, it will pick up that frequency. If I play music, rather than getting an increase in magnitudes of all frequencies, everything becomes weaker, including any whistling or humming. Changing the buffer size to be smaller helps, but at most iterations of the FFT on a buffer it results in very tiny magnitudes across the board.

In general, the things I'm finding are that smaller buffers are more likely to get a very strong magnitude of a frequency, but the more frequencies there are with a (magnitude > 1), the less likely that any of them are very strong (> 200). But none of this really means anything if it's a product of a broken implementation, and I can't seem to find any specific numeric information on what my expectations should be.

So, given an audio input and an output of frequencies and magnitudes (calculated by $\sqrt{\frac{\text{real}^2 + \text{imag}^2}{\frac{\text{numSamples}}{2}}}$), my questions are as follows:

1. Given a sole, unmoving sine wave, with a relatively small buffer size what kind of magnitudes are to be expected on what frequencies?

2. Given a sole, unmoving sine wave, with a relatively large buffer size what kind of magnitudes are to be expected on what frequencies?

3. Given a sole, sweeping frequency sine wave, with a relatively small buffer size what kind of magnitudes are to be expected on what frequencies?

4. Given a sole, sweeping frequency sine wave, with a relatively large buffer size what kind of magnitudes are to be expected on what frequencies?

5. Given static, with a relatively small buffer, what kind of magnitudes are to be expected?

6. Given static, with a relatively large buffer, what kind of magnitudes are to be expected?

I know this is a lot of questions, but the results I'm getting from these tests are not what I was expecting, and I want to start by making sure it's not my expectations that were wrong.

• A lot of the answer will depend on how long the buffer is compared to the period of your sine wave, and whether or not there are an exact integer number of sinewave periods (e.g. zero remainder) in the length of the FFT. – hotpaw2 Jul 31 '17 at 4:35
• That makes sense. How much does it depend on that? What sort of difference in magnitude should I expect, and on what frequencies? – Seph Reed Jul 31 '17 at 4:38
• @SephReed really, that's basically the leakage effect, and can be described by considering the DFT as a bank of sinc-shaped (in frequency domain!) filters. – Marcus Müller Jul 31 '17 at 7:22
• if you could post some concrete examples of the cases you mention and what you expected to see and what you didn't, we could be more helpful. It would also demonstrate, because its been known to happen, that you have a correct implementation. Some people roll their own code and my own first attempt consisted of coding Fortran with a book where 0,not 1 is the start of an array. – Stanley Pawlukiewicz Jul 31 '17 at 20:12
• I don't want to make this q&a specific to my implementation, as it's more of a general question about what kind of stuff to expect. Think of it as an intro I've never gotten, rather than a means to an end. On my end, I've gotten my code to do something more than good enough. But I would still like to have some idea of general IO for an FFT. I tend to learn best not through equations but data, in particular data that is verified good enough, which I do not have any of. – Seph Reed Jul 31 '17 at 20:19

So, I'm not an expert at all, but I feel that I've perhaps learned enough to be somewhat helpful to anyone who ends up here with little introduction to FFT. If any of this is wrong, see the "P.S" at the bottom. tl;dr I'd rather share than leave this question unanswered entirely.

A few things are important to note: Parseval's theorem, bin frequencies, and normalization:

Parseval's theorem is something to the ends that the energy of the signal will be the energy of FFT bins (bins being each frequency/magnitude pair). So, what this means in practice (I think) is that a small buffer size will make the bin magnitude of a sine wave frequency vary based off the amount of high amplitude wave is in the buffer. It won't be consistent.

Bin Frequencies are the frequency of each bin from your FFT. They aren't going to be the exact numbers you are looking for without a bit of work, but they should be close enough to give you some info.

Normalization is something that helps with all this. For my project, I found the max bin magnitude, averaged it with the max from the last cycle, and then divided everything by it. The result is that my visualization is showing something much more like what my ears feel they would see.

Now for the Q's (assuming all signals are normalized to -1 < x < 1):

1. Magnitudes of ~200 +-100, in the bins near the signal wave freq

2. Same, but magnitudes of ~300 +-50. The larger buffer limits cases of more or less high amplitude chunking (sin(x) at [0 to Pi/4] vs [Pi/4 to Pi/2])

3. Magnitudes of ~150 +-100, in the bins near the signal wave freq. The sweeping spreads out the bins a little, but the small buffer size (relative to sweep speed) helps.

4. Magnitudes of ~50 +-100, in the bins touched by the signal wave freq. If the sweep is larger or faster expect the magnitudes to be even more spread out. Note: the more bins touched, the lower the magnitudes overall.

5. Magnitudes of ~5 +-5, in all bins which happen to be strongly represented in this small buffer chunk

6. Magnitudes of ~1 +-1 in all bins.

So, it seems there is probably some form of log function which would help make the perceived levels of all these sounds not so distant when graphed by magnitude, but, overall, using normalization has worked in my project to pick out the most noteworthy note tones. (btw notes and tones are anagrams)

P.S. If any of this is wrong, please do make an answer covering and correcting these topics. I will not be marking this as the accepted answer for at least a month because I'm not experienced enough to be an authority on this subject. That being said, this is what I think may be true based off the results I've been getting, and it's better than nothing for a newcommer.

• Sorry. A bare FFT is a bad way to pick out note pitches. The numbers above are meaningless without a lot more details. – hotpaw2 Jul 31 '17 at 20:53
• I'm not really looking for pitch as much as present frequencies. If looking for pitch, there are better algorithms, I'm aware. In any case, I've gotten it working, so I must have done something right. – Seph Reed Jul 31 '17 at 20:58
• Also, these meaningless numbers are significantly more meaningful than a complete lack of concrete data. Does the number 100 ever make sense? Apparently sometimes. What about 0.5? Sometimes that too. – Seph Reed Jul 31 '17 at 21:00