DFT e FFT

« Older   Newer »
  Share  
view post Posted on 20/12/2014, 16:23
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Grazie Thermidor.
Il discorso dell'ipotenusa, parte reale, immaginaria ecc...devo ancora digerirlo bene, ho capito più o meno, ma non lo "vedo" al 100%.
Per la trasformata inversa invece, appena ho un po' di tempo ci provo.

Adesso sono alle prese con un riconoscitore di numero telefonico in base al suono di ogni tasto (frequenze DTMF), sarebbe un progetto interessante.
Ancor di più sarebbe riuscirlo a fare con un microcontrollore tipo pic....ma sono secoli che non maneggio un uc :(

Grazie ancora...e vi terrò informati sugli sviluppi.
 
Top
view post Posted on 28/12/2014, 08:46
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Purtroppo non ho ancora avuto modo di provare
ma:

CITAZIONE
Peso * sen(num_armonica * omega * T)
poi quella del coseno, la sommatoria estesa a tutte le armoniche ti restituisce la forma d'onda.

per numero armonica intendi le varie frequenze vero? Quelle che vanno da 0 a Max (cioè il mio range massimo analizzbile no?)
Omega non ho capito bene cosa intendi.
T invece dovrebbe essere la il periodo del campionamento giusto? nel mio caso 1/8000=0.000125.
a conti fatti, il cuore di tutto è scritto in questa porzione di codice, lo so che non è facile capire cose scritte da altri, ma così
possiamo riferirci a qualcosa di concreto.
Mi sto un po' incasinando con la trasformata inversa:

float dft(float *campioni,float *ris_3)
{
float w,r,res=0;
int k=0;
int j;
float real [30000]={0};
float unreal [30000]={0};
float somma=0;
float somma_2=0;

for (r=0; r<2000; r++)
{
w=0;
somma=0;
somma_2=0;
for (j=0; j<2000; j++ )
{
res=(campioni[j]*cos(w*r*2*M_PI));
somma=somma+res;
real[k]=real[k]+somma;
//_______________________________________________
res=(campioni[j]*sin(w*r*2*M_PI));
somma_2=somma_2+res;
unreal[k]=unreal[k]+somma_2;
ris_3[k]=sqrt( (real[k]*real[k])+ (unreal[k]*unreal[k]));

w=w+0.000125;

}

k++;

}
return ris_3[0];}




 
Top
thermidor
view post Posted on 30/12/2014, 23:08




Ciao Gila e scusa se rispondo quando posso.
La validità di una DFT è certa per segnali periodici ripetitivi, per farla in breve segnali dove conosci l'inizio e la fine della forma d'onda che rappresenta in pratica la tua fondamentale.
Tutti i valori che trovi sono relativi a quella.
Num_armonica rappresenta effettivamente il numero dell'armonica (1=fondamentale, 2=seconda armonica), volendo puoi anche valutare frequeze diverse esempio 2,35 ma non so quanto siano validi i risultati appunto perchè si presume che stai analizzando una forma d'onda ben definita.
Omega è semplicemente 2*pigreco*f dove f è in pratica la frequenza della fondamentale.
T giustamente è il tempo di campionamento, nel tuo caso all'istante 0 = 0, all'istante 1 = 0.000125, all'istante 2 = 0.00025 e così via.
Una ultima cosa, quando hai estratto un periodo che vuoi analizzare la frequenza la puoi anche mettere a 1, a te interessa trovare l'incidenza delle armoniche che non cambia che la frequenza sia 100Hz o 10kHz, quindi puoi considerare omega = 2*pigreco.
 
Top
view post Posted on 31/12/2014, 19:05
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


CITAZIONE (thermidor @ 30/12/2014, 23:08) 
Ciao Gila e scusa se rispondo quando posso.
La validità di una DFT è certa per segnali periodici ripetitivi, per farla in breve segnali dove conosci l'inizio e la fine della forma d'onda che rappresenta in pratica la tua fondamentale.
Tutti i valori che trovi sono relativi a quella.
Num_armonica rappresenta effettivamente il numero dell'armonica (1=fondamentale, 2=seconda armonica), volendo puoi anche valutare frequeze diverse esempio 2,35 ma non so quanto siano validi i risultati appunto perchè si presume che stai analizzando una forma d'onda ben definita.
Omega è semplicemente 2*pigreco*f dove f è in pratica la frequenza della fondamentale.
T giustamente è il tempo di campionamento, nel tuo caso all'istante 0 = 0, all'istante 1 = 0.000125, all'istante 2 = 0.00025 e così via.
Una ultima cosa, quando hai estratto un periodo che vuoi analizzare la frequenza la puoi anche mettere a 1, a te interessa trovare l'incidenza delle armoniche che non cambia che la frequenza sia 100Hz o 10kHz, quindi puoi considerare omega = 2*pigreco.

Figurati, lo so che gli impegni sono tanti. E poi è grazie a te che sono riuscito a scrivere e capire la dft. Ok, un po' ci ero arrivato,
ma sul discorso di parte reale e immaginaria, non so se da me avrei capito...quindi :)

Appena posso provo a fare la idft, sarebbe bello fare esperimenti, tipo togliere il rumore di fondo e lasciare solo il parlato, come fanno certi telefoni se non erro.
Da altre parti sono stato un po' criticato sul fatto di "riscrivere" la dft, quando c'è in gcc (linux) la libreria C fftw3.
A mio modo di vedere, e mi piaceva sapere il tuo parere, le cose non stanno così.

Che senso ha usare librerie se non conosci il concetto, la teoria?
A me piace capire, poi affidarmi a "cose" sviluppate in decenni dai cervelli migliori al mondo, no?
Comunque, il progetto del riconoscimento dei tasti dft va a avanti, per ora riconosce bene un tasto singolo registrato a microfono.
Poi più avanti lo ampierò....vi farò vedere se tutto va bene.
Intanto buon anno e grazie Thermidor :)
 
Top
thermidor
view post Posted on 1/1/2015, 18:52




Buon anno a te e tutti i presenti sul forum.
Personalmente la vedo come te, usiamo già tante cose a scatola chiusa, almeno quelle per il quale mostriamo interesse sarebbe bene cercare di capire come funzionano.
 
Top
view post Posted on 7/1/2015, 10:01
Avatar

Immane Rompiball

Group:
Administrator
Posts:
18,287
Location:
Orlo esterno della cintura di Orione stella 1957

Status:


CITAZIONE (thermidor @ 1/1/2015, 18:52) 
Buon anno a te e tutti i presenti sul forum.
Personalmente la vedo come te, usiamo già tante cose a scatola chiusa, almeno quelle per il quale mostriamo interesse sarebbe bene cercare di capire come funzionano.

Si si, io non i intendevo affatto dire che è dovere usare qualcosa senza capire cos'è o cosa fa. Tutto il contrario. Occorre sempre capire il più possibilile di ciò con cui si viene a contatto. Volevo solo dire che io uso l'analizzatore e non mi metto a farne uno, e anche se so cosa sia FFT trasformate, annessi e connessi, un conto è sapere l'altro è fare e per fare spesso non si ha tempo. Però, ritengo che sia un'esperienza valida quella che sta affrontando il Gila e spero che riesca ad arrivare abbastanza avanti anche con l'aiuto di Thermidor.
 
Web  Top
thermidor
view post Posted on 7/1/2015, 23:05




Beh lo so Lawrence non era certo diretta a te, ci mancherebbe. Ma sai viviamo in un era di pressapochismo diffuso, quindi quando uno come Gila vuole fare qualcosa e cerca di capire cosa, lo trovo positivo. Poi magari userà un tool pronto, ma almeno avrà capito su quale base si sta muovendo.
 
Top
view post Posted on 8/1/2015, 08:54
Avatar

Immane Rompiball

Group:
Administrator
Posts:
18,287
Location:
Orlo esterno della cintura di Orione stella 1957

Status:


Il Gila è un pò testardo, ma quando parte non lo ferma nessuno. :)
 
Web  Top
view post Posted on 12/1/2015, 18:09
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Ciao ragazzi è da un po' che manco...causa...1000 cause :)

CITAZIONE
Il Gila è un pò testardo, ma quando parte non lo ferma nessuno. :)

Vedo che mi conosci bene Law!!!
Quando una cosa m'interessa, cerco d'impegnarmi. Poi la dft,fft (insomma la trasformata di Fourie), è uno strumento matematico
talmente potente, che vale la pena di studiare un po'.
Purtroppo nella trasformata inversa ho qualche problema...non mi riesce.
Comunque nel frattempo, mi sono messo anche a studiare la libreria FFTW3 presente in gcc (Linux).
A differenza della dft che ho scritto io, è un fulmine, anche se non sono entrato nei dettagli tecnici/matematici.
Però ci sono cose un po' oscure che vorrei chiarire:
Nella "mia" dft, con due cicli for andavo a scansionare un insieme di dati, diciamo da 0 a x per un range di frequenza da 0 a y es:

for (r=0; r<1000; r++)
{
w=0;
somma=0;
somma_2=0;
for (j=0; j<2000; j++ )
{
res=(campioni[j]*cos(w*r*2*M_PI)); //calcolo parte real
somma=somma+res;
real[k]=real[k]+somma;
//_______________________________________________
res=(campioni[j]*sin(w*r*2*M_PI)); //calcolo parte immaginaria
somma_2=somma_2+res;
unreal[k]=unreal[k]+somma_2;
risultato_dft[k]=sqrt( (real[k]*real[k])+ (unreal[k]*unreal[k]));

w=w+0.000125; //(inverso frequenza campionamento 1/8000)

}

k++;

}

Come potete notare, ho due cicli for:con il ciclo r vado ad analizzare frequenze da 0-1000 e con il cilclo j, vado a scansionare
l'array dal dato 0 a 2000.
quindi analizzo i dati a 8,16,32 bits che vanno da 0 a 2000 e posso analizzare solo frequenze minori di 1000.
Così facendo ho una risoluzione di 1hz, bella precisa.
In effetti registrando da microfono i toni dtmf, salvandoli in wave e sottoponendoli a dft, la singola frequenza viene rilevata ottimamente.

Con la fft invece ho una situazione diversa, e vorrei capire se ragiono nel verso giusto.
Abbiamo una traccia audio supponiamo.
Scegliamo una finestra di osservazione a 128,256,512 punti.
Per natura della FFT la finestra per una massima prestazione deve essere una potenza del 2, non so bene il perchè, dettagli puramente tecnici, che per ora
non mi interessano.
La cosa "scocciante", è che non è detto che con la fft si abbia una risoluzione di 1 hz preciso.
Mi spiego:
Traccia a sample rate 44100 Hz (formato cd).
La massima frequenza riproducibile senza incorrere in alias (non so se si dice così), è 44100/2=22050 (teorema di Nyquist).
Supponiamo che la nostra finestra (e ne esistono di vari tipi, ma per ora tralasciamo) sia di 4096.
Il minimo step in Hz che posso leggere, se non ho preso granchi è:
(44100/2)/(4096/2)=22050/2048=10.76 Hz

Giusto?
Logicamente se aumento i punti della finestra a parità di sample_rate la risoluzione aumenta.
Un'altra particolarità che ho notato usando la fftw3, che contiene un sacco di routine diverse, è che su una finestra esempio di 1024
i pesi delle frequenze dati da sqr (parte_reale)*(parte_reale)+(parte_immag.)*(parte_immag.)
Sono nella prima metà e nella seconda metà della finestra
0------>512 pesi frequenza fondamentale
512---->1024 pesi frequenza fondamentale ridondanti.
esempio : a 1024 punti la frequenza fondamentale è in posizione 10, quella ridondante è a 512-10=502
Credo che la parte ridondante sia la parte negativa.
Ad ogni modo non si visualizza e non si tiene in considerazione a meno che si debba operare un filtraggio.
Allora in quel caso va modificata anche la parte ridondande, per poi darla in pasto alla FFT inversa.

Un'altra cosa che ho notato: nella mia dft le linee spettrali erano in perfetto accordo con la potenza associata a quella frequenza:
100 hz "forza" 5
50 hz "forza" 10
la linea spettrale dei 50 hz, è perfettamente il doppio rispetto a quella dei 100 hz.
Con la fft da libreria, non è così.
Forse la routine di default non usa una finestra rettangolare, o forse il tutto è logaritmico, non so.
Comunque al di la di tutto, mi piacerebbe capire se i miei ragionamenti sono esatti.
Analizzando per esempio un wave di 200000 campioni con una finestra da 1024, per avere lo spettro totale dovrei fare 200000/1024=195.3 fft giusto?
la prima finestra da 1024 punti, mi fa la fft SOLO di quel punto no?
a 44100 hz sample_rate con 1024 punti andrei ad analizzare la traccia da 0 secondi a:
1/44100*1024=0.0232*1000=23.219 millisecondi
Grazie a tutti...e scusate per la lunghezza :)

Edited by GILA75 - 12/1/2015, 20:02
 
Top
view post Posted on 14/1/2015, 21:26
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Sto smacchinando di brutto col codice C, appena (e se riesco), vorrei proporre un filtro digitale.
Adesso come adesso più che altro sono i problemi legati alla programmazione in C, non sono ancora a certi livelli :)

Vediamo cosa salta fuori.
certo che con fft e ifft se ne possono fare di cose interessanti.
Appena riesco posto.
Intanto aspetto di capire se quello che ho scritto nel post precedente è esatto.
 
Top
99 replies since 28/12/2010, 17:38   1846 views
  Share