Visualizer onFftDataCapture - Does the byte[] index represent frequency?

+1 vote
asked Sep 12, 2017 by dan

I'm having understanding the Android Visualizer's

onFftDataCapture((Visualizer visualizer, 
            byte[] fft, 
            int samplingRate)

How do I know which frequency is represented by which byte in fft?

For example, would the index be a representation of frequency? Like index = frequency?

For index 0, frequency is 0 Hz, index 1 is 1 Hz, etc?

1 Answer

+1 vote
answered Sep 13, 2017 by mikhail-naganov

FFT produces complex numbers, where each number reflects frequency domain information about a bucket containing a continuous range frequencies. The usual approach for interpreting FFT data is as follows:

  • first determine the frequency bucket size by dividing the length of the FFT table by the sampling rate, let's call it bucketSize;

  • then each bucket with index i (assuming it's 0-based) contains information about frequencies in the range from i * bucketSize to (i + 1) * bucketSize Hz;

  • for real-valued signals, the values of the second half of the FFT table (for buckets of frequencies above samplingRate / 2) will be just a mirror of the first half, so they are usually discarded;

  • to find the magnitude (signal level) for the frequencies in the bucket, one needs to take the complex value from the FFT table for this bucket, say it's a + ib, and calculate sqrt(a*a + b*b).

Now back to the results of onFftDataCapture. Here the fft array contains complex numbers as consecutive pairs of bytes, so fft[0] and fft[1] comprise the complex number for the first bucket, fft[2] and fft[3] -- for the second, and so on.

Because, as I've mentioned, for real-valued signals the second part of the FFT table doesn't bring any benefit, it's not provided in the fft array. But since each FFT bucket takes two array cells, the bucket size in Hz will still be calculated as fft.length / samplingRate. Note that fft.length is actually the capture size set by setCaptureSize method of the Visualizer.

The magnitude of the bucket of frequencies can be easily calculated using Math.hypot function, e.g. for the first bucket it's Math.hypot(fft[0], fft[1]).

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.