2009-03-02 10 views
95

Sto cercando di creare un analizzatore di spettro grafico in python.Analizza audio utilizzando la trasformata di Fourier veloce

Attualmente sto leggendo 1024 byte di un flusso audio a 16 bit a 16 bit a frequenza di campionamento a 44.100 Hz e calcolando la media dell'ampiezza dei 2 canali. Quindi ora ho una serie di 256 cortometraggi firmati. Ora voglio preformare un fft su quell'array, usando un modulo come numpy, e usare il risultato per creare l'analizzatore dello spettro grafico, che, per iniziare, sarà solo 32 bar.

Ho letto gli articoli di wikipedia su Trasformata di Fourier veloce e Trasformata di Fourier discreta, ma non sono ancora chiaro quale sia l'array risultante. Questo è ciò che la matrice sembra dopo aver preforme una FFT sul mio array usando NumPy:

[ -3.37260500e+05 +0.00000000e+00j 7.11787022e+05 +1.70667403e+04j 
    4.10040193e+05 +3.28653370e+05j 9.90933073e+04 +1.60555003e+05j 
    2.28787050e+05 +3.24141951e+05j 2.09781047e+04 +2.31063376e+05j 
    -2.15941453e+05 +1.63773851e+05j -7.07833051e+04 +1.52467334e+05j 
    -1.37440802e+05 +6.28107674e+04j -7.07536614e+03 +5.55634993e+03j 
    -4.31009964e+04 -1.74891657e+05j 1.39384348e+05 +1.95956947e+04j 
    1.73613033e+05 +1.16883207e+05j 1.15610357e+05 -2.62619884e+04j 
    -2.05469722e+05 +1.71343186e+05j -1.56779748e+04 +1.51258101e+05j 
    -2.08639913e+05 +6.07372799e+04j -2.90623668e+05 -2.79550838e+05j 
    -1.68112214e+05 +4.47877871e+04j -1.21289916e+03 +1.18397979e+05j 
    -1.55779104e+05 +5.06852464e+04j 1.95309737e+05 +1.93876325e+04j 
    -2.80400414e+05 +6.90079265e+04j 1.25892113e+04 -1.39293422e+05j 
    3.10709174e+04 -1.35248953e+05j 1.31003438e+05 +1.90799303e+05j... 

Mi chiedo che cosa esattamente questi numeri rappresentano e come vorrei convertire questi numeri in una percentuale di altezza per ciascuno dei 32 barre. Inoltre, dovrei mediare i 2 canali insieme?

risposta

187

La matrice che si sta visualizzando è i coefficienti di trasformata di Fourier del segnale audio. Questi coefficienti possono essere utilizzati per ottenere il contenuto di frequenza dell'audio. La FFT è definita per funzioni di input con valori complessi, quindi i coefficienti che si ottengono saranno numeri immaginari anche se l'input è tutti valori reali. Per ottenere la quantità di energia in ciascuna frequenza, è necessario calcolare l'entità del coefficiente FFT per ciascuna frequenza. Questo è non solo il componente reale del coefficiente, è necessario calcolare la radice quadrata della somma del quadrato dei suoi componenti reali e immaginari. Cioè, se il coefficiente è a + b * j, allora la sua grandezza è sqrt (a^2 + b^2).

Una volta calcolata l'entità di ciascun coefficiente FFT, è necessario determinare a quale frequenza audio appartiene ciascun coefficiente FFT. Un punto N FFT ti darà il contenuto in frequenza del tuo segnale a N frequenze equamente distanziate, a partire da 0. Perché la frequenza di campionamento è 44100 campioni/sec. e il numero di punti nella FFT è 256, la spaziatura della frequenza è 44100/256 = 172 Hz (circa)

Il primo coefficiente dell'array sarà il coefficiente di frequenza 0. Questo è fondamentalmente il livello di potenza medio per tutte le frequenze. Il resto dei coefficienti conterà da 0 in multipli di 172 Hz fino a raggiungere 128. In una FFT, puoi misurare solo le frequenze fino a metà dei tuoi punti campione. Leggi questi link su Nyquist Frequency e Nyquist-Shannon Sampling Theorem se sei un ghiottone per punizione e hai bisogno di sapere perché, ma il risultato di base è che le tue frequenze più basse saranno replicate o aliased nelle tazze di frequenza più alta.Quindi le frequenze inizieranno da 0, aumenteranno di 172 Hz per ciascun coefficiente fino al coefficiente N/2, quindi diminuiranno di 172 Hz fino al coefficiente N - 1.

Questo dovrebbe essere abbastanza informazioni per iniziare. Se desideri un'introduzione alle FFT molto più accessibile di quella fornita su Wikipedia, puoi provare con lo Understanding Digital Signal Processing: 2nd Ed.. È stato molto utile per me.

Quindi questo è ciò che rappresentano questi numeri. La conversione in una percentuale di altezza può essere eseguita ridimensionando ciascuna grandezza del componente di frequenza in base alla somma di tutte le grandezze dei componenti. Anche se questo ti darebbe solo una rappresentazione della distribuzione di frequenza relativa e non la potenza effettiva per ciascuna frequenza. Puoi provare a ridimensionare in base alla grandezza massima possibile per un componente di frequenza, ma non sono sicuro che ciò si visualizzerebbe molto bene. Il modo più rapido per trovare un fattore di ridimensionamento utilizzabile sarebbe quello di sperimentare segnali audio forti e deboli per trovare l'impostazione giusta.

Infine, si dovrebbe calcolare la media dei due canali insieme se si desidera mostrare il contenuto di frequenza dell'intero segnale audio nel suo complesso. Stai mixando l'audio stereo in audio mono e mostrando le frequenze combinate. Se si desiderano due display separati per le frequenze destra e sinistra, sarà necessario eseguire la Trasformata di Fourier su ciascun canale separatamente.

+3

+1 per la grande risposta e mi fa imparare un nuovo idioma, come Non sono un madrelingua inglese.;) – macbirdie

+1

+1 Impressionante, questo mi ha aiutato a capire cosa stavo facendo male. – Davido

+4

+1 - Anche se conosco già FFT - una delle migliori spiegazioni semplici in inglese sul web. – OldTinfoil

10

quello che hai è un campione la cui durata nel tempo è 256/44100 = 0,00580499 secondi. Ciò significa che la tua risoluzione di frequenza è 1/0,00580499 = 172 Hz. I 256 valori che escono da Python corrispondono alle frequenze, in pratica, da 86 Hz a 255 * 172 + 86 Hz = 43946 Hz. I numeri che ottieni sono numeri complessi (da cui la "j" alla fine di ogni secondo numero).

CURA: FISSO informazioni errate

è necessario convertire i numeri complessi in ampiezza calcolando la sqrt (i + j), dove i e j sono le parti reale e immaginaria, resp.

Se si desidera disporre di 32 barre, è necessario comprendere la media di quattro ampiezze successive, ottenendo 256/4 = 32 barre come si desidera.

+0

Ciao, scusa per la risposta iniziale (sbagliata) ... non ho capito bene la matematica. Questo dovrebbe essere corretto ora. –

+4

Si noti che, se c è un numero complesso, sqrt (c.real ** 2 + c.imag ** 2) == abs (c) – tzot

25

Sebbene questo thread abbia anni, l'ho trovato molto utile. Volevo solo dare il mio contributo a chiunque lo trovi e stia cercando di creare qualcosa di simile.

Per quanto riguarda la divisione in barre, questo non dovrebbe essere fatto come suggerito da antti, dividendo i dati equamente in base al numero di barre. Il più utile sarebbe dividere i dati in parti di ottava, ogni ottava raddoppia la frequenza del precedente. (ad esempio 100 hz è un'ottava sopra 50hz, che è un'ottava sopra 25hz).

A seconda del numero di barre che si desidera, si divide l'intero intervallo in intervalli di ottava 1/X. Sulla base di una data frequenza centrale di A sulla barra, si ottengono i limiti superiore e inferiore della barra da:

upper limit = A * 2^(1/2X) 
lower limit = A/2^(1/2X) 

Per calcolare la successiva frequenza centrale adiacente si utilizza un calcolo simile:

next lower = A/2^(1/X) 
next higher = A * 2^(1/X) 

Quindi media i dati che rientrano in questi intervalli per ottenere l'ampiezza per ciascuna barra.

Ad esempio: Vogliamo dividere in intervalli di 1/3 di ottave e iniziamo con una frequenza centrale di 1 kHz.

Upper limit = 1000 * 2^(1/(2 * 3)) = 1122.5 
Lower limit = 1000/2^(1/(2 * 3)) = 890.9 

44100Hz Given e 1024 campioni (43 Hz tra ciascun punto di dati) dovremmo mediare i valori da 21 a 26. (890,9/43 = 20,72 ~ 21 e 1122,5/43 = 26.10 ~ 26)

(Le barre di 1/3 di ottava ti portano circa 30 bar tra ~ 40hz e ~ 20khz). Come puoi capire ora, mentre andiamo più in alto faremo una media di una gamma più ampia di numeri. Le barre basse in genere includono solo 1 o un numero ridotto di punti dati. Mentre le barre più alte possono essere la media di centinaia di punti. Il motivo è che 86 Hz è un'ottava sopra i 43 Hz ... mentre 10086 Hz suona quasi la stessa di 10043 Hz.

Problemi correlati