Documente Academic
Documente Profesional
Documente Cultură
algoritmul permite detecia unui ton folosind doar un coeficient real. Un alt avantaj al algoritmului Goertzel, pe lng c se reduce astfel numrul coeficienilor folosii, este acela c algoritmul poate prelucra fiecare eantion pe msur ce acesta sosete, eliminnd asfel nevoia utilizrii unui buffer de memorie n care s se stocheze N eantioane, ca n cazul TFD. n plus, nu este necesar nici un mecanism bit reversed de adresare a memoriei, ca n cazul FFT.
Deoarece
w NkN = e j 2 ( kN ) N
= e j 2k = 1
2 N
X N (k ) =
cu acest factor i obinem:
N 1 n =0
nk x(n) wN , k = 0...N 1, wN = e
X N (k ) = w kN X N (k ) = w kN
Fie
N 1 n =0
nk x ( n) w N
N 1 n =0
x(n) wNk ( N n)
y k ( m) =
N 1 n =0
( x1 * x 2 )(n) =
Pentru m = N obinem:
k =
x1 (k ) x2 (n k )
yk ( N ) =
N 1 n=0
x(n) wNk ( N n) = X (k )
deci este evident c yk (N ) este convoluia ntre o secven de intrare x(n) de lungime N cu un filtru cu funcia pondere
wNkm u (m)
x(n)
y(n)
hk (n) =
y(N)=X(k) -e-j2k/N
X (k ) = y k ( N ) m= N
Pentru orice alt moment m N , ieirea filtrului, y (m) , nu este egal cu X (k ) . Filtrul cu funcia rspuns la impuls
hk (n) = wNkm u (m)
2cos(2k/N)
-1
H k ( z) = H k ( z) =
1 ( w Nk z 1 ) N 1 w Nk z 1
N 1 m =0
w Nk z 1 j
2 k N
1 e j 2 k z N 1 e
2 k j N
Figura 3. Implementarea algoritmului Goertzel ca filtru IIR Rezultatul TFD i TFR este un vector de dimensiune N ce conine valorile complexe (amplitudine i faz) ale componentelor spectrale ale unui vector de intrare tot de dimensiune N. Transformarea este ndeplinit prin procesarea mai nti a unui
z 1
1 1 e
2 k j N
1 e (1 e
2 k j N
z 1 z 1 )
z 1
2 k j z 1 )(1 e N
numr de N eantioane de intrare, apoi calculnd rezultatele de ieire, adic cele N componente spectrale. Spre deosebire, un filtru FIR sau IIR calculeaz o nou ieire pentru fiecare eantion de intrare. Calculul recursiv de ordinul 2 al TFD prin algoritmul Goertzel d o nou ieire y(n) pentru fiecare eantion de intrare x(n). Rezultatul TFD, X(k), este echivalent cu y(n) cnd n = N . Cum celelalte valori ale y(n), pentru n N , nu contribuie n nici un fel la rezultatul final X(k), nu este nevoie s calculm y(n) pn cnd n nu devine egal cu N. Aceasta nseamn c algoritmul Goertzel este echivalent funcional cu un filtru IIR de ordin doi, cu excepia faptului c o nou ieire a filtrului este generat doar dup ce au ajuns, au fost prelucrate n eantioane ale semnalului analizat. Calculele privind realizarea algoritmului Goertzel pot fi mprite n dou etape: prima implic calculele legate de calea de reacie iar cea de a doua calculele privind calea direct i obinerea X(k), aa cum este artat n figura 3.
Deci
1 e N z 1 H ( z) = 2k 1 1 2 cos( ) z + z 2 N
2 k
Calea de reacie
Calea de reacie este urmat de toate eantioanele semnalului de intrare. De-a lungul acestei ci, reprezentat separat n figura 4 sunt stocate n memorie sau n registre dou valori intermediare: v(n-1) i v(n-2). Acestea sunt calculate dup cum urmeaz:
x(n)
2cos(2k/N)
v(1) = v(2) = 0
v(n)
y(n)
Calea direct
Pe calea direct se fac calcule o singur dat, la momentul N, dup ce s-au realizat calculele pe calea de reacie pentru toate cele N eantioane. X(k) este calculat folosind dou valori intermediare, v(n) i v(n-1) obinute n urma calculelor efectuate pe calea de reacie. Aa cum arat figura 5, unde este reprezentat doar calea direct,
z-1 v(n-1)
y ( N ) = v(n) e j 2k / N v(n 1) = X (k )
n acest moment, cele dou valori intermediare sunt v(N-1) i v(N-2) deoarece n = N-1.
v(1) = v(2) = 0
for(k=0;k<N;k++) { for(n=0;n<N;n++) { v2[k]=v1[k]; v1[k]=v[k]; v[k]=sign[n]+2*c[k]*v1[k]-v2[k]; } v2[k]=v1[k]; v1[k]=v[k]; v[k]=2*c[k]*v1[k]-v2[k]; SGN_real[k]=v[k]-v1[k]*c[k]; SGN_imag[k]=v1[k]*s[k]; } } void sin_cos(int L_DFT) { int k; for(k=0;k<L_DFT;k++) { c[k]=cos(2*pi*k/L_DFT); s[k]=sin(2*pi*k/L_DFT); } }
#define pi 3.141592 float c[N],s[N]; // n vectorii c[ ] i s[ ] se pstreaz valorile coeficienilor // cos(2k/N) i sin(2k/N) void sin_cos(int L_DFT); void goertzel( float sign[],float SGN_real[],float SGN_imag[]); main() { int n; float Xreal[N],Ximag[N]; float x[]={0.9003,-0.5377,0.2137, -0.0280,0.7826,0.5242,-0.0871,-0.9630}; 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;