blob: 0abe030474233f2858376206c2f177eab0b562a1 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#include <stdio.h>
2#include <stdlib.h>
3#include <malloc.h>
4#include <math.h>
5
6static void fft(short *data,double *x,double *y,unsigned short n,short sign)
7{
8 unsigned short i,j,k,l,m,n1,n2;
9 double c,c1,e,s,s1,t,tr,ti;
10 //Calculate i = log2N
11 for (i = 0;i < n;i++)
12 {
13 x[i] = data[i];
14 //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"cal_freq_fft x[%d]=%f,data=%d!\n",i,x[i],data[i]);
15
16 }
17 for (j = 1,i = 1; i<20; i++)
18 {
19 m = i;
20 j = 2*j;
21 if (j == n)
22 break;
23 }
24
25 //¼ÆËãµûÐÎͼµÄÊäÈëϱ꣨Âëλµ¹¶Á£©
26 n1 = n - 1;
27 for (j=0,i=0; i<n1; i++)
28 {
29 if (i<j)
30 {
31 tr = x[j];
32 ti = y[j];
33 x[j] = x[i];
34 y[j] = y[i];
35 x[i] = tr;
36 y[i] = ti;
37 }
38 k = n/2;
39 while (k<(j+1))
40 {
41 j = j - k;
42 k = k/2;
43 }
44 j = j + k;
45 }
46 //¼ÆËãÿһ¼¶µÄÊä³ö£¬lΪijһ¼¶£¬iΪͬһ¼¶µÄ²»Í¬Èº£¬Ê¹ÓÃͬһÄڴ棨¼´Î»ÔËË㣩
47 n1 = 1;
48 for (l=1; l<=m; l++)
49 {
50 n1 = 2*n1;
51 n2 = n1/2;
52 e = 3.1415926/n2;
53 c = 1.0;
54 s = 0.0;
55 c1 = cos(e);
56 s1 = -sign*sin(e);
57 for (j=0; j<n2; j++)
58 {
59 for (i=j; i<n; i+=n1)
60 {
61 k = i + n2;
62 tr = c*x[k] - s*y[k];
63 ti = c*y[k] + s*x[k];
64 x[k] = x[i] - tr;
65 y[k] = y[i] - ti;
66 x[i] = x[i] + tr;
67 y[i] = y[i] + ti;
68 }
69 t = c;
70 c = c*c1 - s*s1;
71 s = t*s1 + s*c1;
72 }
73 }
74 //Èç¹ûÊÇÇóIFFT£¬ÔÙ³ýÒÔN
75 if (sign == -1)
76 {
77 for (i=0; i<n; i++)
78 {
79 x[i] /= n;
80 y[i] /= n;
81 }
82 }
83}
84static void max_fft(double *a,unsigned short n,unsigned short *h)
85{
86 unsigned short i = 0;
87 *h=5;
88 for (i=5;i<n;i++)
89 {
90 if (a[i]>a[*h])
91 *h=i;
92 }
93
94}
95
96static void abs_fft(double *x,double *y,unsigned short n,double *z)
97{
98 unsigned short i=0;
99
100 for (i= 0;i<n;i++)
101 {
102 z[i] =sqrt(x[i]*x[i]+y[i]*y[i]);
103 }
104
105
106
107}
108
109
110typedef struct
111{
112 double freqValue;
113 double freqAmp;
114}
115zDrvVp_Freqfft;
116
117int cal_freq_fft( short *data,zDrvVp_Freqfft *freqfft,unsigned short n, int fs)
118{
119 unsigned short h = 0;
120 unsigned short offset = 0;
121 double *x = NULL,*xi = NULL,*xvalue = NULL;
122 if ( data == NULL || freqfft == NULL || n <= 0 || fs < 0)
123 {
124 return -1;
125 }
126
127 if (n > 32768 || n < 2) // ÏÞÖÆÔÚ2µÄ1´ÎÃݵ½15´ÎÃÝ
128 return -1;
129
130 // ¼ì²énÊÇ·ñ2µÄÃÝ´Î
131 do
132 {
133 offset++;
134 h = n >> offset;
135 }while (h > 0);
136
137 if( n != (1 << (offset - 1))) return -1;
138
139 x=(double*)calloc(n, sizeof(double));
140 xi=(double*)calloc(n, sizeof(double));
141 xvalue=(double*)calloc(n, sizeof(double));
142
143 if(x && xi && xvalue)
144 {
145 fft(data,x,xi,n,1);
146 /*for(i=0;i<1024;i++)
147 {
148 zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"cal_freq_fft x[%d]=%f,xi[%d]=%f!\n",i,x[i],i,xi[i]);
149 }*/
150
151 abs_fft(x,xi,n/2,xvalue);
152 max_fft(xvalue,n/2,&h);
153 //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"h=%d!\n",h);
154 freqfft->freqValue = (h-1)*fs/((n)*1.0);
155 freqfft->freqAmp = xvalue[h]/(n/2);
156 //*freqValue = (h-1)*fs/((n)*1.0);
157 //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"n=%d!\n",n);
158 // freq = freqfft->freqValue;
159 //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"fs=%d!\n",fs);
160 //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"freq=%f!\n",freq);
161 //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"freqfft->freqAmp=%f!\n",freqfft->freqAmp);
162
163
164 free(x);
165 free(xi);
166 free(xvalue);
167 return 0;
168 }
169
170 if(x) free(x);
171 if(xi) free(xi);
172 if(xvalue) free(xvalue);
173
174
175 return -1;
176}