IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

fast fourier transform


Sujet :

C++

  1. #1
    Membre habitué
    Inscrit en
    Avril 2006
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 11
    Par défaut fast fourier transform
    Salut a tous,voia mon pb.
    Je veux recuperer le son du micro et savoir qu'elles frequences sont emise.
    je m'aide d'un source qui me donne:

    fft_float(1024,0,Temp1,Temp2,RO,IO);

    RO et IO sont des tableaux de 1024 float de sortie.
    Jusque la ca va mais ensuite je ne sais pas quoi en faire.
    Il faut un calcule pour savoir l'amplitude de chaques frequences.
    J'essais donc celuis ci:

    for (i=0;i<1024;i++){
    Amp[i]=(float)(sqrt(pow(RO[i],2)+pow(IO[i],2)));
    Freq[i]=(float)((44100*(i+1))*2);
    Freq[i]/=Buffer.dwBufferLength;
    }

    Mais quand j'essais avec le micro eteint(donc silence) j'ai quand meme des grosses valeur dans l'amplitude,c'est normal ?.

    Si quelqu'un peut m'aider ,merci.

  2. #2
    Membre habitué
    Inscrit en
    Avril 2006
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 11
    Par défaut reponse
    Merci mais je sais deja aquerir le son depuis un micro.
    Le probleme vient du tableau de sortie.
    Apres la transformer de fourier que dois je faire?.

  3. #3
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Prendre la valeur absolue, comme tu le fais...
    Affiche une fois un graphe de tes valeurs. C'est ta version de la FFT ? Est-ce qu'elle est mise à l'échelle ? - application du 1/T lors de la transformation directe ou inverse ? -
    Enfin, pour qui veut faire du vrai traitement audio, on utilise des hôtes ASIO, pas du DirectX...

  4. #4
    Membre habitué
    Inscrit en
    Avril 2006
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 11
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    void fft_float ( unsigned NumSamples,
                     int    InverseTransform,
                     float  *RealIn,
                     float  *ImagIn,
                     float  *RealOut,
                     float  *ImagOut )
    {
    unsigned NumBits;    /* Number of bits needed to store indices */
    unsigned i, j, k, n;
    unsigned BlockSize, BlockEnd;
     
    float angle_numerator = 2.0F * 3.141592F;
    float delta_angle;
    float alpha, beta;  /* used in recurrence relation */
    float delta_ar;
    float tr, ti;     /* temp real, temp imaginary */
    float ar, ai;     /* angle vector real, angle vector imaginary */
     
    	if (InverseTransform)
    		angle_numerator = -angle_numerator;
    	NumBits = NumberOfBitsNeeded ( NumSamples );
     
    	for ( i=0; i < NumSamples; i++ )
    	{
    		j = ReverseBits ( i, NumBits );
    		RealOut[j] = RealIn[i];
    		ImagOut[j] = ImagIn ? ImagIn[i] : 0.0F;
    	}
     
    	BlockEnd = 1;
    	for ( BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1 )
    	{
    		delta_angle = angle_numerator / (float)BlockSize;
    		alpha = (float)sin(0.5 * delta_angle);
    		alpha = 2.0F * alpha * alpha;
    		beta = (float)sin (delta_angle);
     
    		for ( i=0; i < NumSamples; i += BlockSize )
    		{
    			ar = 1.0;   /* cos(0) */
    			ai = 0.0;   /* sin(0) */
    			 for ( j=i, n=0; n < BlockEnd; j++, n++ )
    			 {
    					k = j + BlockEnd;
    					tr = ar*RealOut[k] - ai*ImagOut[k];
    					ti = ar*ImagOut[k] + ai*RealOut[k];
     
    					RealOut[k] = RealOut[j] - tr;
    					ImagOut[k] = ImagOut[j] - ti;
     
    					RealOut[j] += tr;
    					ImagOut[j] += ti;
     
    					delta_ar = alpha*ar + beta*ai;
    					ai -= (alpha*ai - beta*ar);
    					ar -= delta_ar;
    			 }
    		}
     
    		BlockEnd = BlockSize;
    	}
     
    	if ( InverseTransform )
    	{
    		float denom = (float)NumSamples;
    		for ( i=0; i < NumSamples; i++ )
    		{
    			 RealOut[i] /= denom;
    			 ImagOut[i] /= denom;
    		}
    	}
    }

    Voila mon code fft.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    HWAVEIN	hwi;	//Nouvelle allocation pour le Handle
    WAVEHDR  wh;
    static WAVEFORMATEX wfx;
     
    #define TAILLE_BUFFER     44100
    static short Buffer[TAILLE_BUFFER / 2], BufferTmp[TAILLE_BUFFER / 2] = {0};
     
    float Real[22050]; //tableau d'entree
    float Imag[22050];//tableau imaginaire
    float IOut[22050];//
    float ROut[22050];//tableaux de sortie
    float Amp[22050]; 
    float Freq[22050];
     
     
    Donc je capture le son au micro dans Buffer.
    Buffer[1] = 384 ,Buffer[2]=140,Buffer[50]=139 etc..
     
    Ensuite je les passent en float dans Real:
    	  for (i=0;i<22050;i++){
    Real[i] =(float)Buffer[i];
    	  }
     
    Ensuite je pratique la fft:
    fft_float(22050,0,Real,Imag,ROut,IOut);
     
    Ensuite je cherche l'amplitude pour chaque frequence:
     
    for (i=0;i<22050;i++){
    Amp[i]=(float)(sqrt(pow(ROut[i],2)+pow(IOut[i],2)));
    Freq[i]=(float)((44100*(i+1))*2);
    Freq[i]/=wh.dwBufferLength;
    }
     
    Cela me donne :
    Freq[1]=4   Amp[1]=3.98441e+006
    Freq[2]=6   Amp[2]=241
    Freq[3]=8   Amp[3]=3.98441e+006
    Freq[4]=10   Amp[4]=241
    etc
    Je ne comprend pas ces resultats.
    Merci.

  5. #5
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut

    Et alors ? Je ne vais pas regarder ton code pour savoir quans tu fais la mise à l'échelle, c'est à toi de le savoir si tu l'as codée.

    edit : je regarde, et en 2sec je trouve le code de mise à l'échelle. Tu lis parfois ce que tu écris ?

  6. #6
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Non, ce n'est pas normal...
    Si ton micro est éteint, le spectre devrait quasiment être bul (aux bruits d'acquisition prêt)!
    POur le fft, y'a des choses déjà faites

    http://www.fftw.org/

  7. #7
    Membre habitué
    Inscrit en
    Avril 2006
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 11
    Par défaut
    Non sans lib svp.
    Moi aussi je crois que j'ai foiré quelque part mais ou...

  8. #8
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    - dernière demande...

    Juste pour dire, vu ton code, ça ne m'étonne pas, la réponse de la FFT. Elle peut être bonne. Tu as au moins testé avec un sinus ?

  9. #9
    Membre Expert

    Homme Profil pro
    Inscrit en
    Juillet 2003
    Messages
    2 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 2 075
    Par défaut
    Citation Envoyé par Miles
    - dernière demande...

    Juste pour dire, vu ton code, ça ne m'étonne pas, la réponse de la FFT. Elle peut être bonne. Tu as au moins testé avec un sinus ?
    Balises rajoutées

  10. #10
    Membre habitué
    Inscrit en
    Avril 2006
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 11
    Par défaut
    Ca y est j'ai rectifié le code.
    Maintenent apres la fft j'ai mon tableau : ROut[1024].
    Micro eteint il vaut 0 environ, puis quand je l'allume j'ai des valeurs (20,35,41,...).
    Ca me semble correte jusque la.
    Maintenent comment attribuer ces valeurs aux frequences.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (i=0;i<1024,i++){
    Freq[i]=(44100/1024)*i;
    Amp[i]=ROut[i];
    }
    exmple pour i=1 :
    Freq[1](44100/1024)*1=43,06640625 hz
    Amp[1]=45

    la frequence 43.06hz a une amplitude de 45 db,
    Vous croyez que c'est bon?.
    Merci

  11. #11
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Fais gaffe, tu as un facteur d'échelle dans le tas, n'oublie pas !
    Si tu veux savoir combien de dB, ça fait, prends un signal dont tu connais exactement la puissance et fais la FFT dessus, pour savoir quelle est la puissance effective.

  12. #12
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    C'est en effet la meilleure méthode : un bon cosinus (de durée longue gare aux effets de bords) dont tu connais l'amplitude et hop c'est gagné !
    Il suffit de mesurer l'amplitude du pic obtenue...

    Vérifie au passage la fréquence (dépend de ta fréquence d'échantillonage ) car bon nombre de FTT affiche en fréquence réduite (-0.5 0.5)....

    A+

Discussions similaires

  1. Détection de pics - Fast Fourier Transform
    Par salah16 dans le forum MATLAB
    Réponses: 6
    Dernier message: 29/04/2015, 17h44
  2. Réponses: 0
    Dernier message: 09/04/2012, 12h41
  3. Calcul de Fast Fourier Transform (FFT)
    Par chouchinou dans le forum Traitement du signal
    Réponses: 1
    Dernier message: 03/12/2009, 12h44
  4. Fast Fourier Transform
    Par nicoblade77240 dans le forum Traitement d'images
    Réponses: 2
    Dernier message: 29/09/2009, 12h21
  5. FFT(Fast Fourier Transform)
    Par IngBen dans le forum Traitement du signal
    Réponses: 6
    Dernier message: 23/05/2002, 16h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo