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

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = mpskoptimdem.cpp
  3. //
  4. #include <stdlib.h>
  5. #include "parmfile.h"
  6. #include "mpskoptimdem.h"
  7. #include "misdefs.h"
  8. #include "model_graph.h"
  9. extern ParmFile *ParmInput;
  10. extern int PassNumber;
  11. #ifdef _DEBUG
  12.   extern ofstream *DebugFile;
  13. #endif
  14. using namespace std;
  15. //======================================================
  16. MpskOptimalDemod::MpskOptimalDemod( 
  17.                      char* instance_name,
  18.                      PracSimModel* outer_model,
  19.                      Signal< complex< float > >* in_sig,
  20.                      Signal< bit_t >* symb_clock_in,
  21.                      Signal< byte_t >* out_sig )
  22.                 :PracSimModel(instance_name,
  23.                               outer_model)
  24. {
  25.    MODEL_NAME(MpskOptimalDemod);
  26.    ENABLE_MULTIRATE;
  27.    //  Read model config parms
  28.    OPEN_PARM_BLOCK;
  29.    GET_INT_PARM(Bits_Per_Symb);
  30.    GET_INT_PARM(Samps_Per_Symb);
  31.    //  Connect input and output signals
  32.    Out_Sig = out_sig;
  33.    Symb_Clock_In = symb_clock_in;
  34.    In_Sig = in_sig;
  35.    MAKE_OUTPUT( Out_Sig );
  36.    MAKE_INPUT( Symb_Clock_In );
  37.    MAKE_INPUT( In_Sig );
  38.    double resamp_rate = 1.0/double(Samps_Per_Symb);
  39.    CHANGE_RATE( In_Sig, Out_Sig, resamp_rate );
  40.    CHANGE_RATE( Symb_Clock_In, Out_Sig, resamp_rate );
  41.    Num_Diff_Symbs = 1;
  42.    for(int i=1; i<=Bits_Per_Symb; i++)
  43.       Num_Diff_Symbs *=2;
  44. }
  45. //======================================================
  46. MpskOptimalDemod::~MpskOptimalDemod( void ){ };
  47. //======================================================
  48. void MpskOptimalDemod::Initialize(void)
  49. {
  50.   Block_Size = In_Sig->GetBlockSize();
  51.   Out_Samp_Intvl = Out_Sig->GetSampIntvl();
  52.   //
  53.   //  set up table of phase references
  54.   Conj_Ref = new std::complex<float>[Num_Diff_Symbs];
  55.   Integ_Val = new double[Num_Diff_Symbs];
  56.   for( byte_t isymb=0; isymb<Num_Diff_Symbs; isymb++){
  57.     Integ_Val[isymb] = 0.0;
  58.     Conj_Ref[isymb] = std::complex<float>( 
  59.        float(cos(TWO_PI * 
  60.        isymb/double(Num_Diff_Symbs))),
  61.        -float(sin(TWO_PI * 
  62.        isymb/double(Num_Diff_Symbs))));
  63.     }
  64. }
  65. //======================================================
  66. int MpskOptimalDemod::Execute()
  67. {
  68.    byte_t *out_sig_ptr;
  69.    std::complex<float> *in_sig_ptr;
  70.    bit_t *symb_clock_in_ptr;
  71.    std::complex<float> in_val;
  72.    double *integ_val;
  73.    double max_val=0.0;
  74.    int is;
  75.    int block_size;
  76.    byte_t isymb, symb_decis;
  77. #ifdef _DEBUG
  78.    *DebugFile << "In MpskOptimalDemod::Execute" 
  79.               << endl;
  80. #endif
  81.    in_sig_ptr = GET_INPUT_PTR( In_Sig );
  82.    symb_clock_in_ptr = GET_INPUT_PTR( Symb_Clock_In );
  83.    out_sig_ptr = GET_OUTPUT_PTR( Out_Sig );
  84.    block_size = In_Sig->GetValidBlockSize();
  85.    Out_Sig->SetValidBlockSize(block_size/
  86.                               Samps_Per_Symb);
  87.    integ_val = Integ_Val;
  88.    for (is=0; is<block_size; is++){
  89.       in_val = *in_sig_ptr++;
  90.       // correlate input signal against all possible
  91.       // reference phases
  92.       for( isymb=0; isymb<Num_Diff_Symbs; isymb++){
  93.          Integ_Val[isymb] += std::real(in_val * 
  94.                               Conj_Ref[isymb]);
  95.       }
  96.       if(*symb_clock_in_ptr != 0){
  97.          // time to make a decision
  98.          max_val = Integ_Val[0];
  99.          symb_decis = 0;
  100.          for(isymb=1; isymb<Num_Diff_Symbs; isymb++){
  101.             if(Integ_Val[isymb] > max_val){
  102.                max_val = Integ_Val[isymb];
  103.                symb_decis = isymb;
  104.             }
  105.          }
  106.          *out_sig_ptr = symb_decis;
  107.          out_sig_ptr++;
  108.          for(isymb=0; isymb<Num_Diff_Symbs; isymb++){
  109.             Integ_Val[isymb] = 0.0;
  110.          }
  111.       }
  112.       symb_clock_in_ptr++;
  113.    }
  114.    return(_MES_AOK);
  115. }