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

3G开发

开发平台:

Visual C++

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