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

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = qamoptdem_bp.cpp
  3. //
  4. #include <stdlib.h>
  5. #include <fstream.h>
  6. #include "parmfile.h"
  7. #include "qamoptdem_bp.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. QamOptimalBandpassDemod::QamOptimalBandpassDemod( char* instance_name,
  17.                                   PracSimModel* outer_model,
  18.                                   Signal< float >* in_sig,
  19.                                   Signal< bit_t >* symb_clock_in,
  20.                                   Signal< byte_t >* out_sig )
  21.                 :PracSimModel(instance_name,
  22.                               outer_model)
  23. {
  24.   MODEL_NAME(QamOptimalBandpassDemod);
  25.   ENABLE_MULTIRATE;
  26.   //-----------------------------------------
  27.   //  Read model config parms
  28.   OPEN_PARM_BLOCK;
  29.   GET_DOUBLE_PARM(Phase_Unbal);
  30.   GET_DOUBLE_PARM(Carrier_Freq);
  31.   GET_INT_PARM(Bits_Per_Symb);
  32.   GET_INT_PARM(Samps_Per_Symb);
  33.   GET_DOUBLE_PARM(Dly_To_Start);
  34.   Carrier_Freq_Rad = TWO_PI * Carrier_Freq;
  35.   //int block_size = ParmInput.GetIntParm("block_size");
  36.   //double samp_intvl = ParmInput.GetDoubleParm("samp_intvl");
  37.   //--------------------------------------
  38.   //  Connect input and output signals
  39.   Out_Sig = out_sig;
  40.   Symb_Clock_In = symb_clock_in;
  41.   In_Sig = in_sig;
  42.   MAKE_OUTPUT( Out_Sig );
  43.   MAKE_INPUT( Symb_Clock_In );
  44.   MAKE_INPUT( In_Sig );
  45.   double resamp_rate = 1.0/double(Samps_Per_Symb);
  46.   CHANGE_RATE( In_Sig, Out_Sig, resamp_rate );
  47.   CHANGE_RATE( Symb_Clock_In, Out_Sig, resamp_rate );
  48.   //------------------
  49.   //  compute decision boundaries
  50.   Num_Diff_Symbs = 1;
  51.   for(int i=1; i<=Bits_Per_Symb; i++)
  52.     Num_Diff_Symbs *=2;
  53.   double offset = TWO_PI/(2.0*Num_Diff_Symbs);
  54.   Decis_Bound = new float[Num_Diff_Symbs];
  55.   for(int isymb=0; isymb<Num_Diff_Symbs; isymb++)
  56.     {
  57.     Decis_Bound[isymb] = float(offset + isymb*TWO_PI/double(Num_Diff_Symbs));
  58.     }
  59. }
  60. //==============================================
  61. QamOptimalBandpassDemod::~QamOptimalBandpassDemod( void ){ };
  62. //==============================================
  63. void QamOptimalBandpassDemod::Initialize(void)
  64. {
  65.   Block_Size = In_Sig->GetBlockSize();
  66. //  Out_Samp_Intvl = Out_Sig->GetSampIntvl();
  67.   //
  68.   //  set up table of phase references
  69.   Ref_Angle = new float[Num_Diff_Symbs];
  70.   Integ_Val = new double[Num_Diff_Symbs];
  71.   for( int isymb=0; isymb<Num_Diff_Symbs; isymb++)
  72.     {
  73.     Integ_Val[isymb] = 0.0;
  74.     Ref_Angle[isymb] = TWO_PI * isymb/double(Num_Diff_Symbs);
  75.     }
  76.   Time = 0.0;
  77.   Samp_Intvl = In_Sig->GetSampIntvl();
  78. }
  79. //============================================
  80. int QamOptimalBandpassDemod::Execute()
  81. {
  82.   byte_t *out_sig_ptr;
  83.   float *in_sig_ptr;
  84.   bit_t *symb_clock_in_ptr;
  85.   float in_val;
  86.   double *integ_val;
  87.   double max_val=0.0;
  88.   double omega, time, time_base;
  89.   double samp_intvl;
  90.   int is;
  91.   byte_t isymb, symb_decis;
  92.   #ifdef _DEBUG
  93.     *DebugFile << "In QamOptimalBandpassDemod::Execute" << endl;
  94.   #endif
  95.   in_sig_ptr = GET_INPUT_PTR( In_Sig );
  96.   symb_clock_in_ptr = GET_INPUT_PTR( Symb_Clock_In );
  97.   out_sig_ptr = GET_OUTPUT_PTR( Out_Sig );
  98.   omega = Carrier_Freq_Rad;
  99.   time_base = Time;
  100.   samp_intvl = Samp_Intvl;
  101.   integ_val = Integ_Val;
  102.   for (is=0; is<Block_Size; is++)
  103.     {
  104.     in_val = *in_sig_ptr++;
  105.     time = time_base + is * samp_intvl;
  106.     // correlate input signal against all possible reference phases
  107.     for( isymb=0; isymb<Num_Diff_Symbs; isymb++)
  108.       {
  109.       Integ_Val[isymb] += in_val * cos(omega*time + Ref_Angle[isymb]);
  110.       }
  111.     if(*symb_clock_in_ptr != 0)
  112.       {
  113.       // time to make a decision
  114.       max_val = Integ_Val[0];
  115.       symb_decis = 0;
  116.       for(isymb=1; isymb<Num_Diff_Symbs; isymb++)
  117.         {
  118.         if(Integ_Val[isymb] > max_val)
  119.           {
  120.           max_val = Integ_Val[isymb];
  121.           symb_decis = isymb;
  122.           }
  123.         }
  124.       *out_sig_ptr = symb_decis;
  125.       out_sig_ptr++;
  126.       for(isymb=0; isymb<Num_Diff_Symbs; isymb++)
  127.         {
  128.         Integ_Val[isymb] = 0.0;
  129.         }
  130.       }
  131.     symb_clock_in_ptr++;
  132.     }
  133.   Time = time_base + samp_intvl * Block_Size;
  134.   //Integ_Val = integ_val;
  135.   return(_MES_AOK);
  136. }