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

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = iir_comp_resp.cpp
  3. //
  4. //  Member functions for class IirComputedResponse
  5. //
  6. #include <math.h>
  7. #include <stdlib.h>
  8. #include <complex>
  9. #include "iir_comp_resp.h"
  10. #include "typedefs.h"
  11. #include "misdefs.h"
  12. #include "unwrap.h"
  13. #ifdef _DEBUG
  14. extern ofstream *DebugFile;
  15. #endif
  16. //============================================================
  17. IirComputedResponse::IirComputedResponse( double *numer_coeff,
  18.                                           double *denom_coeff,
  19.                                           int filt_order,
  20.                                           double samp_intvl,
  21.                                           int num_resp_pts,
  22.                                           bool db_scale_enabled )
  23. {
  24.  int resp_indx, tap_indx;
  25.  double delta_freq;
  26.  double theta, phi;
  27.  int max_numer_idx, max_denom_idx;
  28.  double real_sum, imag_sum;
  29.  std::complex<double> numerator, denominator;
  30.  
  31.  #ifdef _DEBUG
  32.   *DebugFile << " in ctor for IirComputedResponse" << endl;
  33.  #endif
  34.   Num_Resp_Pts = num_resp_pts;
  35.   Db_Scale_Enabled = db_scale_enabled;
  36.   Samp_Intvl = samp_intvl;
  37.   Freq_Resp = new std::complex<double>[Num_Resp_Pts];
  38.   Mag_Resp = new double[Num_Resp_Pts];
  39.   Phase_Resp = new double[Num_Resp_Pts];
  40.   delta_freq = PI/( samp_intvl * Num_Resp_Pts );
  41.   theta = delta_freq * samp_intvl;
  42.   max_numer_idx = filt_order;
  43.   max_denom_idx = filt_order;
  44.   for( resp_indx=1; resp_indx<Num_Resp_Pts; resp_indx++){
  45.     real_sum = 0.0;
  46.     imag_sum = 0.0;
  47.     for( tap_indx=0; tap_indx<=max_numer_idx; tap_indx++){
  48.       phi = theta * resp_indx * tap_indx;
  49.       real_sum += (numer_coeff[tap_indx] * cos(phi));
  50.       imag_sum -= numer_coeff[tap_indx] * sin(phi);
  51.       }  
  52.     numerator = std::complex<double>(real_sum, imag_sum);
  53.     real_sum = 1.0;
  54.     imag_sum = 0.0;
  55.   
  56.     for( tap_indx=1; tap_indx<=max_denom_idx; tap_indx++){
  57.        phi = theta * tap_indx * resp_indx;
  58.        real_sum -= (denom_coeff[tap_indx] * cos(phi));
  59.        imag_sum += (denom_coeff[tap_indx] * sin(phi));
  60.       } 
  61.     denominator = std::complex<double>(real_sum, imag_sum); 
  62.     Freq_Resp[resp_indx] = numerator/denominator;
  63.     }
  64.   Freq_Resp[0] = Freq_Resp[1];
  65.    
  66.  //-----------------------------------------------
  67.  //  compute magnitude and phase of response
  68.  for( resp_indx=0; resp_indx<Num_Resp_Pts; resp_indx++){
  69.     Phase_Resp[resp_indx] = std::arg<double>(Freq_Resp[resp_indx]);
  70.    if(Db_Scale_Enabled)
  71.      {Mag_Resp[resp_indx] = 10.0 * log10(std::norm<double>(Freq_Resp[resp_indx]));}
  72.    else
  73.      {Mag_Resp[resp_indx] = std::abs<double>(Freq_Resp[resp_indx]);}
  74.    }
  75.  
  76.  return;
  77. }
  78. //=======================================================
  79. void IirComputedResponse::NormalizeResponse( void )
  80. {
  81.  int n;
  82.  double peak;
  83.  
  84.  if(Db_Scale_Enabled){
  85.     peak = -100.0; 
  86.     
  87.     for( n=0; n < Num_Resp_Pts; n++)
  88.       {if(Mag_Resp[n]>peak) peak = Mag_Resp[n];}
  89.     for( n=0; n < Num_Resp_Pts; n++)
  90.       {Mag_Resp[n] = Mag_Resp[n] - peak;}
  91.    }
  92.  else
  93.    {
  94.     peak = 0.0;
  95.     
  96.     for( n=0; n < Num_Resp_Pts; n++)
  97.       {if(Mag_Resp[n]>peak) peak = Mag_Resp[n];}
  98.     for( n=0; n < Num_Resp_Pts; n++)
  99.       {Mag_Resp[n] = Mag_Resp[n] / peak;}
  100.    }
  101.  return;
  102. }
  103. //===============================================
  104. double* IirComputedResponse::GetMagResp( void)
  105. {
  106.  return(Mag_Resp);
  107. }
  108. //===========================================================
  109. void IirComputedResponse::DumpMagResp( ofstream *resp_file )
  110. {
  111.  double freq, delta_freq, phase;
  112.  
  113.  delta_freq = 0.5/( Samp_Intvl * Num_Resp_Pts );
  114.  for(int n=0; n<Num_Resp_Pts; n++){
  115.     freq = n*delta_freq;
  116.     phase = 180.0 * Phase_Resp[n] /PI;
  117.     UnwrapPhase(n, &phase);
  118.     (*resp_file) << freq << ", " 
  119.                      << Mag_Resp[n] << ", "
  120.                      << phase << endl;
  121.    }
  122.  return;
  123. }