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

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = clock_recov.cpp
  3. //
  4. //#include <stdlib.h>
  5. //#include <fstream.h>
  6. #include "parmfile.h"
  7. #include "misdefs.h"
  8. #include "model_error.h"
  9. #include "clock_recov.h"
  10. #include "butt_filt_iir.h"
  11. #include "model_graph.h"
  12. //#include "sinc.h"
  13. extern ParmFile *ParmInput;
  14. extern PracSimModel *ActiveModel;
  15. //======================================================
  16. ClockRecoveryLoop::ClockRecoveryLoop( char* instance_name,
  17.                         PracSimModel* outer_model,
  18.                         Signal<float>* fsig_input,
  19.                         Signal<float>* fsig_raw_error,
  20.                         Signal<float>* fsig_filtered_error,
  21.                         Signal<float>* fsig_symbol_period,
  22.                         Signal<float>* out_sig )
  23.                 :PracSimModel(instance_name,
  24.                               outer_model)
  25. {
  26.    MODEL_NAME(ClockRecoveryLoop);
  27.    //ENABLE_MULTIRATE;
  28.    //---------------------------------------
  29.    //  Read model config parms
  30.    OPEN_PARM_BLOCK;
  31.    GET_DOUBLE_PARM(K_Sub_0);
  32.    GET_DOUBLE_PARM(Center_Freq_Hz);
  33.    GET_DOUBLE_PARM(Gate_Fraction);
  34.    GET_DOUBLE_PARM(Nominal_Symbol_Period);
  35.    Min_Symbol_Period = 0.96 * Nominal_Symbol_Period;
  36.    Max_Symbol_Period = 1.04 * Nominal_Symbol_Period;
  37.    //--------------------------------------
  38.    //  Connect input and output signals
  39.    fsig_Input = fsig_input;
  40.    fsig_Filtered_Error = fsig_filtered_error;
  41.    fsig_Raw_Error = fsig_raw_error;
  42.    fsig_Symbol_Period = fsig_symbol_period;
  43.    fsig_Output = out_sig;
  44.    MAKE_OUTPUT( fsig_Output );
  45.    MAKE_OUTPUT( fsig_Filtered_Error );
  46.    MAKE_OUTPUT( fsig_Raw_Error );
  47.    MAKE_OUTPUT( fsig_Symbol_Period );
  48.    MAKE_INPUT( fsig_Input );
  49.    //SAME_RATE(fsig_Input,fsig_Filtered_Error);
  50.    //SAME_RATE(fsig_Input,fsig_Output);
  51.    //----------------------------------
  52.    //  Compute derived parameters
  53.    //Omega_Sub_0 = TWO_PI * Center_Freq_Hz;
  54.    Omega_Sub_0 = 1.0/Nominal_Symbol_Period;
  55.    //--------------------------------
  56.    // create loop filter object
  57.    char sub_name[50];
  58.    strcpy(sub_name, GetInstanceName());
  59.    strcat(sub_name, ":Filter");
  60.    Filter_Core = new ButterworthFilterByIir<float>( sub_name, this);
  61. }
  62. //======================================
  63. ClockRecoveryLoop::~ClockRecoveryLoop( void ){ };
  64. //=======================================
  65. void ClockRecoveryLoop::Initialize(void)
  66. {
  67.    //------------------
  68.    int block_size = fsig_Output->GetBlockSize();
  69.    Samp_Intvl = fsig_Input->GetSampIntvl();
  70.    Filter_Core->Initialize(block_size, Samp_Intvl);
  71.    Reduced_Time = 0.0;
  72.    Early_Gate_Open_Time = 0.0;
  73.    Late_Gate_Close_Time = 0.0;
  74.    Late_Gate_Is_Open = false;
  75.    Early_Gate_Is_Open = true;
  76.    Early_Gate_Sum = 0.0;
  77.    Adjusted_Symbol_Period = Nominal_Symbol_Period;
  78.    Gate_Diff = 0.0;
  79.    Old_Input_Val = 0.0;
  80. }
  81. //=======================================================
  82. int ClockRecoveryLoop::Execute()
  83. {
  84.    // pointers for signal data
  85.    float *fsOutput_ptr;
  86.    float *fs_filtered_error_ptr;
  87.    float *fs_raw_error_ptr;
  88.    float *fsInput_ptr;
  89.    float *fs_symbol_period_ptr;
  90.    float input_val;
  91. //   float inst_freq;
  92.    double samp_intvl;
  93.    double filt_val=0;
  94.    double err_sum=0;
  95.    int is;
  96.    int block_size;
  97.    double time;
  98.    double old_gate_diff=0;
  99.    double closing_delay;
  100.    double opening_delay;
  101.    double val_at_close;
  102.    double val_at_open;
  103.    //--------------------------------------------------------------
  104.    // set up pointers to data buffers for input and output signals
  105.    fsOutput_ptr = GET_OUTPUT_PTR( fsig_Output );
  106.    fs_filtered_error_ptr = GET_OUTPUT_PTR( fsig_Filtered_Error );
  107.    fs_raw_error_ptr = GET_OUTPUT_PTR( fsig_Raw_Error );
  108.    fs_symbol_period_ptr = GET_OUTPUT_PTR( fsig_Symbol_Period );
  109.    fsInput_ptr = GET_INPUT_PTR( fsig_Input );
  110.    //---------------------------------------------------------------
  111.    samp_intvl = Samp_Intvl;
  112.    block_size = fsig_Input->GetValidBlockSize();
  113.    fsig_Output->SetValidBlockSize(block_size);
  114.    fsig_Filtered_Error->SetValidBlockSize(block_size);
  115.    fsig_Raw_Error->SetValidBlockSize(block_size);
  116.    fsig_Symbol_Period->SetValidBlockSize(block_size);
  117.    //--------------------------------------------------------------
  118.    if(Reduced_Time > block_size * samp_intvl)
  119.    {
  120.       // reduce all the times by one pass duration
  121.       Reduced_Time -= block_size * samp_intvl;
  122.       Early_Gate_Open_Time -= block_size * samp_intvl;
  123.       Early_Gate_Close_Time -= block_size * samp_intvl;
  124.       Late_Gate_Open_Time -= block_size * samp_intvl;
  125.       Late_Gate_Close_Time -= block_size * samp_intvl;
  126.    }
  127.    //-------------------------------------------------------
  128.    for (is=0; is<block_size; is++)
  129.    {
  130.       time = Reduced_Time + is * samp_intvl;
  131.       //*fsOscOutput_ptr++ = osc_output_val;
  132.       input_val = *fsInput_ptr;
  133.       if(is == 3100)
  134.       {
  135.          err_sum = 1;
  136.       }
  137.       //---------------------------------------------------
  138.       // Late gate
  139.       if(Late_Gate_Is_Open)
  140.       {
  141.          //late gate was open prior to current sample time
  142.          if(time >= Late_Gate_Open_Time + Gate_Fraction * Adjusted_Symbol_Period)
  143.          {
  144.             // gate should be closed
  145.             Late_Gate_Close_Time = Late_Gate_Open_Time + Gate_Fraction * Adjusted_Symbol_Period;
  146.             Late_Gate_Is_Open = false;
  147.             closing_delay = time - Late_Gate_Close_Time;
  148.             val_at_close = input_val + closing_delay * (Old_Input_Val - input_val);
  149.             Late_Gate_Latched_Sum = Late_Gate_Sum + (1.0 - closing_delay) * (val_at_close + Old_Input_Val)/2.0;
  150.             Late_Gate_Sum = 0.0;
  151.            // Gate_Diff = fabs(Early_Gate_Latched_Sum) - fabs(Late_Gate_Latched_Sum);
  152.             Gate_Diff = fabs(Late_Gate_Latched_Sum) - fabs(Early_Gate_Latched_Sum);
  153.       if(Gate_Diff != old_gate_diff)
  154.       {
  155.          old_gate_diff = Gate_Diff;
  156.       }
  157.       filt_val = Filter_Core->ProcessSample(Gate_Diff);
  158.       Adjusted_Symbol_Period = Nominal_Symbol_Period - K_Sub_0 * filt_val;
  159. //      if(Adjusted_Symbol_Period < Min_Symbol_Period) Adjusted_Symbol_Period = Min_Symbol_Period;
  160. //      if(Adjusted_Symbol_Period > Max_Symbol_Period) Adjusted_Symbol_Period = Max_Symbol_Period;
  161.          }
  162.          else
  163.          {
  164.             // late gate remains open
  165.             Late_Gate_Sum += input_val;
  166.             Gate_Diff = 0.0;
  167.          }
  168.       }
  169.       else
  170.       {
  171.          // late gate was closed prior to current sample time
  172.          if(time >= Late_Gate_Close_Time + (1.0 - Gate_Fraction) * Adjusted_Symbol_Period)
  173.          {
  174.             // gate should be opened
  175.             Late_Gate_Open_Time = Late_Gate_Close_Time + (1.0 - Gate_Fraction) * Adjusted_Symbol_Period;
  176.             Late_Gate_Is_Open = true;
  177.             opening_delay = time - Late_Gate_Open_Time;
  178.             val_at_open = input_val + closing_delay * (Old_Input_Val - input_val);
  179.             Late_Gate_Sum = opening_delay * (val_at_open + input_val)/2.0;
  180.             //Late_Gate_Sum = input_val;
  181.          }
  182.          Gate_Diff = 0.0;
  183.       }
  184.       //---------------------------------------------------
  185.       // Early gate
  186.       if(Early_Gate_Is_Open)
  187.       {
  188.          //early gate was open prior to current sample time
  189.          if(time >= Early_Gate_Open_Time + Gate_Fraction * Adjusted_Symbol_Period)
  190.          {
  191.             // gate should be closed
  192.             Early_Gate_Close_Time = Early_Gate_Open_Time + Gate_Fraction * Adjusted_Symbol_Period;
  193.             Early_Gate_Is_Open = false;
  194.             closing_delay = time - Early_Gate_Close_Time;
  195.             val_at_close = input_val + closing_delay * (Old_Input_Val - input_val);
  196.             Early_Gate_Latched_Sum = Early_Gate_Sum + (1.0 - closing_delay) * (val_at_close + Old_Input_Val)/2.0;
  197.             Early_Gate_Sum = 0.0;
  198.          }
  199.          else
  200.          {
  201.             // early gate remains open
  202.             Early_Gate_Sum += input_val;
  203.          }
  204.       }
  205.       else
  206.       {
  207.          // early gate was closed prior to current sample time
  208.          if(time >= Early_Gate_Close_Time + (1.0 - Gate_Fraction) * Adjusted_Symbol_Period)
  209.          {
  210.             // gate should be opened
  211.             Early_Gate_Open_Time = Early_Gate_Close_Time + (1.0 - Gate_Fraction) * Adjusted_Symbol_Period;
  212.             Early_Gate_Is_Open = true;
  213.             opening_delay = time - Early_Gate_Open_Time;
  214.             val_at_open = input_val + closing_delay * (Old_Input_Val - input_val);
  215.             Early_Gate_Sum = opening_delay * (val_at_open + input_val)/2.0;
  216.             //Early_Gate_Sum = input_val;
  217.          }
  218.       }
  219.       Old_Input_Val = input_val;
  220.       //-------------------------------------
  221.       //  filter the gate difference signal
  222. //      if(Gate_Diff != old_gate_diff)
  223. //      {
  224. //         old_gate_diff = Gate_Diff;
  225. //      }
  226. //      filt_val = Filter_Core->ProcessSample(Gate_Diff);
  227.       *fs_filtered_error_ptr++ = filt_val;
  228.       *fs_raw_error_ptr++ = Gate_Diff;
  229.       //----------------------------------------
  230.       // use filtered error signal to drive VCO
  231.       //inst_freq = Omega_Sub_0 + K_Sub_0 * filt_val;
  232.       //Adjusted_Symbol_Period = 1.0/inst_freq;
  233.       //Adjusted_Symbol_Period -= K_Sub_0 * filt_val;
  234.       *fs_symbol_period_ptr++ = Adjusted_Symbol_Period;
  235.       if(Early_Gate_Is_Open)
  236.       {
  237.          *fsOutput_ptr++ = 1.0;
  238.       }
  239.       else
  240.       {
  241.          *fsOutput_ptr++ = 0.0;
  242.       }
  243.       fsInput_ptr++;
  244.    }
  245.    Reduced_Time += block_size * samp_intvl;
  246.   return(_MES_AOK);
  247. }