| [637] | 1 | #include "math.h" | 
|---|
|  | 2 |  | 
|---|
|  | 3 | #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr | 
|---|
|  | 4 |  | 
|---|
|  | 5 | void four1(float *data,int nn,int isign); | 
|---|
|  | 6 |  | 
|---|
|  | 7 | double souslin(double *y,int n);                /* soustrait la droite de y[0] à y[n-1]  */ | 
|---|
|  | 8 | void filtre(double *y,int n,double f); | 
|---|
|  | 9 | void spectre(double *y,int n); | 
|---|
|  | 10 | void spectreRMS(double *y,int n); | 
|---|
|  | 11 |  | 
|---|
|  | 12 |  | 
|---|
|  | 13 | /*  --------  filtre passe - bas du tableau double y[] -----------*/ | 
|---|
|  | 14 |  | 
|---|
|  | 15 | /*double souslin(double *y,int n)               /* soustrait la droite de y[0] à y[n-1] | 
|---|
|  | 16 | {double pas;int i; | 
|---|
|  | 17 | pas=(y[n-1]-y[0])/(double)(n-1); | 
|---|
|  | 18 | for (i=0;i<n;i++) y[i]=y[i]-y[0]-pas*(double)i; | 
|---|
|  | 19 | return(pas); | 
|---|
|  | 20 | } | 
|---|
|  | 21 | */ | 
|---|
|  | 22 |  | 
|---|
|  | 23 | double souslin(double *y,int n)         /* soustrait la pente et la moyenne     */ | 
|---|
|  | 24 | {double pas,mm=0;int i; | 
|---|
|  | 25 | pas=(y[n-1]-y[0])/(double)(n-1); | 
|---|
|  | 26 | for (i=0;i<n;i++) {y[i]=y[i]-pas*(double)i;mm+=y[i];} | 
|---|
|  | 27 | mm/=(double)n; | 
|---|
|  | 28 | for (i=0;i<n;i++) y[i]=y[i]-mm; | 
|---|
|  | 29 | return(pas); | 
|---|
|  | 30 | } | 
|---|
|  | 31 |  | 
|---|
|  | 32 | void filtre(double *y,int n,double f) | 
|---|
|  | 33 | { | 
|---|
|  | 34 | float *v,u;int i;double pas; | 
|---|
|  | 35 | v=(float *)y; | 
|---|
|  | 36 | pas=souslin(y,n); | 
|---|
|  | 37 | /* | 
|---|
|  | 38 | printf("y0 ... = %g %g %g %g %g\n",y[0],y[1],y[2],y[3],y[4]); | 
|---|
|  | 39 | printf("filtre avec bande=%g  : pente=%g \n",f,pas); | 
|---|
|  | 40 | */ | 
|---|
|  | 41 | for (i=0;i<n;i++)               v[i]=(float)y[i]; | 
|---|
|  | 42 | for (i=n-1;i>=0;i--)    {v[2*i+1]=v[i]/(float)n;v[2*i+2]=0;} | 
|---|
|  | 43 |  | 
|---|
|  | 44 | four1(v,n,1); | 
|---|
|  | 45 | for (i=(int)f;i<n/2;i++) | 
|---|
|  | 46 | {u=((double)i-f)/f; | 
|---|
|  | 47 | u=1/(1+2*u*u); | 
|---|
|  | 48 | v[2*i+1]=v[2*i+1]*u; | 
|---|
|  | 49 | v[2*i+2]=v[2*i+2]*u; | 
|---|
|  | 50 | v[2*n-2*i-1]=v[2*i+1]*u; | 
|---|
|  | 51 | v[2*n-2*i]=v[2*i+2]*u; | 
|---|
|  | 52 | } | 
|---|
|  | 53 | four1(v,n,-1); | 
|---|
|  | 54 | for (i=0;i<n;i++)               v[i]=v[2*i+1]; | 
|---|
|  | 55 | for (i=n-1;i>=0;i--)    y[i]= (double)v[i]; | 
|---|
|  | 56 | for (i=0;i<n;i++)       y[i]=y[i] + pas * (double)(i-n/2); | 
|---|
|  | 57 | } | 
|---|
|  | 58 |  | 
|---|
|  | 59 |  | 
|---|
|  | 60 |  | 
|---|
|  | 61 | /* -------spectre de fréquence du tableau double y[]-----------*/ | 
|---|
|  | 62 |  | 
|---|
|  | 63 | void spectreRMS(double *y,int n) | 
|---|
|  | 64 | {float *v;int i;float ym=0; | 
|---|
|  | 65 | v=(float *)y; | 
|---|
|  | 66 | // souslin(y,n); | 
|---|
|  | 67 | for (i=0;i<n;i++)               {v[i]=(float)y[i];ym=ym+v[i];} | 
|---|
|  | 68 | ym=ym/(float)n; | 
|---|
|  | 69 | for (i=n-1;i>=0;i--)            {v[2*i+1]=(v[i]-ym)/(float)n;v[2*i+2]=0;} | 
|---|
|  | 70 | four1(v,n,1); | 
|---|
|  | 71 | for (i=0;i<n;i++)               v[i]=sqrt(2*(v[2*i+1]*v[2*i+1]+v[2*i+2]*v[2*i+2])); | 
|---|
|  | 72 | for (i=n-1;i>=0;i--)    y[i]=(double)v[i]; | 
|---|
|  | 73 | } | 
|---|
|  | 74 |  | 
|---|
|  | 75 |  | 
|---|
|  | 76 |  | 
|---|
|  | 77 |  | 
|---|
|  | 78 | void spectre(double *y,int n) | 
|---|
|  | 79 | {float *v;int i;float ym=0; | 
|---|
|  | 80 | v=(float *)y; | 
|---|
|  | 81 | souslin(y,n); | 
|---|
|  | 82 | for (i=0;i<n;i++)               {v[i]=(float)y[i];ym=ym+v[i];} | 
|---|
|  | 83 | ym=ym/(float)n; | 
|---|
|  | 84 | for (i=n-1;i>=0;i--)            {v[2*i+1]=(v[i]-ym)/(float)n;v[2*i+2]=0;} | 
|---|
|  | 85 | four1(v,n,1); | 
|---|
|  | 86 | for (i=0;i<n;i++)               v[i]=v[2*i+1]*v[2*i+1]+v[2*i+2]*v[2*i+2]; | 
|---|
|  | 87 | for (i=n-1;i>=0;i--)    y[i]=(double)v[i]; | 
|---|
|  | 88 | } | 
|---|
|  | 89 |  | 
|---|
|  | 90 |  | 
|---|
|  | 91 |  | 
|---|
|  | 92 | /* ----------------- transformée de Fourier complexe ---------*/ | 
|---|
|  | 93 |  | 
|---|
|  | 94 | void four1(float *data,int nn,int isign)   /* data tableau de 1 à 2*nn  */ | 
|---|
|  | 95 | /* isign=1 --> Tf directe   data = real-imag-real-imag ........ */ | 
|---|
|  | 96 |  | 
|---|
|  | 97 | /* isign=-1 --> Tf inverse    */ | 
|---|
|  | 98 | { | 
|---|
|  | 99 | int n,mmax,m,j,istep,i; | 
|---|
|  | 100 | double wtemp,wr,wpr,wpi,wi,theta; | 
|---|
|  | 101 | float tempr,tempi; | 
|---|
|  | 102 |  | 
|---|
|  | 103 | n=nn << 1; | 
|---|
|  | 104 | j=1; | 
|---|
|  | 105 | for (i=1;i<n;i+=2) { | 
|---|
|  | 106 |  | 
|---|
|  | 107 | if (j > i) { | 
|---|
|  | 108 | SWAP(data[j],data[i]); | 
|---|
|  | 109 | SWAP(data[j+1],data[i+1]); | 
|---|
|  | 110 | } | 
|---|
|  | 111 | m=n >> 1; | 
|---|
|  | 112 | while (m >= 2 && j > m) { | 
|---|
|  | 113 | j -= m; | 
|---|
|  | 114 | m >>= 1; | 
|---|
|  | 115 | } | 
|---|
|  | 116 | j += m; | 
|---|
|  | 117 | } | 
|---|
|  | 118 | mmax=2; | 
|---|
|  | 119 | while (n > mmax) { | 
|---|
|  | 120 | istep=2*mmax; | 
|---|
|  | 121 | theta=6.28318530717959/(isign*mmax); | 
|---|
|  | 122 | wtemp=sin(0.5*theta); | 
|---|
|  | 123 | wpr = -2.0*wtemp*wtemp; | 
|---|
|  | 124 | wpi=sin(theta); | 
|---|
|  | 125 | wr=1.0; | 
|---|
|  | 126 | wi=0.0; | 
|---|
|  | 127 | for (m=1;m<mmax;m+=2) { | 
|---|
|  | 128 | for (i=m;i<=n;i+=istep) { | 
|---|
|  | 129 | j=i+mmax; | 
|---|
|  | 130 | tempr=wr*data[j]-wi*data[j+1]; | 
|---|
|  | 131 | tempi=wr*data[j+1]+wi*data[j]; | 
|---|
|  | 132 | data[j]=data[i]-tempr; | 
|---|
|  | 133 | data[j+1]=data[i+1]-tempi; | 
|---|
|  | 134 | data[i] += tempr; | 
|---|
|  | 135 | data[i+1] += tempi; | 
|---|
|  | 136 | } | 
|---|
|  | 137 | wr=(wtemp=wr)*wpr-wi*wpi+wr; | 
|---|
|  | 138 | wi=wi*wpr+wtemp*wpi+wi; | 
|---|
|  | 139 | } | 
|---|
|  | 140 | mmax=istep; | 
|---|
|  | 141 | } | 
|---|
|  | 142 | } | 
|---|
|  | 143 |  | 
|---|
|  | 144 | #undef SWAP | 
|---|
|  | 145 |  | 
|---|