Noise reduction (uso FFT?)

Facendo delle prove con CoolEdit sono rimanso piacevolmente colpito dalla possibilità di togliere il rumore. Ho cercato di sviluppare un programma per fare lo stesso mestiere, ma il risultato è disastroso. Quello che ho fatto è prendere 2 segnali in ingresso (canzone, e solo un pezzettino del rumore) fare la FFT, sottarre i due FFT tra di loro, e rigenerare il segnale PCM con la IFFT. Quello che ottengo e una cosa molto simile all'originale ma il rumore rimane (anzi sembra quasi peggio!). Immagino che l'algoritmo funzionante non sia quello che ho implementato io. Qualche suggerimento? Qualche sito dove spiegano come affrontare questa problematica? Grazie Luca Moreschi

Reply to
Luca Moreschi
Loading thread data ...

Ciao!

io farei così...

  1. faccio la FFT della canzone, ottengo i campioni delle varie frequenze
  2. faccio la FFT del rumore, ottengo i campioni (lo spettro) del rumore
  3. divido a pari frequenza i campioni della canzone con quelli del rumore (divido perché convolvere nel tempo significa moltiplicare nelle frequenze e considero il rumore come un "filtraggio" seppure non lineare)
  4. con la IFFT ottengo i campioni nel tempo originali

bye

Reply to
Luke

"Luke" ha scritto nel messaggio news: snipped-for-privacy@4ax.com...

[...]

ma una volta il rumore non si sommava? mah...che brutto non ricordarsi le cose.

Io vorrei sapere, a titolo di curiosità, come si può misurare il rumore che sta "sotto" al segnale...

Ciao Ste

Reply to
PeSte

Se non ricordo male, non devi sommarli, devi moltiplicare S(f) per l'inverso di N(f) (o il complesso coniugato, non ricordo, vedi l'altro thread in cui se ne parla).

--
- asd -
Reply to
dalai lamah

ciao!

misuri un attimo di silenzio... Come fa ad es. il GSM per testare lo stato del canale, invia pacchetti di IDLE di cui già conosce in ricezione la trasformata e confronta quella che riceve con quella attesa bye

Reply to
Luke

"Luke" ha scritto nel messaggio news: snipped-for-privacy@4ax.com...

e tu cosa assumi come spettro del rumore si fondo? un super fantastico e onnipresente gaussiano bianco?

Ciao Ste

Reply to
PeSte

"PeSte" ha scritto nel messaggio news:HtVqd.18920$ snipped-for-privacy@tornado.fastwebnet.it...

[...]

mi sono espresso mooolto male...volevo dire...ti basta una misura del rumore di fondo per ridurlo?

Grazie per le info, per me è un terreno inesplorato

Ciao Ste

Reply to
PeSte

ciao!

beh mettiamola così... Se supponi il segnale gaussiano bianco incorrelato questo ha uno spettro costante e quindi è molto facile da rimuovere... Dato che non è quasi mai così :-) se il canale ha una risposta all'impulso h(t), ovvero in frequenza una H(f), quello che tu ottieni da un segnale s(t) è

s(t)-convoluzione-h(t)

ovvero in frequenza

S(f)*H(f)

per tornare al segnale di partenza conoscendo H(f) devi moltiplicare per il filtro inverso

1/H(f)

ovvero alla fine dividere :-) Certo il filtro potrebbe essere complesso e non reale, allora in effetti devi usare il complesso coniugato. bye

Reply to
Luke

Mmmmm. ci ho provato, ma sparisce tutto il segnale! Ad essere sincero non sono molto sicuro dell'implementazione della divisione. Visto che non sono molte linee di codice le aggiungo in coda. Dove sbaglio?

// fft noise for(i = 0; i < FFT_LEN; i++) { m_dataIn[i] = (double)m_pPcmNoise[i]; } fft_double(FFT_LEN, FALSE, m_dataIn, NULL, m_fftNoiseR, m_fftNoiseI);

// process the whole data for(l = 0; l < m_pcmInLen; l += FFT_LEN ) { // ffi In for(i = 0; i < FFT_LEN; i++) { m_dataIn[i] = (double)m_pPcmIn[l+i]; } fft_double(FFT_LEN, FALSE, m_dataIn, NULL, m_fftInR, m_fftInI);

/* // sub noise for(i = 0; i < FFT_LEN; i++) { m_fftInR[i] -= m_fftNoiseR[i]; m_fftInI[i] -= m_fftNoiseI[i]; }

*/

// div noise for(i = 0; i < FFT_LEN; i++) { double a = m_fftInR[i]; double b = m_fftInI[i]; double c = m_fftNoiseR[i]; double d = m_fftNoiseI[i]; double x = c*c+d*d; m_fftInR[i] = ( a*c+b*d)/x; m_fftInI[i] = (-a*d+b*c)/x; }

// inverse fft fft_double(FFT_LEN, TRUE, m_fftInR, m_fftInI, m_fftOutR, m_fftOutI);

// save data for(i = 0; i < FFT_LEN; i++) { m_pPcmOut[l+i] = (short)(m_fftOutR[i]); } }

Reply to
Luca Moreschi

I calcoli mi sembrano giusti, ma tu sei sicuro che la tua funzione FFT ti restituisca parte reale e immaginaria? Di solito le FFT restituiscono modulo e fase. In questo caso devi dividere fra di loro i moduli e sottrarre le fasi (almeno credo :)).

--
- asd -
Reply to
dalai lamah

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.