twotonetest.c 2.6 KB

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