begin process at 2012 02 14 05:39:24
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Modules

 > TRANSFORMEE DE FOURIER DANS LES APPLICATIONS AUDIO-NUMERIQUES

TRANSFORMEE DE FOURIER DANS LES APPLICATIONS AUDIO-NUMERIQUES


 Information sur la source

Note :
9 / 10 - par 3 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Modules Source .NET ( DotNet ) Classé sous :fourier, fft, transformée, fréquence, spectre Niveau :Initié Date de création :21/02/2006 Date de mise à jour :28/12/2008 00:42:30 Vu :24 033

Auteur : comemich

Ecrire un message privé
Commentaire sur cette source (39)
Ajouter un commentaire et/ou une note

 Description

Le module Fourier comprend les fonctions utiles dans les applications destinees à manipuler le son numerique. Les commentaires fournissent les definitions de base et expliquent le principe. La transformee de Fourier sert a analyser le spectre de fréquences d'un echantillon sonore. La transformee inverse permet de calculer le son apres filtrage des magnitudes.

Source

  • Module ModuleFourier
  • ' Utilitaires pour calculs audio-numériques
  • ' FFT (Fast Fourier Transform) : TRANSFORMEE RAPIDE DE FOURIER
  • ' PCM (Pulse Code Modulation) : modulation par impulsions
  • ' Sampling-Rate : Cadencement (Fréquence des impulsions)
  • ' La transformée de Fourier permet de calculer le spectre de fréquences
  • ' correspondant à l'échantillon PCM de longueur 2^P2 .
  • ' Exemple pour un bloc de 8192 impulsions (2^13),dans un échantillon cadencé à 44100 hz
  • ' on aura une fréquence de base de 44100 / 8192 = 5.38330078125 Hz
  • ' C'est à dire des magnitudes et angles correspondants aux fréquences :
  • ' 10.76 , 16.14 , 21.53 , 26.91 , 32.29 , 37.68 , 43.06 , 48.44 , 53.83 ...
  • ' ... 430.66 , 436.04 , 441.43 , 446.81 ... jusqu'à 22050 Hz (fréquence de Nyquist)
  • ' REMARQUE : On ne connaitra jamais la magnitude exacte du " La 440 " par exemple (diapason)
  • ' Pour celà , il faudrait un échantillon cadencé à : (440 / 82) * 8192 = 43957 Hz
  • Public Structure NombreComplex
  • Public Réel As Double
  • Public Imaginaire As Double
  • End Structure
  • Public Function Fourier(ByVal Suite() As NombreComplex) As NombreComplex()
  • 'Calcule la transformée d'une suite de nombres complexes
  • Dim Nbr As Integer ' Nombre de complexes dans la suite
  • Dim P2 As Byte ' Puissance de 2 du nombre entier Nbr
  • Dim ISuit, ITrans As Integer ' Compteurs de boucles
  • Dim Fin, Taille As Integer ' Butées
  • Dim dAngl, dAr As Double
  • Dim Alpha, Beta As Double
  • Dim k, I, J, L As Integer
  • Dim AR, TR, Ti, AI As Double
  • ' Nbr est la taille de la suite à transformer
  • Nbr = UBound(Suite) + 1 ' Obligatoirement: une puissance de 2
  • P2 = Puissance(Nbr)
  • Dim Transformée(Nbr - 1) As NombreComplex
  • For ISuit = 0 To Nbr - 1
  • ITrans = Ivrs(ISuit, P2)
  • Transformée(ITrans).Réel = Suite(ISuit).Réel
  • Transformée(ITrans).Imaginaire = Suite(ISuit).Imaginaire
  • Next ISuit
  • Fin = 1
  • Taille = 2
  • Do While (Taille <= Nbr)
  • dAngl = 2 * Math.PI / Taille
  • Alpha = 2 * ((System.Math.Sin(0.5 * dAngl)) ^ 2)
  • Beta = System.Math.Sin(dAngl)
  • I = 0
  • Do While (I < Nbr)
  • AR = 1 ' Cosinus(0)
  • AI = 0 ' Sinus(0)
  • J = I
  • For L = 1 To Fin
  • k = J + Fin
  • TR = AR * Transformée(k).Réel - AI * Transformée(k).Imaginaire
  • Ti = AI * Transformée(k).Réel + AR * Transformée(k).Imaginaire
  • Transformée(k).Réel = Transformée(J).Réel - TR
  • Transformée(k).Imaginaire = Transformée(J).Imaginaire - Ti
  • Transformée(J).Réel = Transformée(J).Réel + TR
  • Transformée(J).Imaginaire = Transformée(J).Imaginaire + Ti
  • dAr = Alpha * AR + Beta * AI
  • AI = AI - (Alpha * AI - Beta * AR)
  • AR = AR - dAr
  • J = J + 1
  • Next L
  • I = I + Taille
  • Loop
  • Fin = Taille
  • Taille = Taille * 2
  • Loop
  • Return Transformée
  • End Function
  • Public Function Inverse(ByVal Transformée() As NombreComplex) As NombreComplex()
  • 'Calcule la transformée inverse d'une suite de nombres complexes
  • Dim Nbr As Integer ' Nombre de complexes dans la suite
  • Dim P2 As Byte ' Puissance de 2 du nombre entier Nbr
  • Dim ISuit, ITrans As Integer ' Compteurs de boucles
  • Dim Fin, Taille As Integer ' Butées
  • Dim dAngl, dAr As Double
  • Dim Alpha, Beta As Double
  • Dim k, I, J, L As Integer
  • Dim AR, TR, Ti, AI As Double
  • ' Nbr est la taille de la Transformée à transformer
  • Nbr = UBound(Transformée) + 1 ' Obligatoirement: une puissance de 2
  • P2 = Puissance(Nbr)
  • Dim Suite(Nbr - 1) As NombreComplex
  • For ISuit = 0 To Nbr - 1
  • ITrans = Ivrs(ISuit, P2)
  • Suite(ITrans).Réel = Transformée(ISuit).Réel
  • Suite(ITrans).Imaginaire = Transformée(ISuit).Imaginaire
  • Next ISuit
  • Fin = 1
  • Taille = 2
  • Do While (Taille <= Nbr)
  • dAngl = -2 * Math.PI / Taille
  • Alpha = 2 * ((System.Math.Sin(0.5 * dAngl)) ^ 2)
  • Beta = System.Math.Sin(dAngl)
  • I = 0
  • Do While (I < Nbr)
  • AR = 1 ' Cosinus(0)
  • AI = 0 ' Sinus(0)
  • J = I
  • For L = 1 To Fin
  • k = J + Fin
  • TR = AR * Suite(k).Réel - AI * Suite(k).Imaginaire
  • Ti = AI * Suite(k).Réel + AR * Suite(k).Imaginaire
  • Suite(k).Réel = Suite(J).Réel - TR
  • Suite(k).Imaginaire = Suite(J).Imaginaire - Ti
  • Suite(J).Réel = Suite(J).Réel + TR
  • Suite(J).Imaginaire = Suite(J).Imaginaire + Ti
  • dAr = Alpha * AR + Beta * AI
  • AI = AI - (Alpha * AI - Beta * AR)
  • AR = AR - dAr
  • J = J + 1
  • Next L
  • I = I + Taille
  • Loop
  • Fin = Taille
  • Taille = Taille * 2
  • Loop
  • For I = 0 To UBound(Suite)
  • Suite(I).Réel = 2 * Suite(I).Réel \ Nbr
  • Suite(I).Imaginaire = 2 * Suite(I).Imaginaire \ Nbr
  • Next I
  • Return Suite
  • End Function
  • Public Function Magnitude(ByVal Transformée() As NombreComplex) As Double()
  • Dim Id As Integer
  • Id = UBound(Transformée) \ 2
  • Dim M(Id) As Double
  • For Id = 0 To UBound(M)
  • M(Id) = Math.Sqrt(Math.Pow(Transformée(Id).Réel, 2) + Math.Pow(Transformée(Id).Imaginaire, 2))
  • Next
  • Return M
  • End Function
  • Public Function Ivrs(ByVal IdPuls As Integer, ByVal P2 As Byte) As Integer
  • Dim I As Short
  • Ivrs = 0
  • For I = 1 To P2
  • Ivrs = (Ivrs * 2) Or (IdPuls And 1)
  • IdPuls = IdPuls \ 2
  • Next I
  • End Function
  • Public Function Puissance(ByVal Entier As Integer) As Byte
  • Return Int(Math.Log(Entier) / Math.Log(2))
  • End Function
  • End Module
Module ModuleFourier
    
    ' Utilitaires pour calculs audio-numériques

    ' FFT (Fast Fourier Transform) : TRANSFORMEE RAPIDE DE FOURIER

    ' PCM (Pulse Code Modulation) : modulation par impulsions
    ' Sampling-Rate : Cadencement (Fréquence des impulsions) 

    ' La transformée de Fourier permet de calculer le spectre de fréquences 
    ' correspondant à l'échantillon PCM de longueur 2^P2 .
    ' Exemple pour un bloc de 8192 impulsions (2^13),dans un échantillon cadencé à 44100 hz
    ' on aura une fréquence de base de 44100 / 8192 =   5.38330078125 Hz
    ' C'est à dire des magnitudes et angles correspondants aux fréquences :
    ' 10.76 ,   16.14 , 21.53 ,   26.91 , 32.29 ,   37.68 , 43.06 ,   48.44 , 53.83   ...
    ' ... 430.66 ,  436.04 , 441.43 , 446.81 ... jusqu'à  22050 Hz (fréquence de Nyquist)
    ' REMARQUE : On ne connaitra jamais la magnitude exacte du " La 440 " par exemple (diapason)
    ' Pour celà , il faudrait un échantillon cadencé à : (440 / 82) * 8192 = 43957 Hz

    Public Structure NombreComplex
        Public Réel As Double
        Public Imaginaire As Double
    End Structure

    Public Function Fourier(ByVal Suite() As NombreComplex) As NombreComplex()

        'Calcule la transformée d'une suite de nombres complexes

        Dim Nbr As Integer ' Nombre de complexes dans la suite
        Dim P2 As Byte ' Puissance de 2 du nombre entier Nbr
        Dim ISuit, ITrans As Integer ' Compteurs de boucles
        Dim Fin, Taille As Integer ' Butées
        Dim dAngl, dAr As Double
        Dim Alpha, Beta As Double
        Dim k, I, J, L As Integer
        Dim AR, TR, Ti, AI As Double

        ' Nbr est la taille de la suite à transformer
        Nbr = UBound(Suite) + 1 ' Obligatoirement: une puissance de 2
        P2 = Puissance(Nbr)

        Dim Transformée(Nbr - 1) As NombreComplex

        For ISuit = 0 To Nbr - 1
            ITrans = Ivrs(ISuit, P2)
            Transformée(ITrans).Réel = Suite(ISuit).Réel
            Transformée(ITrans).Imaginaire = Suite(ISuit).Imaginaire
        Next ISuit

        Fin = 1
        Taille = 2
        Do While (Taille <= Nbr)
            dAngl = 2 * Math.PI / Taille
            Alpha = 2 * ((System.Math.Sin(0.5 * dAngl)) ^ 2)
            Beta = System.Math.Sin(dAngl)

            I = 0
            Do While (I < Nbr)
                AR = 1 ' Cosinus(0)
                AI = 0 ' Sinus(0)

                J = I
                For L = 1 To Fin
                    k = J + Fin
                    TR = AR * Transformée(k).Réel - AI * Transformée(k).Imaginaire
                    Ti = AI * Transformée(k).Réel + AR * Transformée(k).Imaginaire
                    Transformée(k).Réel = Transformée(J).Réel - TR
                    Transformée(k).Imaginaire = Transformée(J).Imaginaire - Ti
                    Transformée(J).Réel = Transformée(J).Réel + TR
                    Transformée(J).Imaginaire = Transformée(J).Imaginaire + Ti
                    dAr = Alpha * AR + Beta * AI
                    AI = AI - (Alpha * AI - Beta * AR)
                    AR = AR - dAr
                    J = J + 1
                Next L
                I = I + Taille
            Loop
            Fin = Taille
            Taille = Taille * 2
        Loop
        Return Transformée
    End Function

    Public Function Inverse(ByVal Transformée() As NombreComplex) As NombreComplex()

        'Calcule la transformée inverse d'une suite de nombres complexes

        Dim Nbr As Integer ' Nombre de complexes dans la suite
        Dim P2 As Byte ' Puissance de 2 du nombre entier Nbr
        Dim ISuit, ITrans As Integer ' Compteurs de boucles
        Dim Fin, Taille As Integer ' Butées
        Dim dAngl, dAr As Double
        Dim Alpha, Beta As Double
        Dim k, I, J, L As Integer
        Dim AR, TR, Ti, AI As Double

        ' Nbr est la taille de la Transformée à transformer
        Nbr = UBound(Transformée) + 1 ' Obligatoirement: une puissance de 2
        P2 = Puissance(Nbr)

        Dim Suite(Nbr - 1) As NombreComplex

        For ISuit = 0 To Nbr - 1
            ITrans = Ivrs(ISuit, P2)
            Suite(ITrans).Réel = Transformée(ISuit).Réel
            Suite(ITrans).Imaginaire = Transformée(ISuit).Imaginaire
        Next ISuit

        Fin = 1
        Taille = 2
        Do While (Taille <= Nbr)
            dAngl = -2 * Math.PI / Taille
            Alpha = 2 * ((System.Math.Sin(0.5 * dAngl)) ^ 2)
            Beta = System.Math.Sin(dAngl)

            I = 0
            Do While (I < Nbr)
                AR = 1 ' Cosinus(0)
                AI = 0 ' Sinus(0)

                J = I
                For L = 1 To Fin
                    k = J + Fin
                    TR = AR * Suite(k).Réel - AI * Suite(k).Imaginaire
                    Ti = AI * Suite(k).Réel + AR * Suite(k).Imaginaire
                    Suite(k).Réel = Suite(J).Réel - TR
                    Suite(k).Imaginaire = Suite(J).Imaginaire - Ti
                    Suite(J).Réel = Suite(J).Réel + TR
                    Suite(J).Imaginaire = Suite(J).Imaginaire + Ti
                    dAr = Alpha * AR + Beta * AI
                    AI = AI - (Alpha * AI - Beta * AR)
                    AR = AR - dAr
                    J = J + 1
                Next L
                I = I + Taille
            Loop
            Fin = Taille
            Taille = Taille * 2
        Loop
        For I = 0 To UBound(Suite)
            Suite(I).Réel = 2 * Suite(I).Réel \ Nbr
            Suite(I).Imaginaire = 2 * Suite(I).Imaginaire \ Nbr
        Next I
        Return Suite
    End Function

    Public Function Magnitude(ByVal Transformée() As NombreComplex) As Double()
        Dim Id As Integer
        Id = UBound(Transformée) \ 2
        Dim M(Id) As Double
        For Id = 0 To UBound(M)
            M(Id) = Math.Sqrt(Math.Pow(Transformée(Id).Réel, 2) + Math.Pow(Transformée(Id).Imaginaire, 2))
        Next
        Return M
    End Function

    Public Function Ivrs(ByVal IdPuls As Integer, ByVal P2 As Byte) As Integer
        Dim I As Short
        Ivrs = 0

        For I = 1 To P2
            Ivrs = (Ivrs * 2) Or (IdPuls And 1)
            IdPuls = IdPuls \ 2
        Next I

    End Function

    Public Function Puissance(ByVal Entier As Integer) As Byte
        Return Int(Math.Log(Entier) / Math.Log(2))
    End Function

End Module

 Conclusion

Remerciements: Don Cross et Jean Debord


 Historique

02 mars 2006 20:39:22 :
Modification du libellé et dans la formulation de la présentation. Remplacement de Pi = 3.14159265358979 par Math.PI (suggéré par Patrice99 dans les commentaires)
28 décembre 2008 00:42:30 :
La valeur de magnitude était injustement divisée par deux

 Sources du même auteur

Source .NET (Dotnet) RESOLUTION D'UNE EQUATION DU TROISIEME DEGRE

 Sources de la même categorie

Source avec Zip Source .NET (Dotnet) CRYPTAGE ET DECRYPTAGE par jerichez
Source avec Zip Source avec une capture Source .NET (Dotnet) EXEMPLE MODBUS POUR MODULES ADAM, BECKHOFF, WAGO par mnmsjaune
Source avec Zip Source .NET (Dotnet) CRÉER SON PROPRE DESIGNER COMME CELUI DE VISUAL STUDIO par ShareVB
Source avec Zip Source .NET (Dotnet) CONVERSION UTM VERS LAT/LONG par BarresLTD
Source avec Zip CPROPGROUP : COLLECTION FAITE MAISON par Flocreate

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture TRANSFORMÉE DE FOURRIER (PAS FFT) par Flocreate
Source avec Zip Source avec une capture Source .NET (Dotnet) ANALYSE DE SIGNAL AUDIO-NUMÉRIQUE par Orohena
Source avec Zip ANALYSE SPECTRALE SOUS EXCEL (TFR OU FFT) par Patrice99
Source avec Zip Source avec une capture Source .NET (Dotnet) SPECTRE DE FICHIER WAVE par Hakumbaya
Source avec Zip Source avec une capture Source .NET (Dotnet) VBWAVECOMP : LE COMPARATEUR DE SPECTRE AUDIO EN VB .NET par Patrice99

Commentaires et avis

Commentaire de Patrice99 le 22/02/2006 08:44:06

Evite de coder PI ainsi : tu perds un peu de précision, utilise plutot Math.PI
Voir aussi :
http://patrice.dargenton.free.fr/vbwavecomp/index.html
http://patrice.dargenton.free.fr/vbwavecomp/VBWaveCompSrc.html

Commentaire de AbriBus le 22/02/2006 14:00:45

Salut,
Tout ca me semble un peu obscur dans son application finale... apres quelques recherche sur le net, j'ai cru comprendre que fourier pouvait etre utilisé pour le cadage de Mp3 (?)
Serait-il possible d'avoir plus d'informations quand à l'application du calcul de la transformee de fourier ?

AbriBus

Commentaire de jazzd2 le 22/03/2006 13:23:44

La transformée de fourrier, sans rentrer dans les détails, sert à pas mal de choses dans l'analyse du signal. Elle est utilisé pour faire apparaitre les fréquences d'un signal. Elle est utilisé pour le son, les signaux acquis dans l'industrie, le traitement d'image.... en gros chaque fois que tu veux analyser un signal pour trouver certaines infos c'est une des méthodes utilisées.

Commentaire de AbriBus le 22/03/2006 14:33:21

Salut,
tout d'abord, merc jazzd2 pour l'info... mais, toujours sans rentrer dans des détails indescents, quel est le genre d'info qu'on recupere par ces methode ? la qualité, la puissance, l'integrité ...?
En fait la question, c'est quel est l'objectif final d'une telle analyse (je ne doute pas ici qu'il y en a une...)?

Commentaire de Patrice99 le 22/03/2006 17:05:46

La TF donne le spectre du signal, c'est-à-dire la distribution (répartition) des fréquences contenues dans le signal, ce qui est utile par exemple pour l'audio, pour savoir l'énergie du signal qui risque d'être perdu selon le type d'écouteur.
Voir par exemple :
http://patrice.dargenton.free.fr/vbwavecomp/index.html

Commentaire de Arnal88 le 20/05/2007 15:17:28

Merci énormément comemich ! Je cherchais depuis un moment des infos sur la transformée de Fourier car je développe un mini-oscillo en VB 2005 et je veux ajouter une fonction analyseur de spectre, mais pas moyen de trouver une description de l'algorithme... Sans celui que tu as posté (et qui fonctionne parfaitement !!) je n'y serais jamais arrivé...
Par contre j'ai essayé de le comprendre mais ça reste un peu obscur... Je m'en sers donc sans savoir comment ça marche (ce qui n'est pas un problème : l'essentiel est que ça marche...)
Bref, merci c'est très utile !!

Commentaire de ninja hacker le 05/10/2007 14:08:13

Bonjour!

Je cherche et je cherche mais je ne trouve pas ce que je veux. Je veux analyser le spectre d'un fichier audio. J'ai limpression que le code plus haut dans la page fait cette action mais je ne le comprend pas. Est-ce que vous pouriez me l'expliquer un peu plus en détail et surtout m'expliquer comment pouvoir men servir pour analyser le spectre d'un fichier audio. Merci!

Commentaire de Arnal88 le 06/10/2007 15:02:19

Ben...
c'est pas simple. Ca dépend de ton niveau d'étude en maths.. Je suis en classe préparatoire aux grandes écoles (maths sup), donc je comprends ce que fait ce code.
Mais pour cela, il faut savoir ce qu'est un nombre complexe, une intégrale et avoir un minimum de bases en analyse de Fourier.

Je vais essayer d'expliquer comment s'en servir sans connaissance importantes en maths..
Mais c'est compliqué et je vais simplifier au maximum.

Toute fonction mathématique périodique peut (sous certaines conditions) se décomposer en une somme infinie de cosinus et de sinus d'amplitude et de fréquences différentes.
Par exemple, un signal en créneaux de fréquence 1Hz :
f(t) = 4/Pi * ( sin(2Pi*t) + sin(2Pi*3*t)/3 + sin(2Pi*5*t)/5 + ......)

Le but de la transformée de Fourier est de récupérer l'amplitude de chaque sinus.
Pour chaque fréquence, on a la valeur de l'amplitude correspondante : c'est le spectre.
Le spectre est la représentation du signal dans le domaine des fréquences.

Donc si le signal est l'enregistrement d'un diapason, on va avoir un pic de fréquence à 440Hz, la fréquence du la.

Maintenant, si ce que je raconte est pas clair, direction Google pour plus d'infos...

Le problème est que le signal sonore que l'on veut analyser n'est pas continu, mais numérisé. En clair, c'est une suite de nombres. Les matheux ont donc inventé la transformée de Fourier discrète. C'est cette transformée que l'on utilise avec les signaux numérisés.

Le code ci dessus est celui de la FFT (Fast Fourier Transform, ou Transformée de Fourier Rapide).
C'est une version de la transformée discrète bien plus rapide à calculer. Mais elle n'est rapide que si le nombre d'échantillons est une puissance de 2

Premier impératif pour utiliser ce code :
- utiliser un nombre d'échantillons en puissance de 2 (512, 2048... échantillons)
Si ton signal audio contient trop de valeurs, il faudra le racourcir.

Ce module utilise des nombres complexes. C'est des nombres qui comportent une partie réelle et une partie imaginaire. Mais je vais expliquer comment s'en servir même si tu ne sais pas ce que c'est...

Comment entrer des échantillons dans la moulinette :
- Déclarer un tableau (de longueur puissance de 2, rappelle-toi!) en tant que complexe :

  Dim Signal(511) As NombreComplex

- Pour chaque valeur du tableau, entrer la valeur du signal dans la partie réelle, et mettre 0 dans la partie imaginaire :

  For i As Integer = 0 to 511
    Signal(i).Réel = .... (la valeur du ième échantillon)
    Signal(i).Imaginaire = 0
  Next i

- Déclarer un tableau pour recevoir le résultat :

  Dim Résultat(511) As NombreComplex

- Exécuter la FFT. Le paramètre sera Signal(), et le résultat sera stocké dans Résultat()

  Résultat = Fourier(Signal)

Le tableau Résultat contient maintenant le spectre, mais sous forme de nombres complexes. Pour avoir l'amplitude, il faut récupérer le module de chaque nombre complexe :

  Dim Spectre(511) As Single

  For i As Integer = 0 To 511
    Spectre(i) = Math.Sqrt(Résultat(i).Réel ^ 2 + Résultat(i).Imaginaire ^ 2)
  Next i

Voilà, c'est fini. Le spectre est maintenant contenu dans le tableau Spectre.
On peut alors le tracer par exemple.


Oui, mais... (parce qu'il y a forcément un mais...)
On a l'amplitude de chaque fréquence, mais quelle est la valeur de la fréquence ??

Je m'explique : Spectre(25) vaut 15.4 par exemple.
A quelle valeur de fréquence correspond le 15.4 ?

Et bien cela dépend du signal original. Cela dépend en fait de sa fréquence d'échantillonage, et du nombre d'échantillons que l'on a pris.
Pour des signaux sonores issus d'un CD, c'est 44100 Hz.

Donc si on prend 512 échantillons à 44100 Hz, voilà ce qu'on va avoir :

Spectre(0) correspond à 0 Hz
Spectre(1) correspond à 44100 / 512 = 86.1 Hz
Spectre(2) correspond à 2 * 44100 / 512 = 172.3 Hz
..
Spectre(i) correspond à i * 44100 / 512
..
Spectre(256) correspond à 22050 Hz

Et après : stop ! (voir remarque...)


Remarque :

Si on traite 512 échantillons (comme dans le cas précédent), on n'utilise que les 257 premières valeurs du spectre, c'est à dire de Spectre(0) jusqu'à Spectre(256).
En effet, les valeurs de fréquence suivantes sont les mêmes que celles d'avant, donc elles n'apportent rien.

Si tu traces le tableau Spectre(i) pour i allant de 0 à 511, tu auras une courbe symétrique.
C'est à dire Spectre(0) = Spectre(511), Spectre(2) = Spectre(509) ect...

Donc tu récupères les fréquences de 0 jusqu'à 22050 Hz (la moitié de la fréquence d'échantillonnage)


Voilà pour une rapide explication, mais qui devrait cependant permettre d'utiliser le formidable code de comemich (c'est pas lui qui l'a inventé, mais on ne le remerciera jamais assez de l'avoir écrit en VB2005)

J'ai essayé de faire mon explication aussi complète que possible. Je me concentre sur la mise en oeuvre de ce code.

Mais pour la théorie, ou pour comprendre correctement l'analyse de Fourier, il faut un minimum de connaissances en maths..

VIVE LES MATHS !





Commentaire de comemich le 06/10/2007 17:08:30

Bravo ARNAL88 pour tes explications.

Afin de faciliter la compréhension du mode d' emploi , j' ai écrit une petite application qui utilise le module de Fourier. C' est une illustration de ce qu' on peut faire en audio-numérique avec la transformée rapide de Fourier. Un exemple vaut souvent mieux que de longs discours.

DémoFFT analyse un fichier wave contenant une note de musique.

- Calcule le spertre de fréquences et affiche le graphique
- Analyse le spectre pour savoir où est la fréquence fondamentale et ses harmoniques
- En déduit le nom de la note qui a été jouée. (Do Ré Mi Fa Sol La Si)

Télécharger l' archive :
http://michelcome@free.fr/solutiondemofft.zip

COMEMICH

Commentaire de comemich le 06/10/2007 18:11:50


ERRATUM : l'URL de DémoFFT

http://michelcome.free.fr/solutiondemofft.zip

Bien sûr !

Commentaire de Arnal88 le 06/10/2007 18:45:15

Merci pour tes encouragements..

C'est vrai que je me suis un peu laissé aller côté longueur.. J'ai essayé d'être complet.
Mais il y a tellement de choses à dire ! J'aurais pu en écrire le double.

En tout cas, maintenant tout le monde pourra utiliser ton code sans trop de soucis !

PS : pour ma part, je suis en train de bosser sur la FFT elle-même pour comprendre comment l'algorithme fonctionne. Je n'aime pas utiliser des trucs que je ne comprends pas...

Commentaire de Arnal88 le 06/10/2007 18:53:16

Pas mal ton petit programme.. C'est bien fait. Il montre ce qu'on peut faire avec la FFT.

Tu nous fais quand la transformée en ondelettes ??  ;)

Commentaire de comemich le 06/10/2007 23:28:46

Oh la la ! N'en demandes pas trop.
Si tu es aussi bon en englais qu' en math, je te conseille:
http://www.dsprelated.com/groups/adsp/show/4302.php

Commentaire de Arnal88 le 06/10/2007 23:57:29

Ok, je me débrouille un peu en maths (pas trop le choix) mais je préfère la physique. Faut voir le nombre d'applications que peut avoir la FFT en physique !!

Concernant les ondelettes, c'est pour te charier ! Je n'en connais que le principe.

Je conseille fortement le site du lycée le Dantec : http://www.lycee-ledantec.ac-rennes.fr/
Fouillez dans Articles > Tutorial Ondelettes. C'est vraiment bien expliqué ! Et il traite aussi de la transformée de Fourier...

Commentaire de ninja hacker le 17/10/2007 23:24:13

wow Merci!

Ont a une chouete communauté ici a vb france :). J'ai pas encore tout tester les indications dans vos commentaire. Je viens de finir de les lires (j'avais pas eu le temps de revenir depuis un petit bout de temps) et c'est fou! bravo Arnal tu ma fais comprend un peu plus ce qu'était le FFT. Je suis encore confu par l'algorithme mais je m'estime déja bien de comprendre tout ca n'entend qu'en secondaire 4! Bref je telecharge ta source a l'instant Comemich. Merci encore pour tout =D

Commentaire de ninja hacker le 18/10/2007 02:51:37

Est-il possible d'utuliser le microphone comme source a analyser en temps réel avec ce code? (désolé n'ayant pas les capacité VB et mathématique pour résoudre se probleme je dois posé beaucoup de questions... c'est pour un projet d'expo science a mon école)

Commentaire de ninja hacker le 18/10/2007 03:02:00

Ah et j'oubliais comment as tu créer tes fichier wav? j'essai dutuliser mon micro pour enregistrer un de mes diapason et je ne peu pas l'ouvrir avec ton code. J'ai essailler de le sauvegarder avec un taux d'échantillonage de 44Khz, taille de l'échantillion 16 bit en PCM et mono comme tes fichier fourni mais je ne peux pas plus les ouvrir. Une idée?

Commentaire de comemich le 18/10/2007 18:20:47

Je dois reconaitre que je ne suis pas très fier de ma routine pour lire dans les fichiers wave car je n' ai pas beaucoup d' information la dessus. Je suis bien incapable d'assurer une lecture fiable. Est ce que quelqu'un a de la doc là dessus ?. Mon intention, au départ, c' était juste de distribuer la FFT. Le reste, c' était juste pour expliquer comment s' en servir. Mais tout n'est pas très propre là dedans. Il ne faut pas prendre ça pour du bon pain . Ce n'est surement pas un exemple à suivre.
Enregistre avec Sndrec32.exe de Microsoft. C'est livré avec Windows et ça fait des fichiers généralement lisibles par ma routine. Mais pour faire plus sérieux, il serait souhaitable de trouver une source mieux adaptée.

Commentaire de Patrice99 le 19/10/2007 15:21:50

Voici ma liste actuelle de liens pour lire un fichier wav :

- [.Net2] Lecture fichier .cda + Extraction piste audio d'un CD
  www.csharpfr.com/code.aspx?ID=41094

- WAVE File Processor in C#
  www.codeproject.com/useritems/WAVE_Processor_In_C_.asp

- Utilitaire pour créer des wav contenant des fréquences données : NCH Tone Generator
  www.world-voices.com/software/nchtone.html

- Générateur de fichier wav de référence pour CD de test
  www.cppfrance.com/code.aspx?ID=34327

- Compose sounds from frequencies and visualize them, By Corinna John
  What you never wanted to know about PCM
  www.codeproject.com/cs/media/wavemixer.asp

- www.codeproject.com/useritems/Concatenation_Wave_Files.asp en C# 2005

- CD audio : http://fr.wikipedia.org/wiki/Disque_compact

Commentaire de galinabuzz le 07/04/2008 21:04:12 7/10

salut et tout d'abord merci pour ce joli code ^^
Je dois toute fois vous exposer le problème auquel je suis confronté.
J'ai voulu tester cette transormée de fourier en y mettant en entrée une somme de 4 sinusoïdes de fréquences 2500, 3500, 4500, 5500Hz et de mêmes amplitudes.
Lorsque j'ai tracé le résultat ds un graphique (excel), il s'est avéré que les amplitudes des raies correspondant à chaque sinus étaient très différentes (je n'ai plus les chiffres en tête). Ceci me pose un gros problème car je souhaiterais calculer le niveau de pression équivalent d'un signal audio issus d'un micro, et pour ce faire, il est impératif que les amplitudes soient correctes.
Voilà, si mon problème est plus lié à une erreur de compréhension de ma part, s'il vous plait faites le moi savoir.
Merci d'avance

Commentaire de comemich le 07/04/2008 23:38:55

Les magnitudes maxi correspondent bien aux fréquences des sinusoïdes que vous avez ajoutées. Qu'entendez vous par "les amplitudes des raies correspondant à chaque sinus étaient très différentes " ?

Commentaire de galinabuzz le 08/04/2008 16:25:01

Et bien en fait, j'ai envoyé 4 sinusoïdes de mêmes amplitudes. Par contre, les 4 raies issues de la fft n'avaient pas les mêmes amplitudes. Je ne suis pas sur d'être beaucoup plus clair...

Bon, exemple :
signal d'entrée :
e(t) = A*sinus(2*pi*2500*t)+A*sinus(2*pi*3500*t)+A*sinus(2*pi*4500*t)+A*sinus(2*pi*5500*t)
A étant l'amplitude du signal.

je récupère en sortie :
- une raie à 2500Hz d'amplitude B
- une raie à 3500Hz d'amplitude C
- une raie à 4500Hz d'amplitude D
- une raie à 5500Hz d'amplitude E
avec B, C, D et E différents!! Alors qu'ils devraient être égaux...

Je ne crois pas (je n'espère pas ^^) dire de bêtise. Quoi qu'il en soit, merci de vous être penché sur mon problème.

Commentaire de comemich le 08/04/2008 23:15:58

La transformée de Fourier permet de calculer le spectre de fréquences correspondant à l'échantillon PCM dont la longueur est obligatoirement une puissance de 2 .
Exemple pour un bloc de 8192 impulsions (2^13),dans un échantillon cadencé à 44100 hz on aura une fréquence de base de 44100 / 8192 =   5.38330078125 Hz C'est à dire des magnitudes et angles correspondants aux fréquences : 10.76 ,   16.14 , 21.53 ,   26.91 , 32.29 ,   37.68 , 43.06 ,   48.44 , 53.83...  jusqu'à  22050 Hz .(fréquence de Nyquist)
REMARQUE : On ne connaitra jamais la magnitude exacte correspondant à 2500 Hz car ce n'est pas un multiple de 5.3833
Pour celà , il faudrait un échantillon cadencé à : 2500 * 8192 / 464 = 44138 Hz.
La magnitude que vous calculez avec un échantillon de 8192 valeurs d'une onde cadencée à 44100 Hz correspond à une fréquence de 2497.85 Hz et non 2500 comme vous l'auriez souhaité. L'imprécision du résultat vient de là.
Il faut utiliser la FFT avec prudence !

Commentaire de Patrice99 le 09/04/2008 08:28:57

Normalement, il suffit d'augmenter le nombre de bits de la TFR pour s'approcher du résultat exact, les amplitudes devraient être conservées, sauf petites imprécisions.
Voir aussi :
http://patrice.dargenton.free.fr/publications/these.html#_Toc483625179
Ici est montré comment générer et tester des signaux avec la TFR :
http://patrice.dargenton.free.fr/vbwavecomp/VBWaveComp.html

Commentaire de Arnal88 le 09/04/2008 18:45:59 10/10

galinabuzz, quand tu dis que les amplitudes sont différentes, est ce que tu peux préciser ?
Si A est 2 fois plus élevé que B, alors il y a un problème, mais si c'est seulement de quelques pourcent, c'est normal ! Cela vient de l'algorithme lui-même..

PS : Le code de comemich mérite bien un petit 10/10 (j'avais oublié de le mettre à l'époque..)

Commentaire de galinabuzz le 09/04/2008 18:51:54

Et bien en fait j'avais fait la transformée sur 32768 (2^15) échantillons, donc, en ce qui concerne la fréquence, j'étais relativement proche de la valeur exacte.
Quoi qu'il en soit je devrais normalement réussir à me débrouiller avec les petites variations d'amplitude que j'ai constaté.
Donc je vous remercie, d'une part pour votre code et d'autre part pour votre aide ^^

PS : à Patrice99, merci pour ces liens, je m'empresse d'aller les lire

Commentaire de galinabuzz le 09/04/2008 19:10:37

Alors voilà, j'ai refait le test afin de pouvoir vous en montrer le résultat.
Les valeurs du signal ont été générées comme suit :

        For i = 0 To NumSamples - 1    'NumSamples = 32768
            t = (i / fe)
            With suite(i)
                .Reel = 0
                For j = 1 To 80
                    .Reel = .Reel + System.Math.Sin(2 * system.math.Pi * (j * 250) * t)
                Next
                .Imaginaire = 0
            End With
        Next

Et en sortie je récupère le spectre hébérgé à cette adresse : http://www.imagup.com/imgs/1207758580.html

Il y a, je trouve, tout de même une certaine différence entre certains pics. Dites-moi, s'il vous plait, si je fais une erreur quelque part.

Commentaire de galinabuzz le 09/04/2008 19:18:10

Je n'arrive pas à éditer mon message donc désolé pour le double post.
J'ai juste oublié de préciser que fe = 44100

Commentaire de comemich le 09/04/2008 22:07:35

Je vous remercie beaucoup de l'intérêt que vous portez à ma contribution FFT. J'avais entrepris de développer un échantillonneur (sampler) mais comme je n'ai pas un niveau très élevé en mathématiques, j'avais du mal à m'en sortir avec les problèmes de spectre de fréquences. J'ai pu surmonter ces difficultés grace aux sites de Don Cross et Jean Debord que je remercie. Mais j'ai un peu galéré pour mettre au point le code Visual Basic. Aussi, j'ai pensé que ça pouvait rendre service à d'autres internautes pour bricoler, comme moi, des applications audio-numériques.Je suis content de constater que vous êtes nombreux à utiliser ce code.
J'utilise la FFT pour localiser les pics et donc identifier les notes dont on connait la fréquence théorique. La précision n'est donc pas un problème dans ce cas. J'aurais même un résultat juste avec un musicien qui joue faux !.
Dans le cas qui semble intéresser GALINABUZZ , il faut augmenter la dimension de l'échantillon pour améliorer la précision comme le suggère PATRICE99. Cette méthode a ses limites: Outre le fait que les temps de calcul s'allongent, il faut disposer d'un échantillon sonore suffisant. 32768 c'est déjà presque une seconde. En musique, il n'est pas courant qu'une note dure aussi longtemps.

Commentaire de Patrice99 le 10/04/2008 08:29:22

Oui, une fois que l'échantillon à analyser loge completement dans la fenetre de calcul, il n'est plus nécessaire d'augmenter la taille de la fenetre, les résultats seront les memes.

Commentaire de Orohena le 27/12/2008 01:19:16


Bonjour

Bravo comemich pour ce code

D'abord, je suis béotien en fft, et je ne travaille sur ce sujet que depuis quelques jours, donc il ne faut pas m'en vouloir si ma question n'est pas pertinente.

Voila, je souhaiterais savoir pourquoi la fonction Magnitude retourne un tableau dont le Dim est égal à la moitié du Dim du tableau Transformées, et seule la première moitié du tableau Transformée est traitée.

Merci par avance

Commentaire de comemich le 27/12/2008 21:05:01

En réalité, le tableau de la transformée a la même dimension que le tableau d'origine mais les valeurs qu'il contient sont symétriques. Donc, seule la moitier est utilisable.

Commentaire de Orohena le 27/12/2008 23:32:26


Bonjour comemich

Merci pour ta réponse limpide. Il est vrai que comme je ne connais rien aux fft, cette symétrie n'était pas évidente.

Est-ce que je peux t'importuner avec une autre question ?
Dans cette même fonction, tu divises par deux la racine carrée pour obtenir l'amplitude, alors que dans les explications d'arnal82, cette division n'apparaît pas. Cela veut-il dire qu'une magnitude donnée n'a pas de signification, et qu'il faut seulement s'intéresser aux magnitudes relatives du spectre ?

Merci encore

Commentaire de comemich le 27/12/2008 23:52:50

Je ne sais pas pourquoi on divise par deux. J'ai trouvé la recette de cuisine numérique sur le site de Jean Debord et je l'ai mise au goût de visual Basic mais je ne sais pas, dans le détail, ce qui fait le succès de la sauce.

Commentaire de Orohena le 28/12/2008 00:10:51


ok, merci en tout cas pour ta recette de cuisine. De toute façon, dans un premier temps, c'est l'amplitude relative qui m'intéresse, donc pas de souci.
Voila, c'est tout, merci encore et bonne année.

Commentaire de comemich le 28/12/2008 00:28:54

Je viens de me renseigner sur le site de Jean Debord. C'est effectivement une erreur de diviser par deux. J'ai mal interprèté l'expression "Double Magnitude" en turbo Pascal qui ne représente pas une valeur deux fois supérieure à la magnitude, mais la valeur de magnitude en double précision.
Dans la pratique, ça ne change pas grand chose. Comme tu l'as dit, ce sont les valeurs relatives qui nous intéressent quand on analyse le spectre. Mais pour plus de rigueur mathématique, il serait souhaitable de corriger le code de la ligne 52 comme suit:

M(Id) = Math.Sqrt(Math.Pow(Transformée(Id).Réel, 2) + Math.Pow(Transformée(Id).Imaginaire, 2))
    

Commentaire de Orohena le 28/12/2008 01:55:05 10/10


J'ai corrigé et je t'ai mis 10/10 dans la foulée, parce que tu as vraiment fait du bon boulot.

Commentaire de cheyenne le 13/11/2010 16:53:46

Bonjour comemich,

Merci pour le code et les explications.

En plus de la visualisation du spectre je voudrais faire également un vu-mètre(ou un bargraph pour chaque voie et j'aimerai savoir quelle peut être la magnitude maximum d'un signal.

Merci et bon week-end.

Cheyenne

Commentaire de comemich le 13/11/2010 20:39:40

Théoriquement, la magnitude est comprise entre -1,79769313486231570E+308 et 1,79769313486231570E+308 mais dans la pratique,je ne sais pas.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Fmod et les fréquences dans le spectre. Comment savoir quelle fréquence correspond à quelle donnée ? [ par azerty25 ] Hello allVous connaissez peut etre la librairie sonnore Fmod, qui permet de lire des fichiers son mais aussi de pouvoir créer un spectre à partir des Plusieurs courbes sur le même graph MSChart [ par merif ] Bonjour à tous !Je dispose d'un graph MSChart de type 2dXY sur lequel je souhaite tracer des spectres que j'acquiers les un après les autres. A chaque Analyse de la fréquence d'une source audio [ par Yanou60 ] Bonjour,je souhaiterai pouvoir analyser un son wav ou mp3, en donnant un fréquence d'échantillonage et récupérer les fréquences.Quelqu'un peut il m'ai Comment faire un spectre [ par unrealgun ] Bonjour,Comment je peux faire un spectre pour mon player ?merci d'avance.The DAMIRATOR FFT [ par cubinou ] salut je suis a la recherche d'une code soource me permettant de passer d'une FFT 1D a une FFT 2D. J'ai deja une fonction qui me permet de faire la F FFT 1D a 2D en JAVA [ par cubinou ] Salut a tous Je suis a la recherche du petit bout de code me manquant pour passer d'une FFT 1D A une FFT 2D. C'est pourdu traitement d'image. Et j'ai Comment générer le spectre d'un son ? [ par sydailly ] Salut tout le monde, Je cherche &#224; g&#233;n&#233;rer le Recherche Transformé de Fourrier en VB 6.0 [ par avillenave ] Bonjour &#224; tous,J'ai besoin d'une fonction : La fft -&gt; la transform&#233;e de FourrierJe ne m'interresse qu'&#224; la partie r&#233;elle du r&# Frequence de rafraichissement dans un .exe [ par darksoul551 ] &nbsp;&nbsp;&nbsp; Bonjour a tous, j'ai une petite question a poser, j'ai cherch&#233; sur les sources et sur google mais j'ai pas trouv&#233;; je la Analyse fréquence audio sur carte son [ par f8bpz ] Salut,Je souhaite creer une application qui analyserai la frequence des sons pr&#233;sents sur l'entree de la carte son (mic. ou aux.). Apr&#232;s de


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,546 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales