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

3G开发

开发平台:

Visual C++

  1. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. //
  3. //  File = filter_proto.cpp
  4. //
  5. //  Base class for all analog protoypes
  6. //
  7. #include <math.h>
  8. #include "misdefs.h"
  9. #include "parmfile.h"
  10. #include "filter_proto.h"
  11. #include "filter_types.h"
  12. #include "unwrap.h"
  13. extern ParmFile ParmInput;
  14. extern ofstream *DebugFile;
  15. //======================================================
  16. //  constructor
  17. AnalogFilterPrototype::AnalogFilterPrototype( void )
  18. {
  19.   Degree_Of_Denom = -1;
  20.   Degree_Of_Numer = -1;
  21.   Num_Biquad_Sects = 0;
  22.   H_Zero = 1.0;
  23. }
  24. //======================================================
  25. //  constructor
  26. AnalogFilterPrototype::AnalogFilterPrototype( int filt_order )
  27. {
  28.   Filt_Order = filt_order;
  29.   Degree_Of_Denom = -1;
  30.   Degree_Of_Numer = -1;
  31.   Num_Biquad_Sects = 0;
  32.   H_Zero = 1.0;
  33. }
  34. //=======================================================
  35. //  destructor
  36. AnalogFilterPrototype::~AnalogFilterPrototype()
  37. {
  38.   if( !(Pole_Locs == NULL) ) delete []Pole_Locs;
  39.   if( !(Zero_Locs == NULL) ) delete []Zero_Locs;
  40. }
  41. //=================================================
  42. int AnalogFilterPrototype::GetOrder()
  43. {
  44.   return(Filt_Order);
  45. }
  46. //=================================================
  47. int AnalogFilterPrototype::GetNumPoles()
  48. {
  49.   return(Num_Poles);
  50. }
  51. //================================================
  52. std::complex<double> *AnalogFilterPrototype::GetPoles()
  53. {
  54.   return(Pole_Locs);
  55. }
  56. //=================================================
  57. int AnalogFilterPrototype::GetNumZeros()
  58. {
  59.   return(Num_Zeros);
  60. }
  61. //================================================
  62. std::complex<double> *AnalogFilterPrototype::GetZeros()
  63. {
  64.   return(Zero_Locs);
  65. }
  66. //================================================
  67. double AnalogFilterPrototype::GetHZero()
  68. {
  69.   return(H_Zero);
  70. }
  71. //================================================
  72. int AnalogFilterPrototype::Get_Biquads(  double **coef_a2,
  73.                                          double **coef_a1,
  74.                                          double **coef_a0,
  75.                                          double **coef_b1,
  76.                                          double **coef_b0 )
  77. {
  78.   if(Num_Biquad_Sects <= 0)
  79.     {
  80.     }
  81.   *coef_a2 = A2_Coef;
  82.   *coef_a1 = A1_Coef;
  83.   *coef_a0 = A0_Coef;
  84.   *coef_b1 = B1_Coef;
  85.   *coef_b0 = B0_Coef;
  86.   return(Num_Biquad_Sects);
  87. }
  88. //===============================================================
  89. //
  90. void AnalogFilterPrototype::DumpBiquads( ofstream* output_stream)
  91. {
  92.  (*output_stream) << "nBiquad Coefficientsn" << endl;
  93.  
  94.  for(int i=0; i<Num_Biquad_Sects; i++)
  95.    {
  96.     (*output_stream) << i << "    b1 = " << B1_Coef[i]
  97.                         << "    b0 = " << B0_Coef[i]
  98.                         << endl;
  99. //    (*output_stream) << i << ") a2 = " << A2_Coef[i]
  100. //                        << "    a1 = " << A1_Coef[i]
  101. //                        << "    a0 = " << A0_Coef[i]
  102. //                        << "    b1 = " << B1_Coef[i]
  103. //                        << "    b0 = " << B0_Coef[i]
  104. //                        << endl;
  105.    }
  106.  if(Filt_Order%2)
  107.   { // order is odd
  108.   (*output_stream) << i << "    c = " << Real_Pole
  109.                                       << endl;
  110.   }                            
  111.  return;
  112. }
  113. //===================================================
  114. RealPolynomial AnalogFilterPrototype::GetDenomPoly(bool binomial_use_enab)
  115. {
  116.  //-----------------------------------------------------
  117.  //  if denominator polynomial is not built yet, build
  118.  //  it by multiplying together binomial factors (s-p[i]) 
  119.  //  where the p[i] are the poles of the filter
  120.  
  121.  if(Degree_Of_Denom <0)
  122.    {
  123.    if(binomial_use_enab)
  124.     { // use binomials
  125.     *DebugFile << "using binomials" << endl;
  126.     CmplxPolynomial cmplx_denom_poly =
  127.                            CmplxPolynomial( std::complex<double>(1.0, 0.0),
  128.                                             -Pole_Locs[0] );
  129.     //                                        -Pole_Locs[1] );
  130.     //for(int ii=2; ii<= Num_Poles; ii++)
  131.     for(int ii=1; ii< Num_Poles; ii++)
  132.       {
  133.        cmplx_denom_poly *= CmplxPolynomial( std::complex<double>(1.0, 0.0),
  134.                                             -Pole_Locs[ii] );
  135.       }                                                                
  136.     *DebugFile << "about to dump cmplx_denom_poly" << endl;
  137.     cmplx_denom_poly.DumpToStream(&*DebugFile);
  138.     
  139.     Denom_Poly = RealPolynomial( cmplx_denom_poly);
  140.     //Denom_Poly = poly_cast( cmplx_denom_poly);
  141.     
  142.     Degree_Of_Denom = Denom_Poly.GetDegree();
  143.     
  144.     *DebugFile << "nin AnalogFilterPrototype::GetDenomPoly" << endl;
  145.     *DebugFile << "(using binomials) real-valued version:" << endl;
  146.     Denom_Poly.DumpToStream(&*DebugFile);
  147.     }
  148.   else
  149.     { // use biquads
  150.     *DebugFile << "using biquads" << endl;
  151.     Denom_Poly = RealPolynomial( 1.0 );
  152.    
  153.     for(int ii=0; ii< Num_Biquad_Sects; ii++)
  154.       {
  155.        Denom_Poly *= RealPolynomial( 1.0, B1_Coef[ii], B0_Coef[ii] );
  156.       }                                                                  
  157.     Degree_Of_Denom = Denom_Poly.GetDegree();
  158.     if(Filt_Order%2)
  159.       { //odd order
  160.       Denom_Poly *= RealPolynomial( 1.0, Real_Pole );
  161.       }
  162.     } // end of use biquds
  163.    }                                    
  164.   #ifdef _DEBUG
  165.     
  166.     *DebugFile << "nin AnalogFilterPrototype::GetDenomPoly" << endl;
  167.     *DebugFile << "denominator coefficients:" << endl;
  168.     Denom_Poly.DumpToStream(&*DebugFile);
  169.   #endif
  170.    
  171.  return(Denom_Poly);
  172. }
  173. //================================================================
  174. //
  175. RealPolynomial AnalogFilterPrototype::GetNumerPoly(bool binomial_use_enab)
  176. {
  177.  //---------------------------------------------------
  178.  //  if numerator polynomial is not built yet,
  179.  //  build it by multiplying together (s-z[i]) binomial
  180.  //  factors where the z[i] are the zeros of the filter.
  181.  
  182.  if(Degree_Of_Numer <0)
  183.    {
  184.       if(binomial_use_enab)
  185.       {
  186.          CmplxPolynomial cmplx_poly =
  187.                         CmplxPolynomial( d_complex_t( 1.0, 0.0), -Zero_Locs[0] );
  188.          //for(int ii=2; ii<= Num_Zeros; ii++)
  189.          for(int ii=1; ii< Num_Zeros; ii++)
  190.          {
  191.             cmplx_poly *= CmplxPolynomial( d_complex_t(1.0, 0.0), -Zero_Locs[ii] );
  192.          }                                                          
  193.          cmplx_poly.DumpToStream(&*DebugFile);
  194.          Numer_Poly = RealPolynomial(cmplx_poly);
  195.          Degree_Of_Numer = Numer_Poly.GetDegree();
  196.          *DebugFile << "nreal-valued version:" << endl;
  197.          Numer_Poly.DumpToStream(&*DebugFile);
  198.       }
  199.       else
  200.       {
  201.       } 
  202.    }                                  
  203.  return(Numer_Poly);
  204. }
  205. //=========================================================
  206. void AnalogFilterPrototype::FilterFrequencyResponse(void)
  207. {
  208.  std::complex<double> numer, denom;
  209.  std::complex<double> transfer_function;
  210.  std::complex<double> s_val, pole;
  211.  double delta_freq, magnitude, phase;
  212.  double peak_magnitude;
  213.  double *mag_resp, *phase_resp, *group_dly;
  214.  int i, k;
  215.  delta_freq = 0.0025;
  216.  //delta_freq = 0.0013889;
  217.  peak_magnitude = -1000.0;
  218.  ofstream* response_file = new ofstream("anlg_rsp.txt", ios::out);
  219.  mag_resp = new double[800];
  220.  phase_resp = new double[800];
  221.  group_dly = new double[800];
  222.  for( i=1; i<800; i++)
  223.    {
  224.     numer = std::complex<double>(1.0, 0.0);
  225.     denom = std::complex<double>(1.0, 0.0);
  226.     //s_val = double_complex(0.0, i*delta_freq*2.0*PI);
  227.     s_val = std::complex<double>(0.0, i*delta_freq);
  228.     //for( k=1; k<=Num_Zeros; k++)
  229.     for( k=0; k<Num_Zeros; k++)
  230.       {
  231.        numer *= (s_val - Zero_Locs[k]);
  232.       }
  233.     //for( k=1; k<=Num_Poles; k++)
  234.     for( k=0; k<Num_Poles; k++)
  235.       {
  236.        denom *= (s_val - Pole_Locs[k]);
  237.       }
  238.     transfer_function = numer/denom;
  239.     magnitude = 10.0 * log10(std::norm(transfer_function));
  240.     //magnitude = sqrt(std::norm(transfer_function));
  241.     mag_resp[i] = magnitude;
  242.     if(magnitude > peak_magnitude)
  243.       {
  244.        peak_magnitude = magnitude;
  245.       }
  246.     phase = 180.0 * std::arg(transfer_function)/PI;
  247.     phase_resp[i] = phase;
  248.    }
  249.  UnwrapPhase(0, &(phase_resp[1]));
  250.  for(i=2; i<800; i++)
  251.   {
  252.   UnwrapPhase(i, &(phase_resp[i]));
  253.   }
  254.  group_dly[1] = PI * (phase_resp[1] - phase_resp[2])
  255.                 / (180.0 * delta_freq);
  256.  for(i=2; i<800; i++)
  257.   {
  258.   group_dly[i] = PI * (phase_resp[i-1] - phase_resp[i])
  259.                  / (180.0 * delta_freq);
  260.   }
  261.  for(i=1; i<800; i++)
  262.    {
  263.     //(*response_file) << (1.0+ (i*delta_freq8)) << ",  "
  264.     (*response_file) << i*delta_freq << ",  " << (mag_resp[i]-peak_magnitude)
  265.                      << ",  " << phase_resp[i] 
  266.                      << ",  " << group_dly[i] << endl;
  267.                      //(*response_file)<< (1.0-(mag_resp[800-i]/peak_magnitude)) << endl;
  268.    }
  269.  //H_Sub_Zero = 1.0/sqrt(mag_sqrd_peak);
  270.  response_file->close();
  271.  delete []phase_resp;
  272.  delete []mag_resp;
  273.  return;
  274. }