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

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = add_gaus_noise.cpp
  3. //
  4. #include <stdlib.h>
  5. #include <fstream>
  6. #include <math.h>
  7. #include "parmfile.h"
  8. #include "add_gaus_noise.h"
  9. #include "syst_graph.h"
  10. #include "misdefs.h"
  11. #include "gensig.h"
  12. #include "butt_filt_iir.h"
  13. #include "gausrand.h"
  14. extern int PassNumber;
  15. extern ParmFile *ParmInput;
  16. extern SystemGraph CommSystemGraph;
  17. #ifdef _DEBUG
  18.   extern ofstream *DebugFile;
  19. #endif
  20. //======================================================
  21. // normal constructor
  22. template <class T>
  23. AdditiveGaussianNoise<T>
  24.          ::AdditiveGaussianNoise( 
  25.                           char* instance_name,
  26.                           PracSimModel* outer_model,
  27.                           Signal<T>* in_sig,
  28.                           Signal<T>* noisy_sig,
  29.                           Signal<float>* power_meas_sig)
  30.                  :PracSimModel(  instance_name,
  31.                                  outer_model)
  32. {
  33.    MODEL_NAME(AdditiveGaussianNoise);
  34.    char sub_name[60];
  35.    In_Sig = in_sig;
  36.    Noisy_Sig = noisy_sig;
  37.    Power_Meas_Sig = power_meas_sig;
  38.    OPEN_PARM_BLOCK;
  39.    GET_FLOAT_PARM(Anticip_Input_Pwr);
  40.    GET_FLOAT_PARM(Desired_Output_Pwr);
  41.    GET_FLOAT_PARM(Desired_Eb_No);
  42.    GET_FLOAT_PARM(Symb_Period);
  43.    GET_FLOAT_PARM(Num_Bits_Per_Symb);
  44.    GET_FLOAT_PARM(Time_Const_For_Pwr_Mtr);
  45.    GET_INT_PARM(Seed);
  46.    GET_BOOL_PARM(Sig_Pwr_Meas_Enabled);
  47.    GET_BOOL_PARM(Outpt_Pwr_Scaling_On);
  48.    strcpy(sub_name,GetModelName());
  49.    strcat(sub_name, ":k_PowerMeter");
  50.    Power_Meter = 
  51.       new k_PowerMeter<T>( sub_name,
  52.                            Anticip_Input_Pwr,
  53.                            Time_Const_For_Pwr_Mtr);
  54.    MAKE_INPUT(In_Sig);
  55.    MAKE_OUTPUT(Noisy_Sig);
  56.    MAKE_OUTPUT(Power_Meas_Sig);
  57.    Noise_Only_Sig = NULL;
  58. }
  59. //======================================================
  60. // constructor that connects a noise-only output signal
  61. template <class T>
  62. AdditiveGaussianNoise<T>::AdditiveGaussianNoise( 
  63.                           char* instance_name,
  64.                           PracSimModel* outer_model,
  65.                           Signal<T>* in_sig,
  66.                           Signal<T>* noisy_sig,
  67.                           Signal<T>* noise_only_sig,
  68.                           Signal<float>* power_meas_sig)
  69.                       :PracSimModel(instance_name,
  70.                                     outer_model)
  71. {
  72.    MODEL_NAME(AdditiveGaussianNoise);
  73.    char sub_name[60];
  74.    In_Sig = in_sig;
  75.    Noisy_Sig = noisy_sig;
  76.    Power_Meas_Sig = power_meas_sig;
  77.    Noise_Only_Sig = noise_only_sig;
  78.    OPEN_PARM_BLOCK;
  79.    GET_FLOAT_PARM(Anticip_Input_Pwr);
  80.    GET_FLOAT_PARM(Desired_Output_Pwr);
  81.    GET_FLOAT_PARM(Desired_Eb_No);
  82.    GET_FLOAT_PARM(Symb_Period);
  83.    GET_FLOAT_PARM(Num_Bits_Per_Symb);
  84.    GET_FLOAT_PARM(Time_Const_For_Pwr_Mtr);
  85.    GET_INT_PARM(Seed);
  86.    GET_BOOL_PARM(Sig_Pwr_Meas_Enabled);
  87.    GET_BOOL_PARM(Outpt_Pwr_Scaling_On);
  88.    strcpy(sub_name,GetModelName());
  89.    strcat(sub_name, ":k_PowerMeter");
  90.    Power_Meter = new k_PowerMeter<T>(  
  91.                            sub_name,
  92.                            Anticip_Input_Pwr,
  93.                            Time_Const_For_Pwr_Mtr);
  94.    MAKE_INPUT(In_Sig);
  95.    MAKE_OUTPUT(Noisy_Sig);
  96.    MAKE_OUTPUT(Power_Meas_Sig);
  97.    MAKE_OUTPUT(Noise_Only_Sig);
  98. }
  99. //=======================================================
  100. // destructor
  101. template <class T>
  102. AdditiveGaussianNoise<T>::~AdditiveGaussianNoise( void )
  103. {
  104.     delete Power_Meter;
  105. };
  106. //======================================================
  107. template < class T>
  108. void AdditiveGaussianNoise<T>::Initialize(void)
  109. {
  110.    double bit_weight, ebno_scaled;
  111.    *DebugFile 
  112.       << "Now in AdditiveGaussianNoise::Initialize()" 
  113.       << endl;
  114.    Proc_Block_Size = In_Sig->GetBlockSize();
  115.    ebno_scaled = double( pow(10.0,(Desired_Eb_No/10.))*
  116.       (In_Sig->GetSampIntvl()) );
  117.    bit_weight = Symb_Period / Num_Bits_Per_Symb;
  118.    Noise_Sigma = float(sqrt( (Anticip_Input_Pwr * 
  119.                      bit_weight) / ebno_scaled / 2.0 ));
  120.    Power_Scaler = float(bit_weight / ebno_scaled);
  121.    Sum = 0.0;
  122.    Sum_Sqrd = 0.0;
  123.    Num_Samps = 0;
  124.    Cumul_Batch_Power = 0.0;
  125.    Power_Meter->Initialize( Proc_Block_Size, 
  126.                             In_Sig->GetSampIntvl());
  127. }
  128. //======================================================
  129. template <class T>
  130. int AdditiveGaussianNoise<T>::Execute(void)
  131. {
  132.    int is;
  133.    T *in_sig, *noisy_sig;
  134.    T *noise_only_sig;
  135.    float *sig_pwr_sig, sig_pwr, noise_sigma;
  136.    std::complex<float> cmpx_in, cmpx_rand_var;
  137.    T rand_var;
  138.    T noisy_sig_val;
  139.    T noise_val;
  140.    float anticip_input_pwr = Anticip_Input_Pwr;
  141.    float desired_output_pwr = Desired_Output_Pwr;
  142.    float power_scaler = Power_Scaler;
  143.    long seed = Seed;
  144.    Proc_Block_Size = In_Sig->GetValidBlockSize();
  145.    Noisy_Sig->SetValidBlockSize(Proc_Block_Size);
  146.    Power_Meas_Sig->SetValidBlockSize(Proc_Block_Size);
  147.    if(Noise_Only_Sig != NULL) 
  148.      Noise_Only_Sig->SetValidBlockSize(Proc_Block_Size);
  149.    //---------------------------------------------------
  150.    // determine the power of the input signal
  151.    in_sig = GET_INPUT_PTR(In_Sig);
  152.    double sum = 0.0;
  153.    for(is=0; is<Proc_Block_Size; is++){
  154.       cmpx_in = *in_sig;
  155.       sum += std::norm(cmpx_in);
  156.       in_sig++;
  157.    }
  158.    Cumul_Batch_Power += sum/double(Proc_Block_Size);
  159.    if( (PassNumber % 10) == 0) {
  160.       BasicResults << PassNumber << " Batch power = " 
  161.          << float(sum/double(Proc_Block_Size)) 
  162.          << "  Cumul = " 
  163.          << float(Cumul_Batch_Power/double(PassNumber))
  164.          << endl;
  165.    }
  166.    in_sig = GET_OUTPUT_PTR(In_Sig);
  167.    sig_pwr_sig = GET_OUTPUT_PTR(Power_Meas_Sig);
  168.    Power_Meter->Execute(in_sig,sig_pwr_sig,
  169.                         Proc_Block_Size);
  170.    // this only needed when signal power is not measured
  171.    sig_pwr = Anticip_Input_Pwr;
  172.    noise_sigma = 
  173.       float(sqrt(sig_pwr * power_scaler / 2.0));
  174.    in_sig = GET_INPUT_PTR(In_Sig);
  175.    noisy_sig = GET_OUTPUT_PTR(Noisy_Sig);
  176.    if(Noise_Only_Sig != NULL) {
  177.       noise_only_sig = GET_OUTPUT_PTR(Noise_Only_Sig);
  178.    }
  179.    //---------------------------------------------------
  180.    //  main loop
  181.    sig_pwr_sig = GET_OUTPUT_PTR(Power_Meas_Sig);
  182.    if( (PassNumber % 50) == 0) {
  183.       BasicResults << "   Metered power = " 
  184.          << float(*(sig_pwr_sig + Proc_Block_Size - 1))
  185.          << endl;
  186.    }
  187.    for(is=0; is<Proc_Block_Size; is++){
  188.       if(Sig_Pwr_Meas_Enabled){
  189.          sig_pwr = *sig_pwr_sig++;
  190.          noise_sigma = 
  191.             float(sqrt( sig_pwr * power_scaler / 2.0 ));
  192.       }
  193.       // generate gaussian RV
  194.       GaussRandom(&seed, &rand_var);
  195.       Sum += rand_var;
  196.       cmpx_rand_var = rand_var;
  197.       Sum_Sqrd += std::norm(cmpx_rand_var);
  198.       Num_Samps ++;
  199.       // combine noise with signal
  200.       noise_val = noise_sigma * rand_var;
  201.       noisy_sig_val = *in_sig + noise_val;
  202.       in_sig++;
  203.       // if specified, apply scaling to output
  204.       if( (Outpt_Pwr_Scaling_On) && 
  205.          (desired_output_pwr > 0.0)){
  206.          noisy_sig_val *= 
  207.             float(sqrt(desired_output_pwr/sig_pwr));
  208.          noise_val *= 
  209.             float(sqrt(desired_output_pwr/sig_pwr));
  210.       }
  211.       *noisy_sig++ = noisy_sig_val;
  212.       if(Noise_Only_Sig != NULL) {
  213.          *noise_only_sig++ = noise_val;
  214.       }
  215.    }// end of main loop
  216.    // put back variables that have changed
  217.    Seed = seed;
  218.    if( PassNumber%100 == 0){
  219.       complex<double> avg = Sum / double(Num_Samps);
  220.       double var = 
  221.          (Sum_Sqrd / Num_Samps) - std::norm(avg);
  222.       BasicResults << "Pass " << PassNumber << " avg = "
  223.                    << avg << "  var = " << var << endl;
  224.       BasicResults << "noise_sigma = " << noise_sigma 
  225.                    << endl;
  226.    }
  227.    return(_MES_AOK);
  228. };
  229. template AdditiveGaussianNoise< complex<float> >;
  230. template AdditiveGaussianNoise<float>;