2014-05-21 5 views
1

J'ai un problème lors de la mise en œuvre d'un algorithme FFT dans Android. Disons que j'ai un fichier wav de 8.000 octets de longueur. Je suis conscient que vous devez sélectionner une taille de l'algorithme FFT (et doit également être une puissance de 2). Mon problème est que je ne suis pas vraiment sûr de la marche à suivre à partir de maintenant. Disons que j'ai choisi une taille de la FFT de N = 1024. J'ai fondamentalement des options dans mon esprit: 1) Appliquez l'algorithme FFT directement à l'ensemble du tableau de 8.000 octets 2) Divisez le fichier wav 8000 octets de tableau en blocs de 1024 octets (et remplissez avec 0 le dernier morceau jusqu'à ce que vous ayez 8 blocs exacts), , puis appliquez le fft à chacun de ces blocs et enfin regroupez tous les différents blocs pour avoir un seul tableau d'octets à représenter. Je pense que c'est l'option 2 mais je ne suis pas tout à fait sûr.Mise en œuvre du tableau FFT

Voici le tableau fft que j'utilise:

package com.example.acoustics; 

public class FFT { 

    int n, m; 

    // Lookup tables. Only need to recompute when size of FFT changes. 
    double[] cos; 
    double[] sin; 

    public FFT(int n) { 
     this.n = n; 
     this.m = (int) (Math.log(n)/Math.log(2)); 

     // Make sure n is a power of 2 
     if (n != (1 << m)) 
      throw new RuntimeException("FFT length must be power of 2"); 

     // precompute tables 
     cos = new double[n/2]; 
     sin = new double[n/2]; 

     for (int i = 0; i < n/2; i++) { 
      cos[i] = Math.cos(-2 * Math.PI * i/n); 
      sin[i] = Math.sin(-2 * Math.PI * i/n); 
     } 

    } 

    /*************************************************************** 
    * fft.c 
    * Douglas L. Jones 
    * University of Illinois at Urbana-Champaign 
    * January 19, 1992 
    * http://cnx.rice.edu/content/m12016/latest/ 
    * 
    * fft: in-place radix-2 DIT DFT of a complex input 
    * 
    * input: 
    * n: length of FFT: must be a power of two 
    * m: n = 2**m 
    * input/output 
    * x: double array of length n with real part of data 
    * y: double array of length n with imag part of data 
    * 
    * Permission to copy and use this program is granted 
    * as long as this header is included. 
    ****************************************************************/ 

    public void fft(double[] x, double[] y) { 
     int i, j, k, n1, n2, a; 
     double c, s, t1, t2; 

     // Bit-reverse 
     j = 0; 
     n2 = n/2; 
     for (i = 1; i < n - 1; i++) { 
      n1 = n2; 
      while (j >= n1) { 
       j = j - n1; 
       n1 = n1/2; 
      } 
      j = j + n1; 

      if (i < j) { 
       t1 = x[i]; 
       x[i] = x[j]; 
       x[j] = t1; 
       t1 = y[i]; 
       y[i] = y[j]; 
       y[j] = t1; 
      } 
     } 

     // FFT 
     n1 = 0; 
     n2 = 1; 

     for (i = 0; i < m; i++) { 
      n1 = n2; 
      n2 = n2 + n2; 
      a = 0; 

      for (j = 0; j < n1; j++) { 
       c = cos[a]; 
       s = sin[a]; 
       a += 1 << (m - i - 1); 

       for (k = j; k < n; k = k + n2) { 
        t1 = c * x[k + n1] - s * y[k + n1]; 
        t2 = s * x[k + n1] + c * y[k + n1]; 
        x[k + n1] = x[k] - t1; 
        y[k + n1] = y[k] - t2; 
        x[k] = x[k] + t1; 
        y[k] = y[k] + t2; 
       } 
      } 
     } 
    } 
} 
+1

Que voulez-vous faire exactement avec le résultat de la FFT? Pour la plupart des applications pratiques, vous devez diviser le tableau de données en blocs qui se chevauchent, appliquer le fenêtrage, faire la FFT, faire le filtrage/modification, faire la FFT inverse et ajouter les résultats en utilisant la même structure de chevauchement. Le fenêtrage peut être agencé pour être une division d'unité, de sorte que, sans modifications, le réseau original est obtenu comme résultat de ces opérations. – LutzL

+0

J'essaie de tracer le spectre FFT comme ceux-ci: [Plot] (http://www.mathworks.com/help/signal/ug/periodogram_psd.png) – paviflo

Répondre

1

Je pense que vous pouvez utiliser tout le réseau avec la FFT. Il n'y a pas de problème avec cela, vous pouvez utiliser 2^13 = 8192 et compléter le tableau avec des zéros, ce traitement est également appelé remplissage zéro et est utilisé dans plus d'une implémentation de la FFT. Si votre procédure fonctionne bien, il n'y a pas de problème avec l'ensemble du tableau, mais si vous utilisez la section 1024 pour calculer la FFT, vous aurez une transformée de Fourier segmentée qui ne décrit pas bien le spectre complet du signal, car la FFT utilisez toutes les positions dans le tableau pour calculer chaque valeur dans le nouveau tableau transformé, alors vous n'obtenez pas la bonne réponse dans la position un par exemple si vous n'utilisez pas le tableau entier du signal. Ceci est mon analyse de votre question Je ne suis pas sûr à cent pour cent mais mes connaissances sur les séries de Fourier me disent que c'est presque ce qui se passe si vous calculez une forme segmentée de la transformée de Fourier plutôt que toute la série.

+1

Oui, il est préférable d'utiliser le tout lorsque cela est possible . Cependant, je pense que le nombre de remplissage devrait être la valeur moyenne des entrées. Ou normaliser les données avant de remplir avec des zéros. Ai-je tort? L'idée, selon moi, est de faire ressembler le son au silence. S'il y a un décalage DC, le silence n'est pas nul. –