| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <malloc.h> | |
| #include <math.h> | |
| static void fft(short *data,double *x,double *y,unsigned short n,short sign) | |
| { | |
| unsigned short i,j,k,l,m,n1,n2; | |
| double c,c1,e,s,s1,t,tr,ti; | |
| //Calculate i = log2N | |
| for (i = 0;i < n;i++) | |
| { | |
| x[i] = data[i]; | |
| //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"cal_freq_fft x[%d]=%f,data=%d!\n",i,x[i],data[i]); | |
| } | |
| for (j = 1,i = 1; i<20; i++) | |
| { | |
| m = i; | |
| j = 2*j; | |
| if (j == n) | |
| break; | |
| } | |
| //¼ÆËãµûÐÎͼµÄÊäÈëϱ꣨Âëλµ¹¶Á£© | |
| n1 = n - 1; | |
| for (j=0,i=0; i<n1; i++) | |
| { | |
| if (i<j) | |
| { | |
| tr = x[j]; | |
| ti = y[j]; | |
| x[j] = x[i]; | |
| y[j] = y[i]; | |
| x[i] = tr; | |
| y[i] = ti; | |
| } | |
| k = n/2; | |
| while (k<(j+1)) | |
| { | |
| j = j - k; | |
| k = k/2; | |
| } | |
| j = j + k; | |
| } | |
| //¼ÆËãÿһ¼¶µÄÊä³ö£¬lΪijһ¼¶£¬iΪͬһ¼¶µÄ²»Í¬Èº£¬Ê¹ÓÃͬһÄڴ棨¼´Î»ÔËË㣩 | |
| n1 = 1; | |
| for (l=1; l<=m; l++) | |
| { | |
| n1 = 2*n1; | |
| n2 = n1/2; | |
| e = 3.1415926/n2; | |
| c = 1.0; | |
| s = 0.0; | |
| c1 = cos(e); | |
| s1 = -sign*sin(e); | |
| for (j=0; j<n2; j++) | |
| { | |
| for (i=j; i<n; i+=n1) | |
| { | |
| k = i + n2; | |
| tr = c*x[k] - s*y[k]; | |
| ti = c*y[k] + s*x[k]; | |
| x[k] = x[i] - tr; | |
| y[k] = y[i] - ti; | |
| x[i] = x[i] + tr; | |
| y[i] = y[i] + ti; | |
| } | |
| t = c; | |
| c = c*c1 - s*s1; | |
| s = t*s1 + s*c1; | |
| } | |
| } | |
| //Èç¹ûÊÇÇóIFFT£¬ÔÙ³ýÒÔN | |
| if (sign == -1) | |
| { | |
| for (i=0; i<n; i++) | |
| { | |
| x[i] /= n; | |
| y[i] /= n; | |
| } | |
| } | |
| } | |
| static void max_fft(double *a,unsigned short n,unsigned short *h) | |
| { | |
| unsigned short i = 0; | |
| *h=5; | |
| for (i=5;i<n;i++) | |
| { | |
| if (a[i]>a[*h]) | |
| *h=i; | |
| } | |
| } | |
| static void abs_fft(double *x,double *y,unsigned short n,double *z) | |
| { | |
| unsigned short i=0; | |
| for (i= 0;i<n;i++) | |
| { | |
| z[i] =sqrt(x[i]*x[i]+y[i]*y[i]); | |
| } | |
| } | |
| typedef struct | |
| { | |
| double freqValue; | |
| double freqAmp; | |
| } | |
| zDrvVp_Freqfft; | |
| int cal_freq_fft( short *data,zDrvVp_Freqfft *freqfft,unsigned short n, int fs) | |
| { | |
| unsigned short h = 0; | |
| unsigned short offset = 0; | |
| double *x = NULL,*xi = NULL,*xvalue = NULL; | |
| if ( data == NULL || freqfft == NULL || n <= 0 || fs < 0) | |
| { | |
| return -1; | |
| } | |
| if (n > 32768 || n < 2) // ÏÞÖÆÔÚ2µÄ1´ÎÃݵ½15´ÎÃÝ | |
| return -1; | |
| // ¼ì²énÊÇ·ñ2µÄÃÝ´Î | |
| do | |
| { | |
| offset++; | |
| h = n >> offset; | |
| }while (h > 0); | |
| if( n != (1 << (offset - 1))) return -1; | |
| x=(double*)calloc(n, sizeof(double)); | |
| xi=(double*)calloc(n, sizeof(double)); | |
| xvalue=(double*)calloc(n, sizeof(double)); | |
| if(x && xi && xvalue) | |
| { | |
| fft(data,x,xi,n,1); | |
| /*for(i=0;i<1024;i++) | |
| { | |
| zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"cal_freq_fft x[%d]=%f,xi[%d]=%f!\n",i,x[i],i,xi[i]); | |
| }*/ | |
| abs_fft(x,xi,n/2,xvalue); | |
| max_fft(xvalue,n/2,&h); | |
| //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"h=%d!\n",h); | |
| freqfft->freqValue = (h-1)*fs/((n)*1.0); | |
| freqfft->freqAmp = xvalue[h]/(n/2); | |
| //*freqValue = (h-1)*fs/((n)*1.0); | |
| //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"n=%d!\n",n); | |
| // freq = freqfft->freqValue; | |
| //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"fs=%d!\n",fs); | |
| //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"freq=%f!\n",freq); | |
| //zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL,"freqfft->freqAmp=%f!\n",freqfft->freqAmp); | |
| free(x); | |
| free(xi); | |
| free(xvalue); | |
| return 0; | |
| } | |
| if(x) free(x); | |
| if(xi) free(xi); | |
| if(xvalue) free(xvalue); | |
| return -1; | |
| } |