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

3G开发

开发平台:

Visual C++

  1. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. //
  3. //  File = anlg_filt_iir.cpp
  4. //
  5. //  The class AnalogFilterByInteg serves as the base class
  6. //  for all the "traditional" analog filter types
  7. //  e.g. Butterworth, Chebyshev, etc. that are modeled 
  8. //  using an IIR filter
  9. //
  10. #include <math.h>
  11. #include "misdefs.h"
  12. #include "parmfile.h"
  13. #include "model_graph.h"
  14. #include "anlg_filt_iir.h"
  15. #include "bilin_transf.h"
  16. #include "iir_comp_resp.h"
  17. extern ParmFile *ParmInput;
  18. extern ofstream *DebugFile;
  19. using std::complex;
  20. //======================================================
  21. //  constructor
  22. template <class T>
  23. AnalogFilterByIir<T>::
  24.          AnalogFilterByIir(  char *instance_name,
  25.                              PracSimModel *outer_model,
  26.                              Signal<T> *in_sig,
  27.                              Signal<T> *out_sig )
  28.                     :PracSimModel(  instance_name,
  29.                                     outer_model )
  30. {
  31.    MODEL_NAME(AnalogFilterByIir);
  32.    this->Constructor_Core(instance_name);
  33.    In_Sig = in_sig;
  34.    Out_Sig = out_sig;
  35.    MAKE_INPUT(In_Sig);
  36.    MAKE_OUTPUT(Out_Sig);
  37.    In_Sig->SetAllocMemDepth( Filt_Order );
  38.    Using_Signal_Objects = true;
  39.    return;
  40. }
  41. //======================================================
  42. template <class T>
  43. AnalogFilterByIir<T>::
  44.          AnalogFilterByIir(  char *instance_name,
  45.                              PracSimModel *outer_model )
  46.                     :PracSimModel(  instance_name,
  47.                                     outer_model )
  48. {
  49.    MODEL_NAME(AnalogFilterByIir);
  50.    this->Constructor_Core(instance_name);
  51.    Using_Signal_Objects = false;
  52.    return;
  53. }
  54. //======================================================
  55. // destructor
  56. template <class T>
  57. AnalogFilterByIir<T>::~AnalogFilterByIir()
  58. {
  59.    delete Denorm_Proto_Filt;
  60. };
  61. //======================================================
  62. template <class T>
  63. void AnalogFilterByIir<T>::
  64.          Constructor_Core( char *instance_name)
  65. {
  66.    OPEN_PARM_BLOCK;
  67.    Denorm_Proto_Filt = NULL;
  68.    Lowpass_Proto_Filt = NULL;
  69.    A_Coef_Precess_Buf = NULL;
  70.    B_Coef_Precess_Buf = NULL;
  71.    In_Mem = NULL;
  72.    Out_Mem = NULL;
  73.    Filt_Order = 0;
  74.    Estim_Delay = 0;
  75.    GET_BOOL_PARM(Bypass_Enabled);
  76.    if(Bypass_Enabled){
  77.       Filt_Band_Config = LOWPASS_FILT_BAND_CONFIG;
  78.       Filt_Order = 0;
  79.       Norm_Hz_Pass_Edge = 0.0;
  80.       Norm_Hz_Pass_Edge_2 = 0.0;
  81.       Lowpass_Proto_Filt = NULL;
  82.       Denorm_Proto_Filt = NULL;
  83.    }
  84.    else{
  85.       GET_INT_PARM(Filt_Order);
  86.       Filt_Band_Config = 
  87.          GetFiltBandConfigParm("Filt_Band_Config");
  88.       switch (Filt_Band_Config){
  89.       case BANDPASS_FILT_BAND_CONFIG:
  90.       case BANDSTOP_FILT_BAND_CONFIG:
  91.          GET_DOUBLE_PARM(Norm_Hz_Pass_Edge);
  92.          GET_DOUBLE_PARM(Norm_Hz_Pass_Edge_2);
  93.          if( Norm_Hz_Pass_Edge >= Norm_Hz_Pass_Edge_2){
  94.             // error
  95.          }
  96.          if( Filt_Order % 2 != 0 ){
  97.             // another error
  98.          }
  99.          Prototype_Order = Filt_Order/2;
  100.          break;
  101.       case LOWPASS_FILT_BAND_CONFIG:
  102.       case HIGHPASS_FILT_BAND_CONFIG:
  103.          GET_DOUBLE_PARM(Norm_Hz_Pass_Edge);
  104.          Norm_Hz_Pass_Edge_2 = 0;
  105.          Prototype_Order = Filt_Order;
  106.          break;
  107.       } // end of switch on Filter_Band_Config
  108.       GET_BOOL_PARM(Resp_Plot_Enabled);
  109.       if(Resp_Plot_Enabled){
  110.          GET_BOOL_PARM(Db_Scale_Enabled);
  111.       }
  112.    }
  113.    Cumul_Samp_Count = 0;
  114.    return;
  115. };
  116. //======================================================
  117. template <class T>
  118. void AnalogFilterByIir<T>::
  119.          Initialize( int proc_block_size, 
  120.                      double samp_intvl)
  121. {
  122.    Proc_Block_Size = proc_block_size;
  123.    Samp_Intvl = samp_intvl;
  124.    Init_Kernel();
  125. }
  126. //======================================================
  127. template <class T>
  128. void AnalogFilterByIir<T>::Initialize()
  129. {
  130.    Samp_Intvl = In_Sig->GetSampIntvl();
  131.    Proc_Block_Size = In_Sig->GetBlockSize();
  132.    Init_Kernel();
  133. }
  134. //======================================================
  135. template <class T>
  136. void AnalogFilterByIir<T>::Init_Kernel()
  137. {
  138.    Input_Write_Idx = 0;
  139.    Output_Write_Idx = 1;
  140.    if(Bypass_Enabled) return;
  141.    Warped_Rad_Pass_Edge =
  142.       tan( PI * Samp_Intvl * Norm_Hz_Pass_Edge )/
  143.       (PI * Samp_Intvl);
  144.    Warped_Rad_Pass_Edge_2 =
  145.       tan( PI * Samp_Intvl * Norm_Hz_Pass_Edge_2 )/
  146.       (PI * Samp_Intvl);
  147.    Denorm_Proto_Filt = 
  148.          new DenormalizedPrototype(  
  149.                               Lowpass_Proto_Filt,
  150.                               Filt_Band_Config,
  151.                               Warped_Rad_Pass_Edge,
  152.                               Warped_Rad_Pass_Edge_2);
  153.    BilinearTransf(   Denorm_Proto_Filt,
  154.                      Samp_Intvl,
  155.                      &A_Coefs,
  156.                      &B_Coefs);
  157.    Input_Buffer = new std::complex<double>[Filt_Order+1];
  158.    Output_Buffer = new std::complex<double>[Filt_Order+1];
  159.    for(int idx=0; idx<=Filt_Order; idx++){
  160.       Output_Buffer[idx] = 0.0;
  161.       Input_Buffer[idx] = 0.0;
  162.    }
  163.    Input_Write_Idx = 0;
  164.    Output_Write_Idx = 1;
  165.    IirComputedResponse *computed_response;
  166.    if(Resp_Plot_Enabled){
  167.       computed_response =  
  168.          new IirComputedResponse(B_Coefs,
  169.                                  A_Coefs,
  170.                                  Filt_Order,
  171.                                  Samp_Intvl,
  172.                                  8192, //num_resp_pts
  173.                                  Db_Scale_Enabled);
  174.       char resp_file_name[50];
  175.       strcpy(resp_file_name, GetModelName());
  176.       strcat(resp_file_name, "_resp.txt");
  177.       ofstream *resp_file = 
  178.                new ofstream(resp_file_name, ios::out);
  179.       computed_response->DumpMagResp(resp_file);
  180.       resp_file->close();
  181.       delete resp_file;
  182.       delete computed_response;
  183.    }
  184.    Out_Mem = 
  185.       new complex<double>[Proc_Block_Size+Filt_Order];
  186.    int i;
  187.    for(i=0; i<(Proc_Block_Size+Filt_Order); i++){
  188.       *(Out_Mem+i) = 0.0;
  189.    }
  190.    if(Using_Signal_Objects){
  191.       T *in_sig_ptr = GET_INPUT_PTR(In_Sig);
  192.       in_sig_ptr -= Filt_Order;
  193.       for(i=0; i<(Proc_Block_Size+Filt_Order); i++){
  194.          (*in_sig_ptr) = 0.0;
  195.          in_sig_ptr++;
  196.       }
  197.    }
  198. }
  199. //===========================================
  200. template <class T>
  201. int AnalogFilterByIir<T>::Execute()
  202. {
  203.    T *in_sig_ptr;
  204.    T *offset_in_sig_ptr;
  205.    complex<double> in_sig_samp;
  206.    T *out_sig_ptr;
  207.    complex<double> *out_mem_base;
  208.    complex<double> *out_mem_ptr;
  209.    complex<double> sum;
  210.    int samp_idx;
  211.    int n, m;
  212.    int proc_block_size;
  213.    in_sig_ptr = GET_INPUT_PTR(In_Sig);
  214.    out_sig_ptr = GET_OUTPUT_PTR(Out_Sig);
  215.    proc_block_size = In_Sig->GetValidBlockSize();
  216.    Out_Sig->SetValidBlockSize(proc_block_size);
  217.    if(Bypass_Enabled){
  218.       // copy input signal to output signal
  219.       for(  samp_idx=0; 
  220.             samp_idx<Proc_Block_Size; 
  221.             samp_idx++){
  222.          *out_sig_ptr = *in_sig_ptr;
  223.          out_sig_ptr++;
  224.          in_sig_ptr++;
  225.       }
  226.    }
  227.    else
  228.    {
  229.       out_mem_base = Out_Mem;
  230.       //  copy last N = Filt_Order samples of remembered
  231.       //  output from previous pass down into first N 
  232.       //  locs of double precision memory buffer
  233.       out_mem_ptr = out_mem_base;
  234.       for(samp_idx=0; samp_idx<Filt_Order; samp_idx++){
  235.          *out_mem_ptr = *(out_mem_ptr+proc_block_size);
  236.          out_mem_ptr++;
  237.       }
  238.       //  perform filter summations
  239.       for(  samp_idx=0; 
  240.             samp_idx<proc_block_size; 
  241.             samp_idx++){
  242.          out_mem_ptr = out_mem_base + samp_idx;
  243.          offset_in_sig_ptr = in_sig_ptr - Filt_Order;
  244.          sum = 0.0;
  245.          for(n=Filt_Order; n>=1; n--){
  246.             sum += A_Coefs[n] * (*out_mem_ptr);
  247.             out_mem_ptr++;
  248.          }
  249.          for(m=Filt_Order; m>=0; m--){
  250.             in_sig_samp = *offset_in_sig_ptr;
  251.             sum += B_Coefs[m] * in_sig_samp;
  252.             offset_in_sig_ptr++;
  253.          }
  254.          *out_mem_ptr = sum;
  255.          if(typeid(*out_sig_ptr) == typeid(sum)){
  256.             //*out_sig_ptr = sum;
  257.          }
  258.          else{
  259.             *out_sig_ptr = sum.real();
  260.          }
  261.          out_sig_ptr++;
  262.          in_sig_ptr++;
  263.          Cumul_Samp_Count++;
  264.       } // end of loop over samp_idx
  265.    } // end of else clause on if(Bypass_Enabled)
  266.    return(_MES_AOK);
  267. }
  268. //======================================================
  269. //  Method to execute the model on single sample
  270. //  in subordinate instance
  271. template <class T>
  272. T AnalogFilterByIir<T>::ProcessSample(T input_val)
  273. {
  274.    T output_val;
  275.    std::complex<double> sum, term;
  276.    int input_read_idx;
  277.    int output_read_idx;
  278.    int tap_idx;
  279.    if(Bypass_Enabled){ 
  280.       // copy input signal to output signal
  281.       output_val = input_val;
  282.    }
  283.    else{
  284.       Input_Buffer[Input_Write_Idx] = input_val;
  285.       input_read_idx = Input_Write_Idx;
  286.       Input_Write_Idx++;
  287.       if(Input_Write_Idx > Filt_Order) 
  288.                            Input_Write_Idx = 0;
  289.       //  perform filter summations
  290.       sum = 0.0;
  291.       for( tap_idx=0; tap_idx<=Filt_Order; tap_idx++){
  292.          term = B_Coefs[tap_idx] * 
  293.                         Input_Buffer[input_read_idx];
  294.          sum += term;
  295.          input_read_idx--;
  296.          if(input_read_idx < 0) 
  297.                         input_read_idx = Filt_Order;
  298.       }
  299.       output_read_idx = Output_Write_Idx;
  300.       for(tap_idx=1; tap_idx<=Filt_Order; tap_idx++){
  301.          term = A_Coefs[tap_idx] * 
  302.                         Output_Buffer[output_read_idx];
  303.          sum+= term;
  304.          output_read_idx--;
  305.          if(output_read_idx < 1) 
  306.                           output_read_idx = Filt_Order;
  307.       }
  308.       Output_Write_Idx++;
  309.       if(Output_Write_Idx > Filt_Order) 
  310.                                  Output_Write_Idx = 1;
  311.       Output_Buffer[Output_Write_Idx] = sum;
  312.       if(typeid(output_val) == typeid(sum)){
  313.          //output_val = sum;
  314.       }
  315.       else{
  316.          output_val = sum.real();
  317.       }
  318.    } // end of else clause on if(Bypass_Enabled) control structure
  319.    return(output_val);
  320. }
  321. template AnalogFilterByIir<std::complex<float> >;
  322. template AnalogFilterByIir<float>;