Chris@184
|
1 #include <stdlib.h>
|
Chris@184
|
2 #include <string.h>
|
Chris@184
|
3 #include <stdio.h>
|
Chris@184
|
4 #include "kiss_fft.h"
|
Chris@184
|
5 #include "kiss_fftr.h"
|
Chris@184
|
6 #include <limits.h>
|
Chris@184
|
7
|
Chris@184
|
8
|
Chris@184
|
9 static
|
Chris@184
|
10 double two_tone_test( int nfft, int bin1,int bin2)
|
Chris@184
|
11 {
|
Chris@184
|
12 kiss_fftr_cfg cfg = NULL;
|
Chris@184
|
13 kiss_fft_cpx *kout = NULL;
|
Chris@184
|
14 kiss_fft_scalar *tbuf = NULL;
|
Chris@184
|
15
|
Chris@184
|
16 int i;
|
Chris@184
|
17 double f1 = bin1*2*M_PI/nfft;
|
Chris@184
|
18 double f2 = bin2*2*M_PI/nfft;
|
Chris@184
|
19 double sigpow=0;
|
Chris@184
|
20 double noisepow=0;
|
Chris@184
|
21 #if FIXED_POINT==32
|
Chris@184
|
22 long maxrange = LONG_MAX;
|
Chris@184
|
23 #else
|
Chris@184
|
24 long maxrange = SHRT_MAX;/* works fine for float too*/
|
Chris@184
|
25 #endif
|
Chris@184
|
26
|
Chris@184
|
27 cfg = kiss_fftr_alloc(nfft , 0, NULL, NULL);
|
Chris@184
|
28 tbuf = KISS_FFT_MALLOC(nfft * sizeof(kiss_fft_scalar));
|
Chris@184
|
29 kout = KISS_FFT_MALLOC(nfft * sizeof(kiss_fft_cpx));
|
Chris@184
|
30
|
Chris@184
|
31 /* generate a signal with two tones*/
|
Chris@184
|
32 for (i = 0; i < nfft; i++) {
|
Chris@184
|
33 #ifdef USE_SIMD
|
Chris@184
|
34 tbuf[i] = _mm_set1_ps( (maxrange>>1)*cos(f1*i)
|
Chris@184
|
35 + (maxrange>>1)*cos(f2*i) );
|
Chris@184
|
36 #else
|
Chris@184
|
37 tbuf[i] = (maxrange>>1)*cos(f1*i)
|
Chris@184
|
38 + (maxrange>>1)*cos(f2*i);
|
Chris@184
|
39 #endif
|
Chris@184
|
40 }
|
Chris@184
|
41
|
Chris@184
|
42 kiss_fftr(cfg, tbuf, kout);
|
Chris@184
|
43
|
Chris@184
|
44 for (i=0;i < (nfft/2+1);++i) {
|
Chris@184
|
45 #ifdef USE_SIMD
|
Chris@184
|
46 double tmpr = (double)*(float*)&kout[i].r / (double)maxrange;
|
Chris@184
|
47 double tmpi = (double)*(float*)&kout[i].i / (double)maxrange;
|
Chris@184
|
48 #else
|
Chris@184
|
49 double tmpr = (double)kout[i].r / (double)maxrange;
|
Chris@184
|
50 double tmpi = (double)kout[i].i / (double)maxrange;
|
Chris@184
|
51 #endif
|
Chris@184
|
52 double mag2 = tmpr*tmpr + tmpi*tmpi;
|
Chris@184
|
53 if (i!=0 && i!= nfft/2)
|
Chris@184
|
54 mag2 *= 2; /* all bins except DC and Nyquist have symmetric counterparts implied*/
|
Chris@184
|
55
|
Chris@184
|
56 /* if there is power in one of the expected bins, it is signal, otherwise noise*/
|
Chris@184
|
57 if ( i!=bin1 && i != bin2 )
|
Chris@184
|
58 noisepow += mag2;
|
Chris@184
|
59 else
|
Chris@184
|
60 sigpow += mag2;
|
Chris@184
|
61 }
|
Chris@184
|
62 kiss_fft_cleanup();
|
Chris@184
|
63 /*printf("TEST %d,%d,%d noise @ %fdB\n",nfft,bin1,bin2,10*log10(noisepow/sigpow +1e-30) );*/
|
Chris@184
|
64 return 10*log10(sigpow/(noisepow+1e-50) );
|
Chris@184
|
65 }
|
Chris@184
|
66
|
Chris@184
|
67 int main(int argc,char ** argv)
|
Chris@184
|
68 {
|
Chris@184
|
69 int nfft = 4*2*2*3*5;
|
Chris@184
|
70 if (argc>1) nfft = atoi(argv[1]);
|
Chris@184
|
71
|
Chris@184
|
72 int i,j;
|
Chris@184
|
73 double minsnr = 500;
|
Chris@184
|
74 double maxsnr = -500;
|
Chris@184
|
75 double snr;
|
Chris@184
|
76 for (i=0;i<nfft/2;i+= (nfft>>4)+1) {
|
Chris@184
|
77 for (j=i;j<nfft/2;j+=(nfft>>4)+7) {
|
Chris@184
|
78 snr = two_tone_test(nfft,i,j);
|
Chris@184
|
79 if (snr<minsnr) {
|
Chris@184
|
80 minsnr=snr;
|
Chris@184
|
81 }
|
Chris@184
|
82 if (snr>maxsnr) {
|
Chris@184
|
83 maxsnr=snr;
|
Chris@184
|
84 }
|
Chris@184
|
85 }
|
Chris@184
|
86 }
|
Chris@184
|
87 snr = two_tone_test(nfft,nfft/2,nfft/2);
|
Chris@184
|
88 if (snr<minsnr) minsnr=snr;
|
Chris@184
|
89 if (snr>maxsnr) maxsnr=snr;
|
Chris@184
|
90
|
Chris@184
|
91 printf("TwoToneTest: snr ranges from %ddB to %ddB\n",(int)minsnr,(int)maxsnr);
|
Chris@184
|
92 printf("sizeof(kiss_fft_scalar) = %d\n",(int)sizeof(kiss_fft_scalar) );
|
Chris@184
|
93 return 0;
|
Chris@184
|
94 }
|