Sunteți pe pagina 1din 4

irelevantă în aplicaţiile de detecţie a DTMF.

Avantajul acestei modificări este acela că


7.10 Algoritmul Goertzel algoritmul permite detecţia unui ton folosind doar un coeficient real.
Un alt avantaj al algoritmului Goertzel, pe lângă că se reduce astfel numărul
7.10.1 Utilizare şi avantaje coeficienţilor folosiţi, este acela că algoritmul poate prelucra fiecare eşantion pe măsură ce
acesta soseşte, eliminând asfel nevoia utilizării unui buffer de memorie în care să se
O tehnică eficientă de a calcula rezultatele doar pentru unele din cele N frecvenţe
stocheze N eşantioane, ca în cazul TFD.
este algoritmul Goertzel, care calculează rezultatul pentru o singură componentă spectrală,
În plus, nu este necesar nici un mecanism “bit reversed” de adresare a memoriei, ca
la fiecare N eşantioane ale semnalului analizat.
în cazul FFT.
Algoritmul Goertzel este utilizat în decodarea şi detecţia DTMF (dual-tone
multifrequency) precum şi la realizarea modemurilor ce utilizează PSK (phase-shift 7.10.2 Deducerea algoritmului
keying) sau FSK (frequency shift keying). Algoritmul Goertzel poate fi folosit şi la calculul
TFD. Algoritmul Goertzel exploatează proprietatea de periodicitate a coeficienţilor de

rotaţie {w N } şi permite exprimarea formulei de definiţie a TFD ca pe o filtrare liniară.


k
A decoda un semnal DTMF înseamnă a extrage cele două tonuri (frecvenţe)
prezente în semnal şi a determina, ştiind valorile lor, numărul sau caracterul codat de Deoarece
acestea. Detecţia tonurilor DTMF se face foarte uşor transpunând semnalul ce le conţine 2π
−j ( − kN )
din domeniul timp în domeniul frecvenţă prin transformare Fourier. Transformata Fourier w N−kN = e N = e j 2πk = 1
Rapidă calculează eficient rezultatele pentru toate cele N puncte ale Transformatei Fourier putem multiplica relaţia de definiţie a TFD:
Discrete. Pe de altă parte, TFD poate fi calculată direct pentru a obţine rezultatele în doar N −1 2π
−j
câteva puncte. X N (k ) = ∑ x(n) wNnk , k = 0...N − 1, wN = e N
n =0
În mod tipic, dacă se cer a fi calculate mai mult de log2N din cele N puncte, este
cu acest factor şi obţinem:
mai rapid să se calculeze rezultatele pentru toate cele N puncte, aplicând TFR şi neluând în
N −1 N −1
seamă punctele nedorite. Dacă este nevoie doar de câteva puncte, TFD este mai rapid de X N (k ) = w − kN X N (k ) = w − kN ∑ x(n) wNnk = ∑ x(n) wN−k ( N −n)
n =0 n =0
aplicat decât TFR. TFD este mai rapidă în a găsi doar 8 frecvenţe (tonurile DTMF sunt
compuse din 2 frecvenţe alese dintr-un set standard de 8) în banda întregului canal Fie
N −1
telefonic.
y k ( m) = ∑ x(n) wN−k ( m−n) = x(m) * w N− km u (m)
Algoritmul Goertzel evaluează TFD cu o economie de calcule şi timp. Pentru a n =0

calcula TFD direct, este nevoie de mulţi coeficienţi complecşi. Pentru a calcula TFD în N În general, convoluţia a două semnale este dată de
2
puncte, sunt necesari N coeficienţi complecşi. Pentru calculul într-un singur punct din cele ∞

N trebuie calculaţi N coeficienţi complecşi.


( x1 * x 2 )(n) = ∑ x1 (k ) x2 (n − k )
k = −∞
Spre deosebire de TFD, algoritmul Goertzel utilizează doar doi coeficienţi (unul Pentru m = N obţinem:
complex şi unul real), pentru calculul într-un singur punct. Algoritmul Goertzel calculează N −1
rezultate complexe, aşa cum face şi TFD dar algoritmul Goertzel poate fi modificat yk ( N ) = ∑ x(n) wN−k ( N −n) = X (k )
n=0
algebric astfel încât rezultatul său să fie pătratul amplitudinii componentei spectrale
respective (o valoare reală). Această modificare şterge informaţia de fază care este
deci este evident că yk (N ) este convoluţia între o secvenţă de intrare x(n) de lungime N x(n) y(n)
+ +
cu un filtru cu funcţia pondere v(n)

hk (n) = wN− km u (m) z-1


Ieşirea acestui filtru la m = N dă valoarea calculată de TFD pe frecvenţa k. v(n-1) y(N)=X(k)
X (k ) = y k ( N ) m= N
z-1
Pentru orice alt moment m ≠ N , ieşirea filtrului, y (m) , nu este egală cu X (k ) . 2cos(2πk/N) -e-j2πk/N
Filtrul cu funcţia răspuns la impuls v(n-2)

hk (n) = wN− km u (m)


are funcţia de transfer -1
N −1 calea de reacţie calea directă
H k ( z) = ∑ wN−km u (m) z −m (feedback) (feedforward)
m =0

1 − ( w N− k z −1 ) N 1 − w N− kN z − N 1 − e j 2 kπ z − N Figura 3. Implementarea algoritmului Goertzel ca filtru IIR


H k ( z) = = = 2 kπ
=
1 − w N− k z −1 1− w N−k z −1 j
1− e N z −1 Rezultatul TFD şi TFR este un vector de dimensiune N ce conţine valorile
2 kπ
−j complexe (amplitudine şi fază) ale componentelor spectrale ale unui vector de intrare tot de
1 1− e N z −1
= 2 kπ
= 2 kπ 2 kπ dimensiune N. Transformarea este îndeplinită prin procesarea mai întâi a unui
j j −j
1− e N z −1 (1 − e N z −1 )(1 − e N z −1 ) număr de N eşantioane de intrare, apoi calculând rezultatele de ieşire, adică cele N
Deci componente spectrale.

−j
2 kπ Spre deosebire, un filtru FIR sau IIR calculează o nouă ieşire pentru fiecare
1 − e N z −1 eşantion de intrare. Calculul recursiv de ordinul 2 al TFD prin algoritmul Goertzel dă o
H ( z) =
2kπ −1
1 − 2 cos( ) z + z −2 nouă ieşire y(n) pentru fiecare eşantion de intrare x(n). Rezultatul TFD, X(k), este
N
echivalent cu y(n) când n = N .
Cum celelalte valori ale y(n), pentru n ≠ N , nu contribuie în nici un fel la

7.10.3 Implementarea algoritmului Goertzel rezultatul final X(k), nu este nevoie să calculăm y(n) până când n nu devine egal cu N.
Aceasta înseamnă că algoritmul Goertzel este echivalent funcţional cu un filtru IIR de ordin
Algoritmul va fi deci implementat sub forma unui filtru cu răspuns infinit la impuls doi, cu excepţia faptului că o nouă ieşire a filtrului este generată doar după ce au ajuns, au
(IIR) care arată ca în figură: fost prelucrate n eşantioane ale semnalului analizat.
Calculele privind realizarea algoritmului Goertzel pot fi împărţite în două etape:
prima implică calculele legate de calea de reacţie iar cea de a doua calculele privind calea
directă şi obţinerea X(k), aşa cum este arătat în figura 3.
Calea de reacţie x(n)
+
v(n)
Calea de reacţie este urmată de toate eşantioanele semnalului de intrare. De-a lungul
acestei căi, reprezentată separat în figura 4 sunt stocate în memorie sau în registre două z-1
valori intermediare: v(n-1) şi v(n-2). Acestea sunt calculate după cum urmează: v(n-1)
v(n) = x(n) + 2 cos(2πk / N )v(n − 1) − v(n − 1)
z-1
v(n-1) şi v(n-2) sunt două elemente de memorie pentru stocarea v(n) iar x(n) este 2cos(2πk/N)
eşantionul curent de intrare. x(n), v(n-1) şi v(n-2) sunt citite din memorie şi folosite la v(n-2)
calculul unui nou v(n). Acest nou v(n) este stocat în locul vechiului v(n) iar acel vechi v(n)
este stocat în locul lui v(n-1).
-1
Prin deplasări succesive se actualizează v(n-1) şi v(n-2) pentru fiecare nou eşantion
de intrare. Figura 4. Calea de reacţie

La început, cele două valori sunt iniţializate cu 0:


v(−1) = v(−2) = 0 y(n)
+
v(n)

Calea directă z-1


v(n-1)
Pe calea directă se fac calcule o singură dată, la momentul N, după ce s-au realizat
calculele pe calea de reacţie pentru toate cele N eşantioane.
X(k) este calculat folosind două valori intermediare, v(n) şi v(n-1) obţinute în urma -e-j2πk/N
calculelor efectuate pe calea de reacţie. Figura 5. Calea directă
Aşa cum arată figura 5, unde este reprezentată doar calea directă,

y ( N ) = v(n) − e − j 2πk / N v(n − 1) = X (k ) Ecuaţiile cu diferenţe finite pentru filtrul Geortzel


În acest moment, cele două valori intermediare sunt v(N-1) şi v(N-2) deoarece n =
Ecuaţiile cu diferenţe finite, în domeniul timp ce implementează filtrul Goertzel
N-1.
sunt cele ce realizează cele două căi, de reacţie şi directă date mai sus:
v(n) = x(n) + 2 cos(2πk / N )v(n − 1) − v(n − 1)
şi

y (n) = v(n) − e − j 2πk / N v(n − 1)


cu condiţiile iniţiale
v(−1) = v(−2) = 0
7.10.4 Programul pentru implementarea algoritmului Goertzel for(k=0;k<N;k++)
{
#include <stdio.h> for(n=0;n<N;n++)
#include <math.h> {
v2[k]=v1[k];
#define M 8 // M - lungimea semnalului v1[k]=v[k];
v[k]=sign[n]+2*c[k]*v1[k]-v2[k];
#define N 8 // N - lungimea transformatei
}
v2[k]=v1[k];
#define pi 3.141592
v1[k]=v[k];
v[k]=2*c[k]*v1[k]-v2[k];
float c[N],s[N]; // în vectorii c[ ] şi s[ ] se păstrează valorile coeficienţilor
SGN_real[k]=v[k]-v1[k]*c[k];
// cos(2πk/N) şi sin(2πk/N) SGN_imag[k]=v1[k]*s[k];
void sin_cos(int L_DFT); }
void goertzel( }
float sign[],float SGN_real[],float SGN_imag[]);
void sin_cos(int L_DFT)
main() {
{ int k;
int n; for(k=0;k<L_DFT;k++)
float Xreal[N],Ximag[N]; {
float x[]={0.9003,-0.5377,0.2137, c[k]=cos(2*pi*k/L_DFT);
-0.0280,0.7826,0.5242,-0.0871,-0.9630}; s[k]=sin(2*pi*k/L_DFT);
}
sin_cos(N); }
goertzel(x,Xreal,Ximag);

for(n=0;n<N;n++)
printf("%f\t%f\t\n",Xreal[n],Ximag[n]);
}

void goertzel(float sign[],float SGN_real[],float SGN_imag[])


{
int n,k;
float v[N],v1[N],v2[N];

for(n=0;n<N;n++)
v[n]=v1[n]=v2[n]=0;

S-ar putea să vă placă și