int reverse(int n, int v) /* Odwrenie kolejnoカci v najmウodszych bit liczby n - funkcja pomocnicza */ { int bit, r = 0; for (bit=0; bit<v; bit++) { r = (r << 1) | (n & 1); n >>= 1; } return r; } /******************************************************************************/ float fft(float *x, float *y, int v, float *SinTab, int M) /* Parametry wejカciowe: x - N prek rzeczywistego sygnaウu znormalizowanego i oknowanego v - log2(N) SinTab - tablica wartoカci funkcji sin(゚) dla ゚ z przedziaウu [0,2pi) M - liczba prek funkcji sinus w okresie (rozmiar tablicy SinTab) Parametry wyjsciowe: y - N prek logarytmicznego widma FFT sygnaウu wyraソonego w [daB], dla cz黌totliwoカci znormalizowanych fT z przedziaウu [0,1) Zwracana wartoカ・ moc sygnaウu x wyraソona w [daB] (liczona z twierdzenia Parsevala) */ { int p, q, r, grp, bfy; register int lc1, lc2, lc3; float Sin, Cos, xp, yp, xq, yq, sum; /* Wyznaczenie liczby punkt FFT */ #define N (1 << v) /* Wyzerowanie cz・ci urojonej (y) */ for (lc1=0; lc1<N; lc1++) y[lc1] = 0.0; /* Szybkie przeksztaウcenie Fouriera wg Cooley'a i Tukey'a (obliczenia z podstawieniem, prki widma w odwronym porzアdku bit), por. [Oppenheim, Schafer], wz (6.16) i rys.6-12 */ grp = 1; bfy = N/2; for (lc1=0; lc1<v; lc1++) { /* kolejne przebiegi oblicze・z podstawianiem */ p = 0; q = bfy; r = 0; for (lc2=0; lc2<grp; lc2++) { /* grupy motylk w ramach danego przebiegu */ Sin = SinTab[r]; Cos = SinTab[r+M/4]; r = reverse(reverse(r,v-1)+1,v-1); for (lc3=0; lc3<bfy; lc3++) { /* motylki w ramach danej grupy */ xq = x[q]; yq = y[q]; xp = x[p] + xq*Cos + yq*Sin; x[q] = 2*x[p] - xp; x[p] = xp; yp = y[p] + yq*Cos - xq*Sin; y[q] = 2*y[p] - yp; y[p] = yp; p++; q++; } p += bfy; q += bfy; } grp *= 2; bfy /= 2; } /* Wyznaczenie kwadratu widma amplitudowego */ for (lc1=0; lc1<N; lc1++) x[lc1] = x[lc1]*x[lc1] + y[lc1]*y[lc1]; /* Tasowanie prek widma przywracajアce ich naturalne uporzアdkowanie */ for (lc1=0; lc1<N; lc1++) y[reverse(lc1,v)] = x[lc1]; /* Logarytmowanie widma [daB] */ for (lc1=0; lc1<N; lc1++) y[lc1] = decabel(y[lc1]); /* Obliczenie logarytmu mocy [daB] na podstawie twierdzenia Parsevala */ sum = 0.0; for (lc1=0; lc1<N; lc1++) sum += x[lc1]; return decabel(sum); }
webss