annotate ext/kissfft/test/twotonetest.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
rev   line source
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 }