shun_iwasawa a35b8f
#include <stdlib.h></stdlib.h>
shun_iwasawa a35b8f
#include <string.h></string.h>
shun_iwasawa a35b8f
#include <stdio.h></stdio.h>
shun_iwasawa a35b8f
#include "kiss_fft.h"
shun_iwasawa a35b8f
#include "kiss_fftr.h"
shun_iwasawa a35b8f
#include <limits.h></limits.h>
shun_iwasawa a35b8f
shun_iwasawa a35b8f
shun_iwasawa a35b8f
static
shun_iwasawa a35b8f
double two_tone_test( int nfft, int bin1,int bin2)
shun_iwasawa a35b8f
{
shun_iwasawa a35b8f
    kiss_fftr_cfg cfg	= NULL;
shun_iwasawa a35b8f
    kiss_fft_cpx *kout	= NULL;
shun_iwasawa a35b8f
    kiss_fft_scalar *tbuf = NULL;
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    int i;
shun_iwasawa a35b8f
    double f1 = bin1*2*M_PI/nfft;
shun_iwasawa a35b8f
    double f2 = bin2*2*M_PI/nfft;
shun_iwasawa a35b8f
    double sigpow=0;
shun_iwasawa a35b8f
    double noisepow=0;
shun_iwasawa a35b8f
#if FIXED_POINT==32
shun_iwasawa a35b8f
    long maxrange = LONG_MAX;
shun_iwasawa a35b8f
#else
shun_iwasawa a35b8f
    long maxrange = SHRT_MAX;/* works fine for float too*/
shun_iwasawa a35b8f
#endif
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    cfg = kiss_fftr_alloc(nfft , 0, NULL, NULL);
shun_iwasawa a35b8f
    tbuf	= KISS_FFT_MALLOC(nfft * sizeof(kiss_fft_scalar));
shun_iwasawa a35b8f
    kout	= KISS_FFT_MALLOC(nfft * sizeof(kiss_fft_cpx));
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    /* generate a signal with two tones*/
shun_iwasawa a35b8f
    for (i = 0; i < nfft; i++) {
shun_iwasawa a35b8f
#ifdef USE_SIMD
shun_iwasawa a35b8f
        tbuf[i] = _mm_set1_ps( (maxrange>>1)*cos(f1*i)
shun_iwasawa a35b8f
                             + (maxrange>>1)*cos(f2*i) );
shun_iwasawa a35b8f
#else        
shun_iwasawa a35b8f
        tbuf[i] =  (maxrange>>1)*cos(f1*i)
shun_iwasawa a35b8f
                 + (maxrange>>1)*cos(f2*i);
shun_iwasawa a35b8f
#endif        
shun_iwasawa a35b8f
    }
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    kiss_fftr(cfg, tbuf, kout);
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    for (i=0;i < (nfft/2+1);++i) {
shun_iwasawa a35b8f
#ifdef USE_SIMD        
shun_iwasawa a35b8f
        double tmpr = (double)*(float*)&kout[i].r / (double)maxrange;
shun_iwasawa a35b8f
        double tmpi = (double)*(float*)&kout[i].i / (double)maxrange;
shun_iwasawa a35b8f
#else
shun_iwasawa a35b8f
        double tmpr = (double)kout[i].r / (double)maxrange;
shun_iwasawa a35b8f
        double tmpi = (double)kout[i].i / (double)maxrange;
shun_iwasawa a35b8f
#endif
shun_iwasawa a35b8f
        double mag2 = tmpr*tmpr + tmpi*tmpi;
shun_iwasawa a35b8f
        if (i!=0 && i!= nfft/2)
shun_iwasawa a35b8f
            mag2 *= 2; /* all bins except DC and Nyquist have symmetric counterparts implied*/
shun_iwasawa a35b8f
shun_iwasawa a35b8f
        /* if there is power in one of the expected bins, it is signal, otherwise noise*/
shun_iwasawa a35b8f
        if ( i!=bin1 && i != bin2 ) 
shun_iwasawa a35b8f
            noisepow += mag2;
shun_iwasawa a35b8f
        else
shun_iwasawa a35b8f
            sigpow += mag2;
shun_iwasawa a35b8f
    }
shun_iwasawa a35b8f
    kiss_fft_cleanup();
shun_iwasawa a35b8f
    /*printf("TEST %d,%d,%d noise @ %fdB\n",nfft,bin1,bin2,10*log10(noisepow/sigpow +1e-30) );*/
shun_iwasawa a35b8f
    return 10*log10(sigpow/(noisepow+1e-50) );
shun_iwasawa a35b8f
}
shun_iwasawa a35b8f
shun_iwasawa a35b8f
int main(int argc,char ** argv)
shun_iwasawa a35b8f
{
shun_iwasawa a35b8f
    int nfft = 4*2*2*3*5;
shun_iwasawa a35b8f
    if (argc>1) nfft = atoi(argv[1]);
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    int i,j;
shun_iwasawa a35b8f
    double minsnr = 500;
shun_iwasawa a35b8f
    double maxsnr = -500;
shun_iwasawa a35b8f
    double snr;
shun_iwasawa a35b8f
    for (i=0;i<nfft 2;i+="(nfft">>4)+1) {</nfft>
shun_iwasawa a35b8f
        for (j=i;j<nfft 2;j+="(nfft">>4)+7) {</nfft>
shun_iwasawa a35b8f
            snr = two_tone_test(nfft,i,j);
shun_iwasawa a35b8f
            if (snr
shun_iwasawa a35b8f
                minsnr=snr;
shun_iwasawa a35b8f
            }
shun_iwasawa a35b8f
            if (snr>maxsnr) {
shun_iwasawa a35b8f
                maxsnr=snr;
shun_iwasawa a35b8f
            }
shun_iwasawa a35b8f
        }
shun_iwasawa a35b8f
    }
shun_iwasawa a35b8f
    snr = two_tone_test(nfft,nfft/2,nfft/2);
shun_iwasawa a35b8f
    if (snr
shun_iwasawa a35b8f
    if (snr>maxsnr) maxsnr=snr;
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    printf("TwoToneTest: snr ranges from %ddB to %ddB\n",(int)minsnr,(int)maxsnr);
shun_iwasawa a35b8f
    printf("sizeof(kiss_fft_scalar) = %d\n",(int)sizeof(kiss_fft_scalar) );
shun_iwasawa a35b8f
    return 0;
shun_iwasawa a35b8f
}