Algoritmo di Goertzel
Da Wikipedia, l'enciclopedia libera.
L'algoritmo di Goertzel è una tecnica di digital signal processing (DSP) utilizzata per identificare le diverse componenti in frequenza di un segnale. La più generale Fast Fourier transform (FFT) considera la completa banda passante del segnale; l'algoritmo di Goertzel si riferisce invece ad alcuni punti specifici predeterminati.
[modifica] Codice d'esempio per un decodificatore Goertzel
#define MAX_BINS 12 #define GOERTZEL_N 92 int sample_count; double q1[ MAX_BINS ]; double q2[ MAX_BINS ]; double r[ MAX_BINS ]; double coefs[ MAX_BINS*2 ] = { 1.7088388, 1.6339398, 1.5514226, 1.4616719, 1.1533606, 1.0391679, 0.7968022, 0.5395935, -0.6697592, -1.0391679, -1.3651063, -1.7088388}; /*---------------------------------------------------------------------------- * post_testing *---------------------------------------------------------------------------- * Qui è dove guardiamo nei bin e decidiamo se abbiamo un segnale valido. */ void post_testing() { int row, col, see_digit; int peak_count, max_index; double maxval, t; int i; char * row_col_ascii_codes[4][4] = { {"1", "2", "3", "A"}, {"4", "5", "6", "B"}, {"7", "8", "9", "C"}, {"*", "0", "#", "D"}}; /* Trova il maggiore nel gruppo delle righe. */ row = 0; maxval = 0.0; for ( i=0; i<4; i++ ) { if ( r[i] > maxval ) { maxval = r[i]; row = i; } } /* Trova il maggiore nel gruppo delle colonne. */ col = 4; maxval = 0.0; for ( i=4; i<8; i++ ) { if ( r[i] > maxval ) { maxval = r[i]; col = i; } } /* Controlla per energia minima */ if ( r[row] < 4.0e5 ) /* 2.0e5 ... 1.0e8 non e' significativo */ { /* energia non abbastanza elevata */ } else if ( r[col] < 4.0e5 ) { /* energia non abbastanza elevata */ } else { see_digit = TRUE; /* Controllo di inversione * CEPT => inversione < 6dB * AT&T => inversione diretta < 4dB e inversione inversa < 8dB * -ndB < 10 log10( v1 / v2 ), where v1 < v2 * -4dB < 10 log10( v1 / v2 ) * -0.4 < log10( v1 / v2 ) * 0.398 < v1 / v2 * 0.398 * v2 < v1 */ if ( r[col] > r[row] ) { /* Inversione diretta */ max_index = col; if ( r[row] < (r[col] * 0.398) ) /* inversione > 4dB, errore */ see_digit = FALSE; } else /* if ( r[row] > r[col] ) */ { /* Inversione inversa */ max_index = row; if ( r[col] < (r[row] * 0.158) ) /* inversione > 8db, errore */ see_digit = FALSE; } /* Controllo del rapporto segnale/rumore * AT&T afferma che il rumore deve essere inferiore di 16dB rispetto al segnale. * Qui contiamo il numero di segnali sopra la soglia e * dovrebbero essercene solo due. */ if ( r[max_index] > 1.0e9 ) t = r[max_index] * 0.158; else t = r[max_index] * 0.010; peak_count = 0; for ( i=0; i<8; i++ ) { if ( r[i] > t ) peak_count++; } if ( peak_count > 2 ) see_digit = FALSE; if ( see_digit ) { printf( "%s", row_col_ascii_codes[row][col-4] ); fflush(stdout); } } } /*---------------------------------------------------------------------------- * goertzel *---------------------------------------------------------------------------- */ void goertzel( int sample ) { double q0; ui32 i; if ( sample_count < GOERTZEL_N ) { sample_count++; for ( i=0; i<MAX_BINS; i++ ) { q0 = coefs[i] * q1[i] - q2[i] + sample; q2[i] = q1[i]; q1[i] = q0; } } else { for ( i=0; i<MAX_BINS; i++ ) { r[i] = (q1[i] * q1[i]) + (q2[i] * q2[i]) - (coefs[i] * q1[i] * q2[i]); q1[i] = 0.0; q2[i] = 0.0; } post_testing(); sample_count = 0; } }
[modifica] Collegamenti esterni
- (EN) http://www.ece.utexas.edu/~mason/codesign/pass/embedded.html
- (EN) http://ptolemy.eecs.berkeley.edu/papers/96/dtmf_ict/www/node3.html
- (EN) http://www.embedded.com/story/OEG20020819S0057
- (EN) http://www.embedded.com/showArticle.jhtml?articleID=17301593
- (EN) http://www.numerix-dsp.com/goertzel.html
- (EN) http://www.mathworks.com/access/helpdesk/help/toolbox/signal/goertzel.html