annotate ext/kissfft/test/twotonetest.c @ 409:1f1999b0f577

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