result of FFT

claptrap clap at trap.com
Thu Jul 10 09:18:41 UTC 2025


On Tuesday, 8 July 2025 at 18:11:27 UTC, Matthew wrote:
> Hi,
>
> I'm writing a program where I'm trying to decode DTMF tones. I 
> already completed the wave file decoder and I know I'm supposed 
> to use an FFT to transform the samples from time domain to 
> frequency domain but I'm stuck on determining which of the DTMF 
> frequencies are present.
>
> Consider the following, the input is the sound wave samples as 
> an array of floats between -1 and +1.
>
> ```D
> void decode_sound(float[] samples)
> {
> 	import std.numeric;
> 	import std.math;
> 	import std.complex;
> 	import std.algorithm;
>
> 	size_t fft_size = 4096;
> 	
> 	auto f = new Fft(fft_size);
>
> 	foreach(ch; samples.chunks(fft_size))
> 	{
> 		auto res = f.fft(ch);
> 		// res is an array of 4096 complex numbers
> 	}
> }
> ```
>
> I can't figure out how the 4096 results of the FFT relate to 
> the frequencies in the input.
>
> I tried taking the magnitude of each element, I tried taking 
> just the real or imaginary parts.  I plotted them but the graph 
> doesn't look how I'm expecting.
>
> What do the 4096 resulting complex numbers represent?
> How should I use the result to check whether the 1209Hz, 
> 1336Hz, 1477Hz, or 1633Hz tones are present in that part of the 
> sound?
>
> Thanks,
> Matthew

The output is an array of "bins", each bin holds a complex 
number, the magnitide of the complex number is the magnitude of 
that bin, and the phase of the complex number is the phase of 
that bin. The frequency the bin represents is..

(samplerate/2) * idx/res.length

where idx is the bin index. IE the first bin = 0hz, and the last 
bin is samplerate/2. And they are linearly spaced across that 
range.

This is for a "real fft", rather than a "complex fft", looks like 
that's what your doing tbh. A complex FFT you get negative 
frequencies too i think, but i never real got my head around that.

Note that FFTs aren't perfect, unless the frequencies line up 
exactly on the bin frequencies you get leakage into neighbouring 
bins. A single sine wave between two bins will show up as peak at 
those two bins and leakage tailing off to some of the bins above 
and below it. You can adjust the distribute of this leakage by 
applying a window function to the sample before you FFT it, but 
it may or may not matter in your case, if the tones your looking 
for are not too close to each other.

You might need to average a few bins around the frequency of 
interest for best results.

I'd probably just make a few test samples with each single sine 
wave, and see what the FFT bins look like, and adjust my 
detection algo based on that. Tweaking FFT length and window 
function will give you enough separation between the tones your 
interested in.



More information about the Digitalmars-d-learn mailing list