Mercurial > hg > qm-dsp
comparison ext/kissfft/test/test_real.c @ 184:76ec2365b250
Bring in kissfft into this repo (formerly a subrepo, but the remote is not responding)
author | Chris Cannam |
---|---|
date | Tue, 21 Jul 2015 07:34:15 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
183:7ab3539e92e3 | 184:76ec2365b250 |
---|---|
1 #include "kiss_fftr.h" | |
2 #include "_kiss_fft_guts.h" | |
3 #include <sys/times.h> | |
4 #include <time.h> | |
5 #include <unistd.h> | |
6 | |
7 static double cputime(void) | |
8 { | |
9 struct tms t; | |
10 times(&t); | |
11 return (double)(t.tms_utime + t.tms_stime)/ sysconf(_SC_CLK_TCK) ; | |
12 } | |
13 | |
14 static | |
15 kiss_fft_scalar rand_scalar(void) | |
16 { | |
17 #ifdef USE_SIMD | |
18 return _mm_set1_ps(rand()-RAND_MAX/2); | |
19 #else | |
20 kiss_fft_scalar s = (kiss_fft_scalar)(rand() -RAND_MAX/2); | |
21 return s/2; | |
22 #endif | |
23 } | |
24 | |
25 static | |
26 double snr_compare( kiss_fft_cpx * vec1,kiss_fft_cpx * vec2, int n) | |
27 { | |
28 int k; | |
29 double sigpow=1e-10,noisepow=1e-10,err,snr,scale=0; | |
30 | |
31 #ifdef USE_SIMD | |
32 float *fv1 = (float*)vec1; | |
33 float *fv2 = (float*)vec2; | |
34 for (k=0;k<8*n;++k) { | |
35 sigpow += *fv1 * *fv1; | |
36 err = *fv1 - *fv2; | |
37 noisepow += err*err; | |
38 ++fv1; | |
39 ++fv2; | |
40 } | |
41 #else | |
42 for (k=0;k<n;++k) { | |
43 sigpow += (double)vec1[k].r * (double)vec1[k].r + | |
44 (double)vec1[k].i * (double)vec1[k].i; | |
45 err = (double)vec1[k].r - (double)vec2[k].r; | |
46 noisepow += err * err; | |
47 err = (double)vec1[k].i - (double)vec2[k].i; | |
48 noisepow += err * err; | |
49 | |
50 if (vec1[k].r) | |
51 scale +=(double) vec2[k].r / (double)vec1[k].r; | |
52 } | |
53 #endif | |
54 snr = 10*log10( sigpow / noisepow ); | |
55 scale /= n; | |
56 if (snr<10) { | |
57 printf( "\npoor snr, try a scaling factor %f\n" , scale ); | |
58 exit(1); | |
59 } | |
60 return snr; | |
61 } | |
62 | |
63 #ifndef NUMFFTS | |
64 #define NUMFFTS 10000 | |
65 #endif | |
66 | |
67 | |
68 int main(int argc,char ** argv) | |
69 { | |
70 int nfft = 8*3*5; | |
71 double ts,tfft,trfft; | |
72 int i; | |
73 if (argc>1) | |
74 nfft = atoi(argv[1]); | |
75 kiss_fft_cpx cin[nfft]; | |
76 kiss_fft_cpx cout[nfft]; | |
77 kiss_fft_cpx sout[nfft]; | |
78 kiss_fft_cfg kiss_fft_state; | |
79 kiss_fftr_cfg kiss_fftr_state; | |
80 | |
81 kiss_fft_scalar rin[nfft+2]; | |
82 kiss_fft_scalar rout[nfft+2]; | |
83 kiss_fft_scalar zero; | |
84 memset(&zero,0,sizeof(zero) ); // ugly way of setting short,int,float,double, or __m128 to zero | |
85 | |
86 srand(time(0)); | |
87 | |
88 for (i=0;i<nfft;++i) { | |
89 rin[i] = rand_scalar(); | |
90 cin[i].r = rin[i]; | |
91 cin[i].i = zero; | |
92 } | |
93 | |
94 kiss_fft_state = kiss_fft_alloc(nfft,0,0,0); | |
95 kiss_fftr_state = kiss_fftr_alloc(nfft,0,0,0); | |
96 kiss_fft(kiss_fft_state,cin,cout); | |
97 kiss_fftr(kiss_fftr_state,rin,sout); | |
98 /* | |
99 printf(" results from kiss_fft : (%f,%f), (%f,%f), (%f,%f) ...\n " | |
100 , (float)cout[0].r , (float)cout[0].i | |
101 , (float)cout[1].r , (float)cout[1].i | |
102 , (float)cout[2].r , (float)cout[2].i); | |
103 printf(" results from kiss_fftr: (%f,%f), (%f,%f), (%f,%f) ...\n " | |
104 , (float)sout[0].r , (float)sout[0].i | |
105 , (float)sout[1].r , (float)sout[1].i | |
106 , (float)sout[2].r , (float)sout[2].i); | |
107 */ | |
108 | |
109 printf( "nfft=%d, inverse=%d, snr=%g\n", | |
110 nfft,0, snr_compare(cout,sout,(nfft/2)+1) ); | |
111 ts = cputime(); | |
112 for (i=0;i<NUMFFTS;++i) { | |
113 kiss_fft(kiss_fft_state,cin,cout); | |
114 } | |
115 tfft = cputime() - ts; | |
116 | |
117 ts = cputime(); | |
118 for (i=0;i<NUMFFTS;++i) { | |
119 kiss_fftr( kiss_fftr_state, rin, cout ); | |
120 /* kiss_fftri(kiss_fftr_state,cout,rin); */ | |
121 } | |
122 trfft = cputime() - ts; | |
123 | |
124 printf("%d complex ffts took %gs, real took %gs\n",NUMFFTS,tfft,trfft); | |
125 | |
126 free(kiss_fft_state); | |
127 free(kiss_fftr_state); | |
128 | |
129 kiss_fft_state = kiss_fft_alloc(nfft,1,0,0); | |
130 kiss_fftr_state = kiss_fftr_alloc(nfft,1,0,0); | |
131 | |
132 memset(cin,0,sizeof(cin)); | |
133 #if 1 | |
134 for (i=1;i< nfft/2;++i) { | |
135 //cin[i].r = (kiss_fft_scalar)(rand()-RAND_MAX/2); | |
136 cin[i].r = rand_scalar(); | |
137 cin[i].i = rand_scalar(); | |
138 } | |
139 #else | |
140 cin[0].r = 12000; | |
141 cin[3].r = 12000; | |
142 cin[nfft/2].r = 12000; | |
143 #endif | |
144 | |
145 // conjugate symmetry of real signal | |
146 for (i=1;i< nfft/2;++i) { | |
147 cin[nfft-i].r = cin[i].r; | |
148 cin[nfft-i].i = - cin[i].i; | |
149 } | |
150 | |
151 kiss_fft(kiss_fft_state,cin,cout); | |
152 kiss_fftri(kiss_fftr_state,cin,rout); | |
153 /* | |
154 printf(" results from inverse kiss_fft : (%f,%f), (%f,%f), (%f,%f), (%f,%f), (%f,%f) ...\n " | |
155 , (float)cout[0].r , (float)cout[0].i , (float)cout[1].r , (float)cout[1].i , (float)cout[2].r , (float)cout[2].i , (float)cout[3].r , (float)cout[3].i , (float)cout[4].r , (float)cout[4].i | |
156 ); | |
157 | |
158 printf(" results from inverse kiss_fftr: %f,%f,%f,%f,%f ... \n" | |
159 ,(float)rout[0] ,(float)rout[1] ,(float)rout[2] ,(float)rout[3] ,(float)rout[4]); | |
160 */ | |
161 for (i=0;i<nfft;++i) { | |
162 sout[i].r = rout[i]; | |
163 sout[i].i = zero; | |
164 } | |
165 | |
166 printf( "nfft=%d, inverse=%d, snr=%g\n", | |
167 nfft,1, snr_compare(cout,sout,nfft/2) ); | |
168 free(kiss_fft_state); | |
169 free(kiss_fftr_state); | |
170 | |
171 return 0; | |
172 } |