fine_delay_est.cpp
上传用户:jtjnyq9001
上传日期:2014-11-21
资源大小:3974k
文件大小:14k
源码类别:

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = coarse_delay_est.cpp
  3. //
  4. #include <stdlib.h>
  5. #include <complex>
  6. //#include <fstream>
  7. #include "parmfile.h"
  8. #include "fine_delay_est.h"
  9. #include "misdefs.h"
  10. #include "model_graph.h"
  11. #include "sigplot.h"
  12. #include "dit_pino_T.h"
  13. #include "dit_nipo_T.h"
  14. #include "dft_T.h"
  15. #include "unwrap.h"
  16. #include "complex_io.h"
  17. extern ParmFile* ParmInput;
  18. //extern SignalPlotter SigPlot;
  19. extern int PassNumber;
  20. #ifdef _DEBUG
  21.   extern ofstream *DebugFile;
  22. #endif
  23. //ofstream CorrFile("corr_res.txt", ios::out);
  24. //======================================================
  25. FineDelayEstimator::FineDelayEstimator( char* instance_name,
  26.                                 PracSimModel* outer_model,
  27.                                 Signal<float>* in_sig,
  28.                                 Signal<float>* ref_sig,
  29.                                 //Signal<float>* out_sig,
  30.                                 Control<bool>* estim_enabled_cntl, //input
  31.                                 Control<bool>* dly_est_is_valid_cntl, //output
  32.                                 Control<float>* estimated_delay_cntl)//output
  33.                                 //Control<int>* samps_delay_at_max_corr)
  34.             :PracSimModel(instance_name,
  35.                           outer_model)
  36. {
  37.    In_Sig = in_sig;
  38.    Ref_Sig = ref_sig;
  39. //   Out_Sig = out_sig;
  40.    Estim_Enabled_Cntl = estim_enabled_cntl;
  41.    Estimated_Delay_Cntl = estimated_delay_cntl;
  42. //   Samps_Delay_At_Max_Corr = samps_delay_at_max_corr;
  43.    Dly_Est_Is_Valid_Cntl = dly_est_is_valid_cntl;
  44.    Dly_Est_Is_Valid_Cntl->SetValue(false);
  45.   OPEN_PARM_BLOCK;
  46.   GET_INT_PARM(Num_Corr_Passes);
  47. //  GET_BOOL_PARM(Limited_Search_Window_Enab);
  48. //  if(Limited_Search_Window_Enab)
  49. //  {
  50. //     GET_INT_PARM(Search_Window_Beg);
  51. //     GET_INT_PARM(Search_Window_End);
  52. //  }
  53.   GET_BOOL_PARM(Invert_Input_Sig_Enab);
  54. //  GET_INT_PARM(Smoothing_Sidelobe_Len);
  55. //  MAKE_OUTPUT(Out_Sig);
  56.   MAKE_INPUT(In_Sig);
  57.   MAKE_INPUT(Ref_Sig);
  58. //  SAME_RATE(In_Sig, Out_Sig);
  59. //  SAME_RATE(Ref_Sig, Out_Sig);
  60.   //control output: Delay_At_Max_Corr
  61.   //control output: Max_Corr_Angle_Out
  62.   Spectrum_File = new ofstream("spectrum.txt", ios::out);
  63. }
  64. FineDelayEstimator::~FineDelayEstimator( void ){ };
  65. void FineDelayEstimator::Initialize(void)
  66. {
  67.    int dummy_size, i;
  68.    double tmp_nsexp;
  69.    double frac_part, int_part;
  70.    float sample=0;
  71.    Proc_Block_Size = In_Sig->GetBlockSize();
  72.    Samp_Intvl = In_Sig->GetSampIntvl();
  73.    In_Sig_Buf = new AuxSignalBuffer<float>(sample, Proc_Block_Size);
  74.    Ref_Sig_Buf = new AuxSignalBuffer<float>(sample, Proc_Block_Size);
  75.    tmp_nsexp = log10(double(Proc_Block_Size))/log10(2.0);
  76.    frac_part = modf(tmp_nsexp, &int_part);
  77.    if( frac_part != 0.0 )
  78.       {
  79.       Ns_Exp = int_part + 2;
  80.       }
  81.    else
  82.       {
  83.       Ns_Exp = int_part + 1;
  84.       }
  85.    Full_Corr_Size = pow(2.0, Ns_Exp);
  86.    X = new std::complex<float>[Full_Corr_Size];
  87.    Y = new std::complex<float>[Full_Corr_Size];
  88. //   if(Limited_Search_Window_Enab)
  89. //      {
  90. //      if(Search_Window_Beg < 0)
  91. //         {
  92. //         Neg_Window_Beg = Full_Corr_Size + Search_Window_Beg;
  93. //         Pos_Window_Beg = 0;
  94. //         }
  95. //      else
  96. //         {
  97. //         Neg_Window_Beg = Full_Corr_Size;
  98. //         Pos_Window_Beg = Search_Window_Beg;
  99. //         }
  100. //      if(Search_Window_End >= 0)
  101. //         {
  102. //         Pos_Window_End = Search_Window_End;
  103. //         Neg_Window_End = Full_Corr_Size-1;
  104. //         }
  105. //      else
  106. //         {
  107. //         Pos_Window_End = -1;
  108. //         Neg_Window_End = Search_Window_End;
  109. //         }
  110. //      }
  111. //   else
  112. //      {
  113. //      Neg_Window_Beg = Full_Corr_Size/2 + 1;
  114. //      Neg_Window_End = Full_Corr_Size-1;
  115. //      Pos_Window_Beg = 0;
  116. //      Pos_Window_End = Full_Corr_Size/2 - 1;
  117. //      }
  118.    dummy_size = Full_Corr_Size - Proc_Block_Size;
  119.    Zero_Array = new std::complex<float>[dummy_size];
  120.    for( i = 0; i < dummy_size; i++)
  121.    {
  122.       Zero_Array[i] = std::complex<float>(0.0, 0.0);
  123.    }
  124.    Size_Of_FComplex = sizeof(std::complex<float>);
  125.    Max_Corr = 0.0;
  126.    Max_Corr_Time = 0.0;
  127.   Diff_Response = new std::complex<float>[Full_Corr_Size];
  128.   for( i=0; i<Full_Corr_Size; i++)
  129.   {
  130.     Diff_Response[i] = 0.0;
  131.   }
  132.    Corr_Pass_Count = 0;
  133.    //INITIALIZATION_REPORT(BasicResults);
  134.    return;
  135. }
  136. int FineDelayEstimator::Execute()
  137. {
  138.    using std::complex;
  139.    float *in_sig_ptr, *in_sig_buf_ptr;
  140.    float *ref_sig_ptr, *ref_sig_buf_ptr;
  141.    int in_sig_buf_count;
  142.    int ref_sig_buf_count;
  143.    //float *out_sig_ptr;
  144. //   float max_corr;
  145. //   float out_mag, x_temp; // out_angle;
  146. //   float max_corr_time;
  147.    int zero_size;
  148.    int samp;
  149.    double deg_per_rad = 180.0/PI;
  150.    double phase_deg;
  151.    if(Corr_Pass_Count > Num_Corr_Passes) return(_MES_AOK);
  152.    if(!(Estim_Enabled_Cntl->GetValue())) return(_MES_AOK);
  153.    //-------------------------------------------------------
  154.    //  Copy frequently accessed member vars into local vars
  155.    std::complex<float> *x = X;
  156.    std::complex<float> *y = Y;
  157.    int proc_block_size;
  158.    int in_sig_block_size;
  159.    int ref_sig_block_size;
  160.    int full_corr_size = Full_Corr_Size;
  161.    int size_of_fcomplex = Size_Of_FComplex;
  162.    int ns_exp = int(Ns_Exp);
  163. //   int smoothing_sidelobe_len = Smoothing_Sidelobe_Len;
  164.    double samp_intvl = Samp_Intvl;
  165.    double phase_to_time;
  166.    double phase_rad;
  167.    double tau, tau_sum, tau_avg;
  168.    double est_delay=-999.9;
  169.    double denom, numer;
  170.    int regression_start, regression_stop;
  171.    double phase_sum;
  172.    double phase_avg;
  173.    double idx_sum, idx_avg;
  174.    std::complex<float> x_of_f[4096];
  175.    bool phase_has_wrapped;
  176.     float amp;
  177.    //----------------------------------------
  178.    // Get pointers for input and output
  179.    in_sig_ptr = GET_INPUT_PTR(In_Sig);
  180.    ref_sig_ptr = GET_INPUT_PTR(Ref_Sig);
  181. //   out_sig_ptr = GET_OUTPUT_PTR(Out_Sig);
  182.    proc_block_size = Proc_Block_Size;
  183.    in_sig_block_size = In_Sig->GetValidBlockSize();
  184.    ref_sig_block_size = Ref_Sig->GetValidBlockSize();
  185.    //------------------------------------------------
  186.    //  Check to see if there enough samples of input
  187.    //  signal and reference signal to perform correlation
  188.    //  If not, set valid block size for output to zero
  189.    //  and then exit from this model.
  190.    in_sig_buf_ptr = In_Sig_Buf->Load(  in_sig_ptr, 
  191.                                        in_sig_block_size, 
  192.                                        &in_sig_buf_count);
  193.    ref_sig_buf_ptr = Ref_Sig_Buf->Load(ref_sig_ptr, 
  194.                                        ref_sig_block_size,
  195.                                        &ref_sig_buf_count);
  196.    if( (in_sig_buf_count < proc_block_size)
  197.       || (ref_sig_buf_count < proc_block_size))
  198.    {
  199. //      Out_Sig->SetValidBlockSize(0);
  200.       return(_MES_AOK);
  201.    }
  202.    
  203.    //----------------------------------------
  204.    zero_size = full_corr_size - proc_block_size;
  205.    phase_to_time = full_corr_size * samp_intvl/TWO_PI;
  206.    //phase_to_time = full_corr_size * samp_intvl;
  207.   // set up arrays for FFT's
  208.   // zero-pad from Proc_Block_Size to Full_Corr_Size
  209.    int i;
  210. //  memcpy( x, in_sig_ptr, proc_block_size*size_of_fcomplex);
  211.    for( i=0; i<proc_block_size; i++)
  212.    {
  213.       x[i] = std::complex<float>( *in_sig_buf_ptr++, 0.0 );
  214.    }
  215.    In_Sig_Buf->Release(proc_block_size);
  216.    for( i=proc_block_size; i<full_corr_size; i++)
  217.    {
  218.       x[i] = 0.0;
  219.    }
  220.    if(Invert_Input_Sig_Enab)
  221.    {
  222.       for( i=0; i<proc_block_size; i++)
  223.       {
  224.          x[i] = -x[i];
  225.       }
  226.    }
  227. //  memcpy( y, ref_sig_ptr, proc_block_size*size_of_fcomplex);
  228.    for( i=0; i<proc_block_size; i++)
  229.    {
  230.       y[i] = std::complex<float>( *ref_sig_buf_ptr++, 0.0 );
  231.    }
  232.    Ref_Sig_Buf->Release(proc_block_size);
  233.    for( i=proc_block_size; i<full_corr_size; i++)
  234.    {
  235.       y[i] = 0.0;
  236.    }
  237.    //memset( &x[proc_block_size], 0,
  238.    //         zero_size*sizeof(std::complex<float>));
  239.    //memcpy( &x[proc_block_size], Zero_Array,
  240.    //         zero_size*size_of_fcomplex);
  241.    //memcpy( &y[proc_block_size], Zero_Array,
  242.    //         zero_size*size_of_fcomplex);
  243.    // perform FFT's
  244.    //FFT(x, ns_exp, full_corr_size, ns_exp);
  245.    //FFT(y, ns_exp, full_corr_size, ns_exp);
  246. //   dft( x, x_of_f, full_corr_size);
  247.    FftDitNipo<float>(x, full_corr_size);
  248.    FftDitNipo<float>(y, full_corr_size);
  249. //   if(PassNumber == Num_Corr_Passes)
  250. //   {
  251. //      ofstream  *special_file = new ofstream("special.txt", ios::out);
  252. //     for(samp=0; samp < full_corr_size; samp++)
  253. //     {
  254. //        *special_file << samp << ", " << x[samp] << ", " << x_of_f[samp] << endl;
  255.         //x[samp] /= float(full_corr_size);
  256.         //x[samp] *= std::conj<float>( y[samp] ) / float(full_corr_size);
  257. //     }
  258. //     special_file->close();
  259. //   }
  260.    // perform correlation
  261.    for(samp=0; samp < full_corr_size; samp++)
  262.    {
  263.       //x[samp] /= float(full_corr_size);
  264.       x[samp] *= std::conj<float>( y[samp] ) / float(full_corr_size);
  265.    }
  266.    //----------------------------------------------------------
  267.    if( (PassNumber >= 2)
  268.       && (Corr_Pass_Count <= Num_Corr_Passes) )
  269.    {
  270.      tau_sum = 0.0;
  271.      tau_avg = 0.0;
  272.       phase_has_wrapped = false;
  273.       for(samp=0; samp < full_corr_size; samp++)
  274.       {
  275.          //phase_deg = deg_per_rad * std::arg<float>(x[samp]);
  276.          Diff_Response[samp] += x[samp];
  277.          if(Corr_Pass_Count == Num_Corr_Passes)
  278.          {
  279.             //UnwrapPhase(samp-1,&phase_deg);
  280.             amp = std::abs<float>(Diff_Response[samp]);
  281.             amp = 10.0*log10(amp);
  282.             phase_deg = deg_per_rad * std::arg<float>(Diff_Response[samp]);
  283.             if(phase_deg > 100) phase_has_wrapped = true;
  284.             if( !phase_has_wrapped) regression_stop = samp;
  285.             //phase_deg = Phase_Response[samp]/(Num_Corr_Passes-1);
  286.             phase_rad = PI * phase_deg/180.0;
  287.             tau = 0.0;
  288.             if(samp !=0)
  289.             {
  290.                tau = -phase_to_time * phase_rad/samp;
  291.             }
  292.             //if(samp > 20)
  293.             //{
  294.             //  tau_sum += tau;
  295.             //  tau_avg = tau_sum/(samp-20);
  296.             // }
  297.             (*Spectrum_File) << samp << ", " << amp << ", " 
  298.                             << phase_deg << ", "
  299.                             << tau << endl;
  300.          }
  301.       }
  302.       if(Corr_Pass_Count == Num_Corr_Passes)
  303.       {
  304.          regression_start = 5;
  305.          //regression_stop = 74;
  306.          if(regression_stop > 300) regression_stop = 300;
  307.          phase_sum = 0.0;
  308.          idx_sum = 0.0;
  309.          for(samp=regression_start; samp < regression_stop; samp++)
  310.          {
  311.             phase_rad = std::arg<float>(Diff_Response[samp]);
  312.             //phase_deg = deg_per_rad * std::arg<float>(Diff_Response[samp]);
  313.             //phase_rad = PI * phase_deg/180.0;
  314.             phase_sum += phase_rad;
  315.             idx_sum += samp;
  316.          }
  317.          numer = 0.0;
  318.          denom = 0.0;
  319.          idx_avg = idx_sum / (regression_stop - regression_start);
  320.          phase_avg = phase_sum / (regression_stop - regression_start);
  321.          for(samp=regression_start; samp < regression_stop; samp++)
  322.          {
  323.             phase_rad = std::arg<float>(Diff_Response[samp]);
  324.             numer += (samp-idx_avg)*(phase_rad - phase_avg);
  325.             denom += (samp-idx_avg)*(samp-idx_avg);
  326.          }
  327.          est_delay = -phase_to_time * numer / denom;
  328.          Spectrum_File->close();
  329.          Estimated_Delay_Cntl->SetValue(est_delay);
  330.          Dly_Est_Is_Valid_Cntl->SetValue(true);
  331.          #ifdef _DEBUG
  332.             (*DebugFile) << "phase slope found delay as " << est_delay << endl;
  333.          #endif
  334.          //exit(-9);
  335.       }
  336.       Corr_Pass_Count++;
  337.    }
  338.    //----------------------------------------------------
  339.    //InverseFFT(x, ns_exp, full_corr_size, ns_exp);
  340.    //dft( x, x_of_f, full_corr_size);
  341. //   IfftDitSino<float>(x, full_corr_size);
  342. //   if(PassNumber == Num_Corr_Passes)
  343. //   {
  344. //      ofstream  *special_file = new ofstream("special.txt", ios::out);
  345. //     for(samp=0; samp < full_corr_size; samp++)
  346. //     {
  347. //        *special_file << samp << ", " << x[samp] << ", " << x_of_f[samp] << endl;
  348.         //x[samp] /= float(full_corr_size);
  349.         //x[samp] *= std::conj<float>( y[samp] ) / float(full_corr_size);
  350. //     }
  351. //     special_file->close();
  352. //   }
  353.    // fill the output buffer
  354.    //memcpy( out_sig_ptr, x, proc_block_size*size_of_fcomplex);
  355. //   for(int ii=0; ii<proc_block_size; ii++)
  356. //   {
  357. //      out_sig_ptr[ii] = x[ii].real();
  358. //   }
  359.    // Determine maximum correlation plus corresponding time
  360. //   out_mag = 0.0;
  361. //   for(samp=Neg_Window_Beg; samp <= Neg_Window_End; samp++)
  362. //   {
  363.       //x_temp = real(x[samp]*conj<float>(x[samp]));
  364. //      x_temp = x[samp].real();
  365. //      (*DebugFile) << samp << ", " << x_temp << endl;
  366. //      if( x_temp > out_mag)
  367. //      {
  368. //         out_mag = x_temp;
  369. //         max_corr = x[samp].real();
  370. //         max_samp = samp;
  371. //      }
  372. //   }
  373. //   for(samp=Pos_Window_Beg; samp <= Pos_Window_End; samp++)
  374. //   {
  375.       //x_temp = real(x[samp]*conj<float>(x[samp]));
  376. //      x_temp = x[samp].real();
  377. //      (*DebugFile) << samp << ", " << x_temp << endl;
  378. //      if( x_temp > out_mag)
  379. //      {
  380. //         out_mag = x_temp;
  381. //         max_corr = x[samp].real();
  382. //         max_samp = samp;
  383. //      }
  384. //   }
  385. //   (*DebugFile) << "max_samp = " << max_samp << endl;
  386. //   if( max_samp > proc_block_size ) max_samp -= full_corr_size;
  387. //   max_corr_time = max_samp*samp_intvl;
  388. //  if( (fabs(max_corr) < 1.0e-30) )
  389. //      {
  390. //      max_corr = 1.0;
  391. //      }
  392.    //---------------------
  393.    return(_MES_AOK);
  394. }