Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Spectrogram and FFT using OpenGL

  1. #1
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281

    Spectrogram and FFT using OpenGL

    Hi,

    I have read the Sonographic Sound Processing page at http://designingsound.org/2013/04/24...nd-processing/ and think to use OpenGL fragment shaders for to implement the conversion of .wav file to a spectrogram

    The only thing that I think to modify compared to this page is to treat chunks of sound by rows instead colums, cf. handle each temporal chunk of sound on a different line instead on a different column

    I think to directly map the PCM/ADPCM 8/4 bits data into the texture image with the stereo/quadriphonic channels mapped into R,G,B and A colors channels and make the PCM/ADPCM to float conversion directly into the fragment shader for to have a very memory space efficient sheme
    (the windowing function has of course to be computed into the fragment shader for to be too really memory efficient)

    How can I make the shader for to compute the FFT on a entire line, cf. a chunk of about 1/44 milliseconds = one line on a 1024 texture image , with interleaved Left/Right (or Left Front/Left Back/Right Front/Right Back) channels stored on a PCM format (or ADPCM for a quadriphonic sound), and/or exist an OpenGL's shader library that can already handle this ?

    My problem is not about the handling of stereo/quadriphonic, I can basically handle this with the copy of the left and right stéréo channels to the Left Front/Back and Right Front/Back quadriphonics channels or the PCM conversion than can easily to be handled using only an external paletted texture access

    It is more about the ADPCM handling that have to compute the final channel value relative to the previous channel sample value and the computation of the Fourrier Transform that need to access alls values of a channel on a line for to compute each of the 1024 Fourrier Transform coefficients for this line
    Last edited by The Little Body; 07-13-2018 at 07:09 PM.
    @+
    Yannoo

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,999
    FFTs are a fairly common application of shaders (either compute shaders or fragment shaders with render-to-texture). But you'd normally use log2(N) passes for N samples. You wouldn't try to compute a FFT in a single call because you need all of the values in each pass to be computed before starting the next pass.

  3. #3
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    Thank, GClements

    You say "FFTs are a fairly common application of shaders"

    => where can I find somes complete examples, please ?

    I have googled about this but don't find something that is fully fonctionnal
    @+
    Yannoo

  4. #4
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    I have begin to test the Fast Fourrier Transform from http://paulbourke.net/miscellaneous/dft/ for to understand how the FFT wotk but I don't understand results

    The real part is only 0.5f and the imaginary part is 0.0f at the wanted frequency when I use the simple signal(angle) = cos( angle )

    The real part is 1.0f and the imaginary part is always 0.0f at the wanted frequency when I use the signal(angle) = cos(angle + i sin(angle)

    What sort of "Fourrier transform" other than the DFT/FFT have I to handle if I want 1.0f for the real part and 1.0f for the imaginary part at the wanted frequency when I use signal(angle) = cos(angle) + i sin(angle) ???

    Here are the content of files I use :

    1) fft.h
    Code :
    #ifndef _FFT_H_
    #define _FFT_H_
    /*
       This computes an in-place complex-to-complex DFT 
     x and y are the real and imaginary arrays of 2^m points.
       dir =  1 gives forward transform
       dir = -1 gives reverse transform 
    */
    int DFT( int dir, int m, double *x1, double *y1 );
     
    /*
       This computes an in-place complex-to-complex FFT 
       x and y are the real and imaginary arrays of 2^m points.
       dir =  1 gives forward transform
       dir = -1 gives reverse transform 
    */
    int FFT( int dir, long m, double *x, double *y );
     
     
    #endif /* _FFT_H_ */

    fft.c
    Code :
    include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
     
    #define FALSE 0
    #define TRUE  1
     
    /*
       Direct fourier transform
    */
    int DFT( int dir, int m, double *x1, double *y1 )
    {
       long i,k;
       double arg;
       double cosarg,sinarg;
       double *x2=NULL,*y2=NULL;
     
       x2 = malloc( m * sizeof(double));
       y2 = malloc( m * sizeof(double));
     
       if (x2 == NULL || y2 == NULL)
          return(FALSE);
     
       for ( i = 0 ; i < m ; i++ ) {
          x2[i] = 0;
          y2[i] = 0;
          arg = - dir * 2.0 * 3.141592654 * (double)i / (double)m;
          for ( k = 0 ; k < m ; k++ ) {
             cosarg = cos(k * arg);
             sinarg = sin(k * arg);
             x2[i] += (x1[k] * cosarg - y1[k] * sinarg);
             y2[i] += (x1[k] * sinarg + y1[k] * cosarg);
          }
       }
     
       /* Copy the data back */
       if (dir == 1) {
          for ( i = 0 ; i < m; i++ ) {
             x1[i] = x2[i] / (double)m;
             y1[i] = y2[i] / (double)m;
          }
       } else {
          for ( i = 0 ; i < m ; i++ ) {
             x1[i] = x2[i];
             y1[i] = y2[i];
          }
       }
     
       free(x2);
       free(y2);
       return(TRUE);
    }
     
     
    /*
       This computes an in-place complex-to-complex FFT 
       x and y are the real and imaginary arrays of 2^m points.
       dir =  1 gives forward transform
       dir = -1 gives reverse transform 
    */
    int FFT( int dir, int m, double *x, double *y )
    {
       long n,i,i1,j,k,i2,l,l1,l2;
       double c1,c2,tx,ty,t1,t2,u1,u2,z;
     
       /* Calculate the number of points */
       n = 1;
       for ( i = 0 ; i < m ; i++ ) 
          n *= 2;
     
       // printf("n= %ld \n", n);
     
       /* Do the bit reversal */
       i2 = n >> 1;
       j = 0;
       for ( i = 0 ; i < n -1 ; i++ ) {
          if (i < j) {
             tx = x[i];
             ty = y[i];
             x[i] = x[j];
             y[i] = y[j];
             x[j] = tx;
             y[j] = ty;
          }
          k = i2;
          while  (k <= j ) {
             j -= k;
             k >>= 1;
          }
          j += k;
       }
     
       // printf("/* Compute the FFT */ \n");
     
       c1 = -1.0; 
       c2 = 0.0;
       l2 = 1;
       for (l=0;l<m;l++) {
          l1 = l2;
          l2 <<= 1;
          u1 = 1.0; 
          u2 = 0.0;
          for (j=0;j<l1;j++) {
             for (i=j;i<n;i+=l2) {
                i1 = i + l1;
                t1 = u1 * x[i1] - u2 * y[i1];
                t2 = u1 * y[i1] + u2 * x[i1];
                x[i1] = x[i] - t1; 
                y[i1] = y[i] - t2;
                x[i] += t1;
                y[i] += t2;
             }
             z =  u1 * c1 - u2 * c2;
             u2 = u1 * c2 + u2 * c1;
             u1 = z;
          }
          c2 = sqrt((1.0 - c1) / 2.0);
          if (dir == 1) 
             c2 = -c2;
          c1 = sqrt((1.0 + c1) / 2.0);
       }
     
       /* Scaling for forward transform */
       if (dir == 1) {
          for (i=0;i<n;i++) {
             x[i] /= n;
             y[i] /= n;
          }
       }
     
       return(TRUE);
    }

    test.c
    Code :
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <stdbool.h>
     
    #include "fft.h"
     
    #define EPSILON 0.001f
     
     
    int size = 16;
    int size2 = 4;
     
    double *reals;
    double *images;
     
    void CreateArrays( int n )
    {
        reals  = malloc( (n+1) * sizeof(double) );
        images = malloc( (n+1) * sizeof(double) );
    }
     
    void FreeArrays()
    {
        free(reals);
        free(images);
    }
     
    void InitArraysCos( int n, float freq )
    {
        int i;
     
        double angle, delta;
     
        angle = 0.0f;
        delta = 2.0f * M_PI / (float)(n);
     
        for( i =  0 ; i < n ; i++ )
        {
            reals[i]  = cos( angle * freq );
            images[i] = 0.0f;
     
            angle += delta;
        }
    }
     
    void InitArraysCosSin( int n, float freq )
    {
        int i;
     
        double angle, delta;
     
        angle = 0.0f;
        delta = 2.0f * M_PI / (float)(n);
     
        for( i =  0 ; i < n ; i++ )
        {
            reals[i]  = cos( angle * freq );
            images[i] = sin( angle * freq );
     
            angle += delta;
        }
    }
     
     
    void PrintArrays( int n, bool zeroes )
    {
        int i;
     
        for( i = 0 ; i < n ; i++ )
        {
            if( (fabs(reals[i]) > EPSILON ) || (fabs(images[i]) > EPSILON ) || ( zeroes == true ) )
            {
                printf("    Freq[%d] = (%f , %f) \n", i, reals[i], images[i] );
            }
        }
    }  
     
    int main( int argc , char **argv)
    {
        float freq;
     
        printf("FFT v0.1 by Cyclone \n");
     
        CreateArrays(size);
     
        for( freq = 1 ; freq < size / 2 ; freq++)
        {
            printf("\n\nInit Arrays signal(angle) = cos(angle) for freq %1f Hz ... \n\n", freq);
            InitArraysCos(size, freq);
            // PrintArrays(size, true);
     
            printf("\n\nCompute DFT  for freq %1f Hz ... \n\n", freq);
            InitArraysCos(size, freq);
            DFT(1, size, reals, images);
            PrintArrays(size / 2, false);
     
            printf("\n\nCompute FFT for freq %1f Hz... \n\n", freq);
            InitArraysCos(size, freq);
            FFT(1, size2, reals, images);
             PrintArrays(size / 2 , false);
     
            printf("\n\n    ----------------------- \n\n");
     
            printf("\n\nInit Arrays signal(angle) = cos(angle) + i sin(angle) for freq %1f Hz ... \n\n", freq);
            InitArraysCosSin(size, freq);
            // PrintArrays(size, true);
     
            printf("\n\nCompute DFT  for freq %1f Hz ... \n\n", freq);
            InitArraysCosSin(size, freq);
            DFT(1, size, reals, images);
            PrintArrays(size / 2, false);
     
            printf("\n\nCompute FFT for freq %1f Hz... \n\n", freq);
            InitArraysCosSin(size, freq);
            FFT(1, size2, reals, images);
             PrintArrays(size / 2 , false);
     
            printf("\n\n    ======================= \n\n");
     
        }
     
     
        FreeArrays();
     
        return 0;
    }

    makefile
    Code :
    all : fft.o test
     
    fft.o : fft.c
        gcc -c fft.c -o fft.o
     
    test : test.c fft.o
        gcc test.c fft.o -o test -lm
     
    clean :
        rm fft.o test

    and the result of the execution of ./test
    Code :
    FFT v0.1 by Cyclone 
     
     
    Init Arrays signal(angle) = cos(angle) for freq 1.000000 Hz ... 
     
     
     
    Compute DFT  for freq 1.000000 Hz ... 
     
        Freq[1] = (0.500000 , -0.000000) 
     
     
    Compute FFT for freq 1.000000 Hz... 
     
        Freq[1] = (0.500000 , -0.000000) 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 1.000000 Hz ... 
     
     
     
    Compute DFT  for freq 1.000000 Hz ... 
     
        Freq[1] = (1.000000 , -0.000000) 
     
     
    Compute FFT for freq 1.000000 Hz... 
     
        Freq[1] = (1.000000 , 0.000000) 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 2.000000 Hz ... 
     
     
     
    Compute DFT  for freq 2.000000 Hz ... 
     
        Freq[2] = (0.500000 , -0.000000) 
     
     
    Compute FFT for freq 2.000000 Hz... 
     
        Freq[2] = (0.500000 , 0.000000) 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 2.000000 Hz ... 
     
     
     
    Compute DFT  for freq 2.000000 Hz ... 
     
        Freq[2] = (1.000000 , -0.000000) 
     
     
    Compute FFT for freq 2.000000 Hz... 
     
        Freq[2] = (1.000000 , 0.000000) 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 3.000000 Hz ... 
     
     
     
    Compute DFT  for freq 3.000000 Hz ... 
     
        Freq[3] = (0.500000 , -0.000000) 
     
     
    Compute FFT for freq 3.000000 Hz... 
     
        Freq[3] = (0.500000 , 0.000000) 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 3.000000 Hz ... 
     
     
     
    Compute DFT  for freq 3.000000 Hz ... 
     
        Freq[3] = (1.000000 , -0.000000) 
     
     
    Compute FFT for freq 3.000000 Hz... 
     
        Freq[3] = (1.000000 , -0.000000) 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 4.000000 Hz ... 
     
     
     
    Compute DFT  for freq 4.000000 Hz ... 
     
        Freq[4] = (0.500000 , -0.000000) 
     
     
    Compute FFT for freq 4.000000 Hz... 
     
        Freq[4] = (0.500000 , 0.000000) 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 4.000000 Hz ... 
     
     
     
    Compute DFT  for freq 4.000000 Hz ... 
     
        Freq[4] = (1.000000 , -0.000000) 
     
     
    Compute FFT for freq 4.000000 Hz... 
     
        Freq[4] = (1.000000 , 0.000000) 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 5.000000 Hz ... 
     
     
     
    Compute DFT  for freq 5.000000 Hz ... 
     
        Freq[5] = (0.500000 , -0.000000) 
     
     
    Compute FFT for freq 5.000000 Hz... 
     
        Freq[5] = (0.500000 , 0.000000) 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 5.000000 Hz ... 
     
     
     
    Compute DFT  for freq 5.000000 Hz ... 
     
        Freq[5] = (1.000000 , -0.000000) 
     
     
    Compute FFT for freq 5.000000 Hz... 
     
        Freq[5] = (1.000000 , 0.000000) 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 6.000000 Hz ... 
     
     
     
    Compute DFT  for freq 6.000000 Hz ... 
     
        Freq[6] = (0.500000 , -0.000000) 
     
     
    Compute FFT for freq 6.000000 Hz... 
     
        Freq[6] = (0.500000 , -0.000000) 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 6.000000 Hz ... 
     
     
     
    Compute DFT  for freq 6.000000 Hz ... 
     
        Freq[6] = (1.000000 , -0.000000) 
     
     
    Compute FFT for freq 6.000000 Hz... 
     
        Freq[6] = (1.000000 , -0.000000) 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 7.000000 Hz ... 
     
     
     
    Compute DFT  for freq 7.000000 Hz ... 
     
        Freq[7] = (0.500000 , -0.000000) 
     
     
    Compute FFT for freq 7.000000 Hz... 
     
        Freq[7] = (0.500000 , 0.000000) 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 7.000000 Hz ... 
     
     
     
    Compute DFT  for freq 7.000000 Hz ... 
     
        Freq[7] = (1.000000 , -0.000000) 
     
     
    Compute FFT for freq 7.000000 Hz... 
     
        Freq[7] = (1.000000 , 0.000000) 
     
     
        =======================

    It exist something like a Fast Discret Cosinus Transform, a Fast Discret Sinus Transform and/or a "Fast Discret Cosinus Transform for the real part mixed with a Fast Sinus Transform for the imaginary part" ?

    And/or can I use the real part for the left channel and the imaginary part for the right channel on a stereo sound for example ?
    (if this is only a story of multiply by two for to have values that I want, it is not really a problem)
    Last edited by The Little Body; 07-18-2018 at 04:26 PM.
    @+
    Yannoo

  5. #5
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,999
    Quote Originally Posted by The Little Body View Post
    The real part is only 0.5f and the imaginary part is 0.0f at the wanted frequency when I use the simple signal(angle) = cos( angle )
    For a real signal, the DFT has conjugate symmetry: y[N-i]=y[i]*.

    Note that eix+e-ix=2·cos(x) and eix-e-ix=2i·sin(x). Also note that eix has period 2π, so e-ix=e2π-ix. So when you take a signal with frequency f and add the image at F-f (where F is the sampling frequency), the imaginary parts cancel and the real part is doubled.

    If you're using this for a spectral display, you just want the magnitude: |z|=sqrt(Re(z)2+Im(z)2). The phase can be ignored.

  6. #6
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    At first view the thing that I search seem to be the Short Time Fourrier Transform, cf. STFT like explained at https://en.wikipedia.org/wiki/Short-...rete-time_STFT

    => this speak of the use of the STFT for to make a spectrogram, so this is relatively certainly what I search
    @+
    Yannoo

  7. #7
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    Thanks GClements;

    If you're using this for a spectral display, you just want the magnitude: |z|=sqrt(Re(z)2+Im(z)2). The phase can be ignored.
    => I think that is what I search
    @+
    Yannoo

  8. #8
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    I have replaced the print of values computed by the FFT but this is always only the half of 1.0f that I find, cf. 0.5f instead 1.0f

    Code :
    void PrintArrays( int n, bool zeroes )
    {
        int i;
     
        for( i = 0 ; i < n ; i++ )
        {
            if( (fabs(reals[i]) > EPSILON ) || (fabs(images[i]) > EPSILON ) || ( zeroes == true ) )
            {
                printf("    Freq[%d] = (%f , %f) [magnitude=%f] \n", 
                    i, reals[i], images[i], sqrt( pow(reals[i], 2.0f) + pow(images[i], 2.0f) ) );
            }
        }
    }

    This give this now
    (the problem of 0.5f values instead 1.0f is always here )
    Code :
    FFT v0.1 by Cyclone 
     
     
    Init Arrays signal(angle) = cos(angle) for freq 1.000000 Hz ... 
     
     
     
    Compute DFT  for freq 1.000000 Hz ... 
     
        Freq[1] = (0.500000 , -0.000000) [magnitude=0.500000] 
     
     
    Compute FFT for freq 1.000000 Hz... 
     
        Freq[1] = (0.500000 , -0.000000) [magnitude=0.500000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 1.000000 Hz ... 
     
     
     
    Compute DFT  for freq 1.000000 Hz ... 
     
        Freq[1] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 1.000000 Hz... 
     
        Freq[1] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 2.000000 Hz ... 
     
     
     
    Compute DFT  for freq 2.000000 Hz ... 
     
        Freq[2] = (0.500000 , -0.000000) [magnitude=0.500000] 
     
     
    Compute FFT for freq 2.000000 Hz... 
     
        Freq[2] = (0.500000 , 0.000000) [magnitude=0.500000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 2.000000 Hz ... 
     
     
     
    Compute DFT  for freq 2.000000 Hz ... 
     
        Freq[2] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 2.000000 Hz... 
     
        Freq[2] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 3.000000 Hz ... 
     
     
     
    Compute DFT  for freq 3.000000 Hz ... 
     
        Freq[3] = (0.500000 , -0.000000) [magnitude=0.500000] 
     
     
    Compute FFT for freq 3.000000 Hz... 
     
        Freq[3] = (0.500000 , 0.000000) [magnitude=0.500000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 3.000000 Hz ... 
     
     
     
    Compute DFT  for freq 3.000000 Hz ... 
     
        Freq[3] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 3.000000 Hz... 
     
        Freq[3] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 4.000000 Hz ... 
     
     
     
    Compute DFT  for freq 4.000000 Hz ... 
     
        Freq[4] = (0.500000 , -0.000000) [magnitude=0.500000] 
     
     
    Compute FFT for freq 4.000000 Hz... 
     
        Freq[4] = (0.500000 , 0.000000) [magnitude=0.500000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 4.000000 Hz ... 
     
     
     
    Compute DFT  for freq 4.000000 Hz ... 
     
        Freq[4] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 4.000000 Hz... 
     
        Freq[4] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 5.000000 Hz ... 
     
     
     
    Compute DFT  for freq 5.000000 Hz ... 
     
        Freq[5] = (0.500000 , -0.000000) [magnitude=0.500000] 
     
     
    Compute FFT for freq 5.000000 Hz... 
     
        Freq[5] = (0.500000 , 0.000000) [magnitude=0.500000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 5.000000 Hz ... 
     
     
     
    Compute DFT  for freq 5.000000 Hz ... 
     
        Freq[5] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 5.000000 Hz... 
     
        Freq[5] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 6.000000 Hz ... 
     
     
     
    Compute DFT  for freq 6.000000 Hz ... 
     
        Freq[6] = (0.500000 , -0.000000) [magnitude=0.500000] 
     
     
    Compute FFT for freq 6.000000 Hz... 
     
        Freq[6] = (0.500000 , -0.000000) [magnitude=0.500000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 6.000000 Hz ... 
     
     
     
    Compute DFT  for freq 6.000000 Hz ... 
     
        Freq[6] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 6.000000 Hz... 
     
        Freq[6] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 7.000000 Hz ... 
     
     
     
    Compute DFT  for freq 7.000000 Hz ... 
     
        Freq[7] = (0.500000 , -0.000000) [magnitude=0.500000] 
     
     
    Compute FFT for freq 7.000000 Hz... 
     
        Freq[7] = (0.500000 , 0.000000) [magnitude=0.500000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 7.000000 Hz ... 
     
     
     
    Compute DFT  for freq 7.000000 Hz ... 
     
        Freq[7] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 7.000000 Hz... 
     
        Freq[7] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        =======================


    => it's normal ?
    @+
    Yannoo

  9. #9
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    Note that eix+e-ix=2·cos(x) and eix-e-ix=2i·sin(x). Also note that eix has period 2π, so e-ix=e2π-ix. So when you take a signal with frequency f and add the image at F-f (where F is the sampling frequency), the imaginary parts cancel and the real part is doubled.
    => if I understand good, it's normal

    Lot of thanks for your help, GClements
    @+
    Yannoo

  10. #10
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    This don't seem to work

    I have replace the display of FFT coefficients like this :
    Code :
    void PrintArrays( int n, bool zeroes )
    {
        int i;
     
        double realpart;
        double imgpart;
     
        for( i = 0 ; i < n ; i++ )
        {
            if( (fabs(reals[i]) > EPSILON ) || (fabs(images[i]) > EPSILON ) || ( zeroes == true ) )
            {
                realpart = reals[i] + reals[size-i];
                imgpart  = images[i] + images[size-i];
     
                printf("    Freq[%d] = (%f , %f) [magnitude=%f] \n", 
                    i, realpart, imgpart, sqrt( pow(realpart, 2.0f) + pow(imgpart, 2.0f) ) );
            }
        }
    }

    But this give this :
    Code :
    FFT v0.1 by Cyclone 
     
     
    Init Arrays signal(angle) = cos(angle) for freq 1.000000 Hz ... 
     
     
     
    Compute DFT  for freq 1.000000 Hz ... 
     
        Freq[1] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 1.000000 Hz... 
     
        Freq[1] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 1.000000 Hz ... 
     
     
     
    Compute DFT  for freq 1.000000 Hz ... 
     
        Freq[1] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 1.000000 Hz... 
     
        Freq[1] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 2.000000 Hz ... 
     
     
     
    Compute DFT  for freq 2.000000 Hz ... 
     
        Freq[2] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 2.000000 Hz... 
     
        Freq[2] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 2.000000 Hz ... 
     
     
     
    Compute DFT  for freq 2.000000 Hz ... 
     
        Freq[2] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 2.000000 Hz... 
     
        Freq[2] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 3.000000 Hz ... 
     
     
     
    Compute DFT  for freq 3.000000 Hz ... 
     
        Freq[3] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 3.000000 Hz... 
     
        Freq[3] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 3.000000 Hz ... 
     
     
     
    Compute DFT  for freq 3.000000 Hz ... 
     
        Freq[3] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 3.000000 Hz... 
     
        Freq[3] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 4.000000 Hz ... 
     
     
     
    Compute DFT  for freq 4.000000 Hz ... 
     
        Freq[4] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 4.000000 Hz... 
     
        Freq[4] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 4.000000 Hz ... 
     
     
     
    Compute DFT  for freq 4.000000 Hz ... 
     
        Freq[4] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 4.000000 Hz... 
     
        Freq[4] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 5.000000 Hz ... 
     
     
     
    Compute DFT  for freq 5.000000 Hz ... 
     
        Freq[5] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 5.000000 Hz... 
     
        Freq[5] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 5.000000 Hz ... 
     
     
     
    Compute DFT  for freq 5.000000 Hz ... 
     
        Freq[5] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 5.000000 Hz... 
     
        Freq[5] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 6.000000 Hz ... 
     
     
     
    Compute DFT  for freq 6.000000 Hz ... 
     
        Freq[6] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 6.000000 Hz... 
     
        Freq[6] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 6.000000 Hz ... 
     
     
     
    Compute DFT  for freq 6.000000 Hz ... 
     
        Freq[6] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 6.000000 Hz... 
     
        Freq[6] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
        ======================= 
     
     
     
    Init Arrays signal(angle) = cos(angle) for freq 7.000000 Hz ... 
     
     
     
    Compute DFT  for freq 7.000000 Hz ... 
     
        Freq[7] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 7.000000 Hz... 
     
        Freq[7] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        ----------------------- 
     
     
     
    Init Arrays signal(angle) = cos(angle) + i sin(angle) for freq 7.000000 Hz ... 
     
     
     
    Compute DFT  for freq 7.000000 Hz ... 
     
        Freq[7] = (1.000000 , -0.000000) [magnitude=1.000000] 
     
     
    Compute FFT for freq 7.000000 Hz... 
     
        Freq[7] = (1.000000 , 0.000000) [magnitude=1.000000] 
     
     
        =======================

    => I don't understand why cos(angle) and cos(angle) + i sin(angle) give now exactly the same FFTs

    ==> we "loose" the imaginery part of the original complex signal when we compute the FFT ???

    But OK, computed non zeroes coefficients are now good 1.0f instead 0.5f
    Last edited by The Little Body; 07-18-2018 at 05:24 PM.
    @+
    Yannoo

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •