0

I have a 1024 samples and I chucked it into 32 chunks in order to perform FFT on it, below is the output from FFT:

(3.13704,2.94588) (12.9193,14.7706) (-4.4401,-6.21331) (-1.60103,-2.78147) (-0.84114,-1.86292) (-0.483564,-1.43068) (-0.272469,-1.17551) (-0.130891,-1.00437) (-0.0276415,-0.879568) (0.0523422,-0.782884) (0.117249,-0.704425) (0.171934,-0.638322) (0.219483,-0.580845) (0.261974,-0.529482) (0.300883,-0.48245) (0.337316,-0.438409) (0.372151,-0.396301) (0.40613,-0.355227) (0.439926,-0.314376) (0.474196,-0.27295) (0.509637,-0.23011) (0.54704,-0.184897) (0.587371,-0.136145) (0.631877,-0.0823468) (0.682262,-0.021441) (0.740984,0.0495408) (0.811778,0.135117) (0.900701,0.242606) (1.01833,0.384795) (1.18506,0.586337) (1.44608,0.901859) (1.92578,1.48171)

(-3.48153,2.52948) (-16.9298,9.92273) (6.93524,-3.19719) (3.0322,-1.05148) (1.98753,-0.477165) (1.49595,-0.206915) (1.20575,-0.047374) (1.01111,0.0596283) (0.869167,0.137663) (0.759209,0.198113) (0.669978,0.247168) (0.594799,0.288498) (0.52943,0.324435) (0.471015,0.356549) (0.417524,0.385956) (0.367437,0.413491) (0.319547,0.439819) (0.272834,0.4655) (0.226373,0.491042) (0.17926,0.516942) (0.130538,0.543728) (0.0791167,0.571997) (0.0236714,0.602478) (-0.0375137,0.636115) (-0.106782,0.674195) (-0.18751,0.718576) (-0.284836,0.772081) (-0.407084,0.839288) (-0.568795,0.928189) (-0.798009,1.0542) (-1.15685,1.25148) (-1.81632,1.61402)

(-1.8323,-3.89383) (-6.57464,-18.4893) (1.84103,7.4115) (0.464674,3.17552) (0.0962861,2.04174) (-0.0770633,1.50823) (-0.1794,1.19327) (-0.248036,0.982028) (-0.29809,0.827977) (-0.336865,0.708638) (-0.368331,0.611796) (-0.394842,0.530204) (-0.417894,0.459259) (-0.438493,0.395861) (-0.457355,0.337808) (-0.475018,0.283448) (-0.491906,0.231473) (-0.508378,0.180775) (-0.524762,0.130352) (-0.541376,0.0792195) (-0.558557,0.0263409) (-0.57669,-0.0294661) (-0.596242,-0.089641) (-0.617818,-0.156045) (-0.642245,-0.231222) (-0.670712,-0.318836) (-0.705033,-0.424464) (-0.748142,-0.55714) (-0.805167,-0.732645) (-0.885996,-0.981412) (-1.01254,-1.37087) (-1.24509,-2.08658)

I only included 3 chunks of 32 in order to prove they are each different values.

After taking this output and giving it to abs() function to calculate magnitude I noticed I get the same output for every chunk! (example below)

4.3034 19.6234 7.63673 3.20934 2.04401 1.51019 1.20668 1.01287 0.880002 0.784632 0.714117 0.661072 0.62093 0.590747 0.568584 0.553159 0.543646 0.539563 0.54071 0.547141 0.559178 0.577442 0.602943 0.63722 0.682599 0.742638 0.822946 0.932803 1.08861 1.32218 1.70426 2.42983

4.3034 19.6234 7.63673 3.20934 2.04401 1.51019 1.20668 1.01287 0.880002 0.784632 0.714117 0.661072 0.62093 0.590747 0.568584 0.553159 0.543646 0.539563 0.54071 0.547141 0.559178 0.577442 0.602943 0.63722 0.682599 0.742638 0.822946 0.932803 1.08861 1.32218 1.70426 2.42983

4.3034 19.6234 7.63673 3.20934 2.04401 1.51019 1.20668 1.01287 0.880002 0.784632 0.714117 0.661072 0.62093 0.590747 0.568584 0.553159 0.543646 0.539563 0.54071 0.547141 0.559178 0.577442 0.602943 0.63722 0.682599 0.742638 0.822946 0.932803 1.08861 1.32218 1.70426 2.42983

Why am I getting the exact same output out of different inputs? is this normal?

Here is a part of my code which I'm performing all of these calculations:

int main(int argc, char** argv)
{
    int i;
    double y;
    const double Fs = 100;//How many time points are needed i,e., Sampling Frequency
    const double  T = 1 / Fs;//# At what intervals time points are sampled
    const double f = 4;//frequency
    int chuck_size = 32; // chunk size (N / 32=32 chunks)
    Complex chuck[32];
    int j = 0;
    int counter = 0;
    for (int i = 0; i < N; i++)
    {
        t[i] = i * T;
        in[i] = { (0.7 * cos(2 * M_PI * f * t[i])), (0.7 * sin(2 * M_PI * f * t[i])) };// generate (complex) sine waveform
        chuck[j] = in[i];
        //compute FFT for each chunk
        if (i + 1 == chuck_size) // for each set of 32 chunks, apply FFT and save it all in a 1d array (magnitude)
        {
            chuck_size += 32;
            CArray data(chuck, 32);
            fft(data);
            j = 0;
            for (int h = 0; h < 32; h++)
            {
                magnitude[counter] = abs(data[h]);
                std::cout << abs(data[h]) << " ";
                counter++;
            }
            printf("\n\n");

        }
        else
            j++;
    }
}

spectrogram (normalized):

example

yarin Cohen
  • 995
  • 1
  • 13
  • 39
  • First, I ask in general, is this normal behavior? @463035818_is_not_a_number – yarin Cohen May 26 '21 at 22:02
  • I added my code – yarin Cohen May 26 '21 at 22:11
  • Can you make it complete enough to actually compile? If nobody can reproduce your problem, and we cannot even see all of what your code is doing, then how can you hope to get help that's better than a guess? What is 't', Complex, CArray, cos, magnitude, fft, N, in, and so on? Actually, that's way too much code. Your bug could be _anywhere_. Strip it down to something minimal, presentable but complete, that still represents the problem. Also, a link to a godbolt example would help. – Chris Uzdavinis May 26 '21 at 22:25

1 Answers1

4

Your signal is a sine wave. You chop it up. Each segment will have the same frequency components, just a different phase (shift). The FFT gives you both the magnitude and phase for each frequency component, but after abs only the magnitude remains. These magnitudes are necessarily the same for all your chunks.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • Ohh, eventually I'm saving these magnitudes into a 2d array and I draw in into a 32x32 window to show the spectrogram, but it comes up wrong, I thought that was the problem – yarin Cohen May 26 '21 at 22:30
  • @yarin Try modifying the signal so it is not static, for example generate a [chirp signal](https://stackoverflow.com/q/21799697/7328782). – Cris Luengo May 26 '21 at 22:36
  • I edited my post and added a screenshot of the spectrogram I'm getting, does that look normal to you? – yarin Cohen May 26 '21 at 22:39
  • 1
    @yarin It looks like your display clips, showing anything above 1 as white. You might want to normalize before display. – Cris Luengo May 26 '21 at 22:44
  • Wow I have no idea how you caught that, I use openGL and I thought the range for the colors are 0-255, now I just need to realize how to normalize it to be within the 0-1 range, thank you! – yarin Cohen May 26 '21 at 22:52
  • Last thing, I normalized every magnitude value by 32 (length of each chunk) and I think I got the correct spectrogram, can you let me know if you think so too? I edited the post. – yarin Cohen May 26 '21 at 23:05
  • @yarin: You a little over 1 period per 32-sample chunk, so having the peak of the spectrogram being the 2nd bin (k=1) is correct (I'm going by the numerical output you showed towards the top of your question). I'm not sure how these numbers relate to your graphical display. – Cris Luengo May 26 '21 at 23:13
  • according to the abs() output I posted, the peak is 19.6234, so I should divide by that? not sure if I completely understand – yarin Cohen May 26 '21 at 23:18
  • @yarn: Yes, divide by the peak value, so that the peak value becomes 1 and all the other values are scaled in the same way, maintaining the relative intensities the same. – Cris Luengo May 26 '21 at 23:23