RTXI  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
iir_resp.cpp
Go to the documentation of this file.
1 //
2 // File = iir_resp.cpp
3 //
4 // Member functions for class IirFilterResponse
5 //
6 
7 #include <math.h>
8 #include <stdlib.h>
9 #include <iostream>
10 
11 #include "iir_resp.h"
12 #include "complex.h"
13 #include "misdefs.h"
14 #include "typedefs.h"
15 #include "unwrap.h"
16 
17 using namespace std;
18 
19 #ifdef _DEBUG
20 extern std::ofstream DebugFile;
21 #endif
22 //==================================================
23 // constructor with all configuration parameters
24 // passed in as arguments
25 //--------------------------------------------------
26 
28  int num_resp_pts, int db_scale_enabled,
29  int normalize_enabled,
30  char* resp_file_name)
31 {
32  Filter_Design = filter_design;
33  Num_Resp_Pts = num_resp_pts;
34  Db_Scale_Enabled = db_scale_enabled;
35  Normalize_Enabled = normalize_enabled;
36 
37  if (resp_file_name == NULL) {
38  Response_File = new ofstream("iir_resp.txt", ios::out);
39  } else {
40  Response_File = new ofstream(resp_file_name, ios::out);
41  }
42 
43  Num_Numer_Coeffs = Filter_Design->GetNumNumerCoeffs();
44  Num_Denom_Coeffs = Filter_Design->GetNumDenomCoeffs();
45  Freq_Resp = (complex*)new double[2 * Num_Resp_Pts];
46  Mag_Resp = new double[Num_Resp_Pts];
47  Phase_Resp = new double[Num_Resp_Pts];
48 
49  return;
50 }
51 
52 //===================================================================
53 // alternate constructor with interactive setting of
54 // configuration parameters
55 //-------------------------------------------------------------------
57  istream& uin, ostream& uout)
58 {
59  logical default_file_ok;
60  Filter_Design = filter_design;
61 
62  uout << "number of points in plot of frequency response?" << std::endl;
63  uin >> Num_Resp_Pts;
64 
65  uout << "scaling?\n"
66  << " 0 = linear, 1 = dB" << std::endl;
67  uin >> Db_Scale_Enabled;
68 
69  if (Db_Scale_Enabled != 0)
70  Db_Scale_Enabled = 1;
71  Normalize_Enabled = 1;
72 
73  uout << "default name for magnitude response output\n"
74  << "file is iir_resp.txt\n\n"
75  << "is this okay?"
76  << " 0 = NO, 1 = YES" << std::endl;
77  uin >> default_file_ok;
78 
79  if (default_file_ok) {
80  Response_File = new ofstream("iir_resp.txt", ios::out);
81  } else {
82  char* file_name;
83  file_name = new char[31];
84 
85  uout << "enter complete name for output file (30 chars max)" << std::endl;
86  uin >> file_name;
87  Response_File = new ofstream(file_name, ios::out);
88  delete[] file_name;
89  }
90 
91  Num_Numer_Coeffs = Filter_Design->GetNumNumerCoeffs();
92  Num_Denom_Coeffs = Filter_Design->GetNumDenomCoeffs();
93  Freq_Resp = (complex*)new double[2 * Num_Resp_Pts];
94  Mag_Resp = new double[Num_Resp_Pts];
95  Phase_Resp = new double[Num_Resp_Pts];
96 
97  return;
98 }
99 
100 //==================================================
101 // method to compute frequency response
102 //--------------------------------------------------
103 void
105 {
106  int resp_indx, tap_indx;
107  double delta_time, delta_freq;
108  double theta, phi;
109  double real_sum, imag_sum;
110  double *numer_coeff, *denom_coeff;
111  complex numerator, denominator;
112 
113  std::cout << " in IirFilterResponse::ComputeResponse" << std::endl;
114 #ifdef _DEBUG
115  DebugFile << " in IirFilterResponse::ComputeResponse" << std::endl;
116 #endif
117  numer_coeff = Filter_Design->GetNumerCoefficients();
118  denom_coeff = Filter_Design->GetDenomCoefficients();
119  delta_time = Filter_Design->GetSamplingInterval();
120 
121  delta_freq = PI / (delta_time * Num_Resp_Pts);
122  theta = delta_freq * delta_time;
123 
124 #ifdef _DEBUG
125  DebugFile << "in ComputeResponse, Num_Numer_Coeffs = " << Num_Numer_Coeffs
126  << std::endl;
127  DebugFile << "in ComputeResponse, Num_Denom_Coeffs = " << Num_Denom_Coeffs
128  << std::endl;
129 #endif
130 
131  for (resp_indx = 0; resp_indx < Num_Resp_Pts; resp_indx++) {
132  real_sum = 0.0;
133  imag_sum = 0.0;
134 
135  for (tap_indx = 0; tap_indx < Num_Numer_Coeffs; tap_indx++) {
136  phi = theta * resp_indx * tap_indx;
137  real_sum += (numer_coeff[tap_indx] * cos(phi));
138  imag_sum -= numer_coeff[tap_indx] * sin(phi);
139  }
140  numerator = complex(real_sum, imag_sum);
141 
142  real_sum = 1.0;
143  imag_sum = 0.0;
144 
145  for (tap_indx = 1; tap_indx <= Num_Denom_Coeffs; tap_indx++) {
146  phi = theta * tap_indx * resp_indx;
147  real_sum -= (denom_coeff[tap_indx] * cos(phi));
148  imag_sum += (denom_coeff[tap_indx] * sin(phi));
149  }
150  denominator = complex(real_sum, imag_sum);
151  Freq_Resp[resp_indx] = numerator / denominator;
152  }
153 
154  //-----------------------------------------------
155  // compute magnitude and phase of response
156 
157  for (resp_indx = 0; resp_indx < Num_Resp_Pts; resp_indx++) {
158  Phase_Resp[resp_indx] = arg(Freq_Resp[resp_indx]);
159 
160  if (Db_Scale_Enabled) {
161  Mag_Resp[resp_indx] = 10.0 * log10(mag_sqrd(Freq_Resp[resp_indx]));
162  } else {
163  Mag_Resp[resp_indx] = norm(Freq_Resp[resp_indx]);
164  }
165  }
166 
167  return;
168 }
169 
170 //=======================================================
171 // method to normalize magnitude response
172 //-------------------------------------------------------
173 
174 void
176 {
177  int n;
178  double biggest;
179 
180  if (Db_Scale_Enabled) {
181  biggest = -100.0;
182 
183  for (n = 0; n < Num_Resp_Pts; n++) {
184  if (Mag_Resp[n] > biggest)
185  biggest = Mag_Resp[n];
186  }
187  for (n = 0; n < Num_Resp_Pts; n++) {
188  Mag_Resp[n] = Mag_Resp[n] - biggest;
189  }
190  } else {
191  biggest = 0.0;
192 
193  for (n = 0; n < Num_Resp_Pts; n++) {
194  if (Mag_Resp[n] > biggest)
195  biggest = Mag_Resp[n];
196  }
197  for (n = 0; n < Num_Resp_Pts; n++) {
198  Mag_Resp[n] = Mag_Resp[n] / biggest;
199  }
200  }
201  return;
202 }
203 //===============================================
204 // method to return a pointer to the magnitude
205 // response that is stored inside this class
206 //-----------------------------------------------
207 
208 double*
210 {
211  return (Mag_Resp);
212 }
213 
214 //===========================================================
215 // method to dump magnitude response to the stream
216 // designated by Response_File
217 //-----------------------------------------------------------
218 
219 void
221 {
222  double freq, delta_time, delta_freq, phase;
223 
224  delta_time = Filter_Design->GetSamplingInterval();
225  delta_freq = 0.5 / (delta_time * Num_Resp_Pts);
226 
227  for (int n = 0; n < Num_Resp_Pts; n++) {
228  freq = n * delta_freq;
229  phase = 180.0 * Phase_Resp[n] / PI;
230  UnwrapPhase(n, &phase);
231  (*Response_File) << freq << ", " << Mag_Resp[n] << ", " << phase
232  << std::endl;
233  }
234  return;
235 }
236 //=====================================================
237 // searches the magnitude response over the interval
238 // from sample intrvl_beg thru the sample intrvl_end
239 // and then returns the largest value found in this
240 // interval.
241 //-----------------------------------------------------
242 double
244 {
245  double peak;
246  int n, indexOfPeak;
247 
248  peak = -9999.0;
249  for (n = nBeg; n < nEnd; n++) {
250  if (Mag_Resp[n] > peak) {
251  peak = Mag_Resp[n];
252  indexOfPeak = n;
253  }
254  }
255  return (peak);
256 }
void NormalizeResponse(void)
Definition: iir_resp.cpp:175
void DumpMagResp(void)
Definition: iir_resp.cpp:220
int logical
Definition: typedefs.h:4
void UnwrapPhase(int ix, double *phase)
Definition: unwrap.cpp:15
double arg(const complex _z)
Definition: complex.h:133
#define PI
Definition: misdefs.h:9
std::ofstream DebugFile
IirFilterResponse(IirFilterDesign *filter_design, int num_resp_pts, int db_scale_enabled, int normalize_enabled, char *resp_file_name)
Definition: iir_resp.cpp:27
double mag_sqrd(const complex _z)
Definition: complex.h:128
virtual void ComputeResponse(void)
Definition: iir_resp.cpp:104
double * GetMagResp(void)
Definition: iir_resp.cpp:209
double norm(const complex _z)
Definition: complex.h:113
double GetIntervalPeak(int beg_indx, int end_indx)
Definition: iir_resp.cpp:243