A hard question about fft

Hi
How can i do analysis sound for a frequency range.
for example we have a sound that enrgy spread between 3000 hz to 4000 , now i want analysis this sound by aurduinofft library from 3000 to 4000 hz and samples 128
And analysis show

3000
3015
3030
3045
3060
.....
4000

I dont want start from 0 Hz

You have to start from 0. But, you don't have to pay attention to the bins that are outside your range of interest.

What's the sampling frequency?

I want analysis sound in two times
First analysis sound from 0 to 10000 hz when found spread main enrgy range then again do fft in this range whith high resoltion

If you use the conventional, discrete Fourier transform, you can transform any frequency range you like.

The FFT is an all or none calculation.

How can i do it?

Start here

If you have example code i understand beter

https://create.arduino.cc/projecthub/AkashKollipara/dft-audio-analyser-11f66a

I doubt that. Unless you know what it is doing you don’t stand a chance of looking at the code and finding out. Your questions show that.

deltaFreq = sampleFreq / numSamples

The first numSamples / 2 bins of the FFT are the positive side of the spectrum. Their frequency values are spaced deltaFreq apart and run from 0 to deltaFreq * (numSamples / 2 - 1).

Since you’re probably taking the FFT of a signal with only real values, the spectrum is even and you can ignore the negative frequencies represented by bins numSamples / 2 to numSamples - 1.

I'm not an FFT/DFT expert but DFT Frequency Resolution.

The resolution (and bins) are in "constant-Hz" so percentagewise you automatically get more resolution at higher frequencies.

If you are using the ADC, you know about aliasing, right?

This code is very complex i dont understand

Spend a significant amount of time studying both the Wikipedia article (there are many others on line) and the Arduino example code, and it will eventually become clear.

With 128 samples (presumably sampled at or above 8kSPS), your frequency resolution cannot be better than 62.5Hz, as 8000/128 = 62.5

Here is a very simple and slow example of a DFT:

// sample data array
float a[8] = {0, 0, 0, 0, 10, 10, 10, 10}; //square wave signal, period = 8 x sample time

void setup() {
 Serial.begin(9600);

 //sample time = 10 ms, signal frequency in this case = 1/period = 12.5 Hz.
 //DFT calculated for 0 to 40 Hz in steps of 0.5 Hz, assuming signal repeats 4 times, no window
 // expect peaks at 0Hz (DC offset), 12.5 Hz, 37.5 Hz, ...

 dft (a, 8, 10, 0, 40, 0.5, 4, 0);

}

void loop() {
}

// from https://www.instructables.com/Arduino-Frequency-Transform-DFT/
// some errors corrected SJR 10/2021
/*
 8 TERMS THAT NEED TO BE SPECIFIED
 1: an array of which dft need to be taken
 2:size of the array
 3:time interval between 2 reading in array in milliSECONDS
 4:lower value of frequency range in Hz
 5:upper value of frequency range in Hz
 6:size of steps for frequency range
 7:repetitions of signal array (minimum 1) higher number better accuracy but increased solution time
 8:  0 for no window, 1 for flat-top window, 2 for Hann window, 3 for Hamming window
     (if you do not have any idea about selecting window keep default 3)
 example:
     dft(a,110,0.5,0,30,0.5,10,3);
     here a is an array of size 110 element to be checked for 0 Hz to 30 Hz with 0.5 step (0,0.5,1,1.5, ... ,29,29.5,30)
     10 repetition and hamming window
     by- ABHILASH PATEL
*/

float dft(float a[], int arraysize, float interval, float f0, float fn, float stepsize, int reps, int window)
{
 float mag, sumi, sumr, ti, tr;
 int j, k;
 float twopi = 2.0 * PI;
 Serial.print("data array repetitions = ");
 Serial.println(reps);

 // apply windowing function
 if (window == 1) //flat-top window
 {
   for (int i = 0; i < arraysize; i++)
   {
     float b = PI * i / (arraysize);
     a[i] = a[i] * ( 1 - (1.93 * cos(2 * b)) + (1.29 * cos(4 * b)) - (0.388 * cos(6 * b)) + (0.028 * cos(8 * b)));
     // Serial.println(a[i]);
   }
 }

 if (window == 2) //hann window
 {
   for (int i = 0; i < arraysize; i++)
   {
     float b = twopi * i / (arraysize);
     a[i] = a[i] * 0.5 * (1 - cos(b));
     //Serial.println(a[i]);
   }
 }

 if (window == 3) //hamming window
 {
   for (int i = 0; i < arraysize; i++)
   {
     float b = twopi * i / (arraysize);
     a[i] = a[i] * (0.54 - 0.46 * cos(b));
   //  Serial.println(a[i]);
   }
 }

 // DFT calculation

 for (float f = f0; f <= fn; f = f + stepsize)
 {

   sumi = sumr = 0.0;
   k = 0;
   for (int i = 0; i < (arraysize * reps); i++)
   {
     j = i - k;
     if (j >= arraysize) {
       k = k + arraysize;  //signal repeat index offset
     }
     ti = a[j] * (sin(twopi * f * i * interval * 0.001)); //0.001 => time in seconds
     tr = a[j] * (cos(twopi * f * i * interval * 0.001));
     sumi = sumi + ti;
     sumr = sumr + tr;
   }
   mag = sqrt(sumi * sumi + sumr * sumr) / (arraysize * reps);
   Serial.print(f);
   Serial.print("\t");
   Serial.println(mag);
 }

}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.