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

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = qpskoptbitdem.cpp
  3. //
  4. #include <stdlib.h>
  5. //#include <fstream>
  6. #include "parmfile.h"
  7. #include "qpskoptbitdem.h"
  8. #include "misdefs.h"
  9. #include "model_graph.h"
  10. extern ParmFile *ParmInput;
  11. extern int PassNumber;
  12. #ifdef _DEBUG
  13.   extern ofstream *DebugFile;
  14. #endif
  15. //======================================================
  16. QpskOptimalBitDemod::QpskOptimalBitDemod( char* instance_name,
  17.                                   PracSimModel* outer_model,
  18.                                   Signal< std::complex< float > >* in_sig,
  19.                                   Signal< std::complex< float > >* carrier_ref_sig,
  20.                                   Signal< bit_t >* symb_clock_in,
  21.                                   Signal< bit_t >* i_decis_out,
  22.                                   Signal< bit_t >* q_decis_out )
  23.                 :PracSimModel(instance_name,
  24.                               outer_model)
  25. {
  26.   MODEL_NAME(QpskOptimalBitDemod);
  27.   ENABLE_MULTIRATE;
  28.   //-----------------------------------------
  29.   //  Read model config parms
  30.   OPEN_PARM_BLOCK;
  31.   GET_INT_PARM(Samps_Per_Symb);
  32.   GET_BOOL_PARM(Constel_Offset_Enabled);
  33.   //--------------------------------------
  34.   //  Connect input and output signals
  35.   I_Decis_Out = i_decis_out;
  36.   Q_Decis_Out = q_decis_out;
  37.   Symb_Clock_In = symb_clock_in;
  38.   Carrier_Ref_Sig = carrier_ref_sig;
  39.   In_Sig = in_sig;
  40.   MAKE_OUTPUT( I_Decis_Out );
  41.   MAKE_OUTPUT( Q_Decis_Out );
  42.   MAKE_INPUT( Symb_Clock_In );
  43.   MAKE_INPUT( Carrier_Ref_Sig );
  44.   MAKE_INPUT( In_Sig );
  45.   double resamp_rate = 1.0/double(Samps_Per_Symb);
  46.   CHANGE_RATE( In_Sig, I_Decis_Out, resamp_rate );
  47.   CHANGE_RATE( In_Sig, Q_Decis_Out, resamp_rate );
  48.   CHANGE_RATE( Carrier_Ref_Sig, I_Decis_Out, resamp_rate );
  49.   CHANGE_RATE( Carrier_Ref_Sig, Q_Decis_Out, resamp_rate );
  50.   CHANGE_RATE( Symb_Clock_In, I_Decis_Out, resamp_rate );
  51. }
  52. //==============================================
  53. QpskOptimalBitDemod::~QpskOptimalBitDemod( void ){ };
  54. //==============================================
  55. void QpskOptimalBitDemod::Initialize(void)
  56. {
  57.   Block_Size = In_Sig->GetBlockSize();
  58.   Out_Samp_Intvl = I_Decis_Out->GetSampIntvl();
  59.   Integ_Val = new double[4];
  60.   for( int isymb=0; isymb<4; isymb++)
  61.     {
  62.     Integ_Val[isymb] = 0.0;
  63.     }
  64.   if(Constel_Offset_Enabled)
  65.     {
  66.     Constel_Offset_Rot = std::complex<float>(sqrt(2.0)/2.0, sqrt(2.0)/2.0);
  67.     }
  68.   else
  69.     {
  70.     Constel_Offset_Rot = std::complex<float>(1.0, 0.0);
  71.     }
  72. }
  73. //============================================
  74. int QpskOptimalBitDemod::Execute()
  75. {
  76.   bit_t *i_decis_out_ptr;
  77.   bit_t *q_decis_out_ptr;
  78.   std::complex<float> *in_sig_ptr;
  79.   bit_t *symb_clock_in_ptr;
  80.   std::complex<float> in_val;
  81.   std::complex<float> constel_offset_rot;
  82.   std::complex<float> correl_ref;
  83.   std::complex<float> *carrier_ref_sig_ptr;
  84.   std::complex<float> carrier_val;
  85.   float correl_val;
  86.   double *integ_val;
  87.   double max_val=0.0;
  88.   int is;
  89.   byte_t isymb, symb_decis;
  90.   #ifdef _DEBUG
  91.     *DebugFile << "In QpskOptimalBitDemod::Execute" << endl;
  92.   #endif
  93.   in_sig_ptr = GET_INPUT_PTR( In_Sig );
  94.   symb_clock_in_ptr = GET_INPUT_PTR( Symb_Clock_In );
  95.   carrier_ref_sig_ptr = GET_INPUT_PTR( Carrier_Ref_Sig );
  96.   i_decis_out_ptr = GET_OUTPUT_PTR( I_Decis_Out );
  97.   q_decis_out_ptr = GET_OUTPUT_PTR( Q_Decis_Out );
  98.   constel_offset_rot = Constel_Offset_Rot;
  99.   std::complex<float> cmpx_j = std::complex<float>(0.0,-1.0);
  100.   integ_val = Integ_Val;
  101.   for (is=0; is<Block_Size; is++)
  102.     {
  103.     in_val = *in_sig_ptr++;
  104.     carrier_val = *carrier_ref_sig_ptr++;
  105.     correl_ref = std::conj(constel_offset_rot * carrier_val);
  106.     // correlate against s0
  107.     correl_val = std::real(in_val * correl_ref);
  108.     integ_val[0] += correl_val;
  109.     // correlate against s2
  110.     integ_val[2] -= correl_val;
  111.     // correlate against s1
  112.     correl_ref *= cmpx_j;
  113.     correl_val = std::real(in_val * correl_ref);
  114.     integ_val[1] += correl_val;
  115.     // correlate against s3
  116.     integ_val[3] -= correl_val;
  117.     if(*symb_clock_in_ptr != 0)
  118.       {
  119.       // time to make a decision
  120.       max_val = Integ_Val[0];
  121.       symb_decis = 0;
  122.       for(isymb=1; isymb<4; isymb++)
  123.         {
  124.         if(integ_val[isymb] > max_val)
  125.           {
  126.           max_val = integ_val[isymb];
  127.           symb_decis = isymb;
  128.           }
  129.         }
  130.       switch (symb_decis)
  131.         {
  132.         case 0:
  133.           *i_decis_out_ptr++ = 1;
  134.           *q_decis_out_ptr++ = 1;
  135.           break;
  136.         case 1:
  137.           *i_decis_out_ptr++ = 0;
  138.           *q_decis_out_ptr++ = 1;
  139.           break;
  140.         case 2:
  141.           *i_decis_out_ptr++ = 0;
  142.           *q_decis_out_ptr++ = 0;
  143.           break;
  144.         case 3:
  145.           *i_decis_out_ptr++ = 1;
  146.           *q_decis_out_ptr++ = 0;
  147.           break;
  148.         }
  149.       for(isymb=0; isymb<4; isymb++)
  150.         {
  151.         integ_val[isymb] = 0.0;
  152.         }
  153.       }
  154.     symb_clock_in_ptr++;
  155.     }
  156.   return(_MES_AOK);
  157. }