Comme promis, voici le code de la FFT commenté. Il n'est pas optimisé, mais tourne bien (d'autres versions de cette méthode à suivre).
Bonne lecture !
Source / Exemple :
public double[] Calcul_FFT(double[] donnees)
{
nb_donnees = donnees.Length; // longueur tableau de données
fft = new double[nb_donnees]; // Tableau final.
indices_fft = new int[nb_donnees]; // tableau d'indices du Reverse Carry
indices_fft = Reverse_Carry(nb_donnees); // Fonction de calcul du Rev Carry
fft_r = new double[nb_donnees]; // tableau d'indices Réels.
fft_i = new double[nb_donnees]; // tableau d'indices Imaginaires.
// création des tableaux Réels / Imaginaires
for(int cptr_mixage = 0 ; cptr_mixage < nb_donnees ; cptr_mixage++)
{
fft_r[cptr_mixage] = Variables.donnees[indices_fft[cptr_mixage]];
fft_i[cptr_mixage] = 0;
}
// rang de l'algorithme (Papillon) - ici, 9 pour 1024 données
for(int rang_fft = 0, cptr_resultat = 0 ; rang_fft < 10 ; rang_fft++)
{
omega_fft = Math.PI/(Math.Pow(2, rang_fft)); // calcul de Omega
cptr_resultat = 0; // compteur de tableau après calcul - Initialisation
while(cptr_resultat < 1024) // Parcours du tableau
{
for(int largeur = 0 ; largeur < (int) Math.Pow(2, rang_fft) ; largeur++, cptr_resultat++)
{
bn_fft_ind = cptr_resultat + (int) Math.Pow(2, rang_fft); // Calcule l'indice des impairs
fac_cos = Math.Cos(omega_fft*largeur); // Calcule le Cosinus
fac_sin = Math.Sin(omega_fft*largeur); // Calcule le Sinus
an_fft_r = fft_r[cptr_resultat]; // a(n) - PAIR / REEL
an_fft_i = fft_i[cptr_resultat]; // a(n) - PAIR / IMAGINAIRE
bn_fft_r = fft_r[bn_fft_ind]; // b(n) - IMPAIR / REEL
bn_fft_i = fft_i[bn_fft_ind]; // b(n) - IMPAIR / IMAGINAIRE
fft_r[cptr_resultat] = an_fft_r + bn_fft_r*fac_cos + bn_fft_i*fac_sin; // Partie réelle de A(k) - (somme)
fft_i[cptr_resultat] = an_fft_i + bn_fft_i*fac_cos - bn_fft_r*fac_sin; // Partie imaginaire de A(k) - (somme)
fft_r[bn_fft_ind] = an_fft_r - bn_fft_r*fac_cos - bn_fft_i*fac_sin; // Partie réelle de B(k) - (différence)
fft_i[bn_fft_ind] = an_fft_i - bn_fft_i*fac_cos + bn_fft_r*fac_sin; // Partie imaginaire de B(k) - (différence)
}
cptr_resultat = bn_fft_ind+1; // Après la fin de chaque trame (2, 4, 8, 16...), passe à la suivante
}
}
//----------------------------------------------------------------------------------------------------------------------
for(int cptr_fft = 0 ; cptr_fft < nb_donnees ; cptr_fft++) // Boucle de calcul des Amplitudes totales.
{
fft[cptr_fft] = Math.Pow(fft_r[cptr_fft], 2) + Math.Pow(fft_i[cptr_fft], 2);
}
return fft;
}
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.