I've been trying to work out the logic for this task, and plan to use the KissFFT source package to perform the fast fourier transform. Please let me know if this looks about right:
- Allocate an FFT structure, ie.
kiss_fft_alloc(N,0,NULL,NULL)
WhereN
is the window size I'm using. The input buffer will be an array ofN
elements of typekiss_fft_scalar
. The output buffer will be an array ofN/2 + 1
elements of typekiss_fft_cpx
. - Decode
N
(window size) number of PCM samples. - For each PCM sample, average each channel's amplitude (unsigned samples) and scale from 0 to 2 (divide by 65536.0), storing the result into the input buffer.
- Perform windowing (ie. Hanning) on the input buffer.
- Perform fast fourier transform on the input buffer, storing into the output buffer. Since I am using real values as input, I can use
kiss_fftr()
. - For the
N/2
output values, obtain the squared magnitude of the transformed data and convert the values to the dB scale with the following formula:10 * log10 (re * re + im * im)
- Plot the
N/2
values from step 6. - Discard the first half of the input buffer, decoding the next (window size / 2) PCM samples and performing scaling and windowing to the data. This should effectively slide the input window and avoid having to redo math on processed PCM samples.
- Loop to step 5, repeating these steps until all samples are processed.
- Free the used memory from
kiss_fft_alloc()
.
It was suggested that I subtract a value from the input window before I perform the FFT, so that the resulting DC value has a magnitude of zero. Should I be subtracting the mean or the average from the input data?
Also, what are the things I need to consider when I choose a window size? Besides that it has to be an even number as per KissFFT's instructions, is there a benefit to using a small window size, ie. will it provide for a better graph? I assume that a large window size reduces the number of FFTs that must be performed, is that the only benefit to using a large window size?
Lastly, when I get to the point that the data is ready to plot, how do I go about plotting it? When I worked on some waveform graph logic in the past, I just plotted 3 values for each pixel along the $x$-axis (min amplitude, max amplitude, RMS amplitude), but I don't know what I'm supposed to do with spectrogram data.
Thank you in advance for any and all guidance you can provide.