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