2

I'm designing a real time Audio Analyser to be embedded on a FPGA chip. The finished system will read in a live audio stream and output frequency and amplitude pairs for the X most prevalent frequencies.

I've managed to implement the FFT so far, but it's current output is just the real and imaginary parts for each window, and what I want to know is, how do I convert this into the frequency and amplitude pairs?

I've been doing some reading on the FFT, and I see how they can be turned into a magnitude and phase relationship but I need a format that someone without a knowledge of complex mathematics could read!

Thanks


Thanks for these quick responses!

The output from the FFT I'm getting at the moment is a continuous stream of real and imaginary pairs. I'm not sure whether to break these up into packets of the same size as my input packets (64 values), and treat them as an array, or deal with them individually.

The sample rate, I have no problem with. As I configured the FFT myself, I know that it's running off the global clock of 50MHz. As for the Array Index (if the output is an array of course...), I have no idea.

If we say that the output is a series of One-Dimensional arrays of 64 complex values:

1) How do I find the array index [i]?

2) Will each array return a single frequency part, or a number of them?

Thankyou so much for all your help! I'd be lost without it.

Dave Moore
  • 1,432
  • 4
  • 12
  • 17

2 Answers2

5

Well, the bad news is, there's no way around needing to understand complex numbers. The good news is, just because they're called complex numbers doesn't mean they're, y'know, complicated. So first, check out the wikipedia page, and for an audio application I'd say, read down to about section 3.2, maybe skipping the section on square roots: http://en.wikipedia.org/wiki/Complex_number

What that's telling you is that if you have a complex number, a + bi, you can picture it as living in the x,y plane at location (a,b). To get the magnitude and phase, all you have to do is find two quantities:

  • The distance from the origin of the plane, which is the magnitude, and
  • The angle from the x-axis, which is the phase.

The magnitude is simple enough: sqrt(a^2 + b^2).

The phase is equally simple: atan2(b,a).

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
Novak
  • 4,687
  • 2
  • 26
  • 64
  • 1
    A bit late to this answer, but: that entire list of values can be replaced with a single function that's supported in every programming language and even has a dedicated cpu instruction: `atan2`, so in this case the phase for complex number `x + iy` is just `atan2(y,x)`. No need to check quadrants and compensate by adding/subtracting values. – Mike 'Pomax' Kamermans Apr 11 '20 at 17:17
  • @Mike'Pomax'Kamermans Exactly. As I came back to read this answer (because of the inbox flag your comment generated) I was thinking to myself, "Why didn't I just recommend ATAN2?" Probably because eight years ago I didn't know about it. – Novak Apr 11 '20 at 18:25
  • That's the nice thing about SO: even if you didn't know about it 8 years ago, today is the perfect time to update the answer to be even better =) – Mike 'Pomax' Kamermans Apr 11 '20 at 18:42
  • 1
    While you’re at it, many languages have a function `hypot(a,b)` to compute `sqrt(a^2 + b^2)` but in a way that avoids overflow if `a` or `b` is very large. – Cris Luengo Apr 11 '20 at 22:43
3

The FFT result will give you an array of complex values. The twice the magnitude (square root of sum of the complex components squared) of each array element is an amplitude. Or do a log magnitude if you want a dB scale. The array index will give you the center of the frequency bin with that amplitude. You need to know the sample rate and length to get the frequency of each array element or bin.

f[i] = i * sampleRate / fftLength

for the first half of the array (the other half is just duplicate information in the form of complex conjugates for real audio input).

The frequency of each FFT result bin may be different from any actual spectral frequencies present in the audio signal, due to windowing or so-called spectral leakage. Look up frequency estimation methods for the details.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • Thanks for this, I've edited to add a couple more questions. Any help you can offer would be much appreciated. – Dave Moore Feb 28 '12 at 12:00
  • If your FFT implementation is some sort of pipelined synchronous process, you will need to know the length of FFT that the process implements, and either the fixed latency or some sort of start-of-result-vector signal. – hotpaw2 Feb 28 '12 at 23:13
  • Would you be willing to update this answer so that it gives the same code-esque formulae for `a[i]` and `db[i]`? I found this answer while searching for "turn FFT real and imaginary into frequency and amplitude" and this answer feels not quite complete enough for a programmer audience. I could edit in `a[i] = (real[i] **2 + im[i] ** 2) ** 0.5`, but I have no idea how to turn your text into code that gives `db[i]` – Mike 'Pomax' Kamermans Apr 11 '20 at 17:13