libdspl-2.0
Библиотека алгоритмов цифровой обработки сигналов
filter_iir.c
1 /*
2 * Copyright (c) 2015-2019 Sergey Bakhurin
3 * Digital Signal Processing Library [http://dsplib.org]
4 *
5 * This file is part of libdspl-2.0.
6 *
7 * is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * DSPL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include "dspl.h"
25 #include "dspl_internal.h"
26 
27 
28 
29 /*******************************************************************************
30 \ingroup IIR_FILTER_DESIGN_GROUP
31 \fn int bilinear(double* bs, double* as, int ord, double* bz, double* az)
32 \brief Analog filter transfer function H(s) bilinear transform to the
33  digital filter transfer function H(z).
34 
35 Function calculates digital filter coefficients by rational substitution
36 
37 \f[
38 s \leftarrow \frac{1 - z^{-1}}{1 - z^{-1}}.
39 \f]
40 
41 Digital filter order still the same as analog prototype order.
42 Analog prototype frequency \f$\Omega\f$ related with the digital filter
43 normalized frequency \f$\omega\f$ as:
44 
45 \f[
46 \Omega = \tan(\omega / 2).
47 \f]
48 
49 \param[in] bs Pointer to the numerator coefficients of an
50  analog prototype transfer function \f$H(s)\f$. \n
51  Array size is `[ord+1 x 1]`. \n
52  Memory must be allocated. \n \n
53 
54 \param[in] as Pointer to the denominator coefficients of an
55  analog prototype transfer function \f$H(s)\f$. \n
56  Array size is `[ord+1 x 1]`. \n
57  Memory must be allocated. \n \n
58 
59 \param[in] ord Filter order. \n
60  Number of coefficients \f$H(s)\f$ and \f$H(z)\f$
61  numerator and denominator equals `ord+1`. \n \n
62 
63 \param[out] bz Pointer to the numerator coefficients of a
64  digital filter transfer function \f$H(z)\f$. \n
65  Array size is `[ord+1 x 1]`. \n
66  Memory must be allocated. \n \n
67 
68 \param[out] az Pointer to the numerator coefficients of a
69  digital filter transfer function \f$H(z)\f$. \n
70  Array size is `[ord+1 x 1]`. \n
71  Memory must be allocated. \n \n
72 
73 \return
74  `RES_OK` if filter is calculated successfully. \n \n
75  Else \ref ERROR_CODE_GROUP "code error". \n
76 
77 \author Sergey Bakhurin www.dsplib.org
78 *******************************************************************************/
79 int DSPL_API bilinear(double* bs, double* as, int ord, double* bz, double* az)
80 {
81  double c[2] = {1.0, -1.0};
82  double d[2] = {1.0, 1.0};
83  return ratcompos(bs, as, ord, c, d, 1, bz, az);
84 }
85 
86 
87 
88 
89 
90 
91 /*****************************************************************************
92 \ingroup IIR_FILTER_DESIGN_GROUP
93 \fn int iir(double rp, double rs, int ord, double w0, double w1, int type, double* b, double* a)
94 \brief IIR digital filter transfer function \f$H(z)\f$
95  coefficients calculation which can be used in \ref filter_iir
96 
97 
98 \param[in] rp Filter passband ripple level (dB). \n \n
99 
100 \param[in] rs Filter stopband supression level (dB).\n \n
101 
102 \param[in] ord Filter order. \n
103  Number of \f$H(z)\f$ coefficients is `ord+1`. \n
104  This parameter must be evan for bandpass
105  and bandstop filter type.\n \n
106 
107 \param[in] w0 Normlized cutoff frequency for LPF and HPF. \n
108  Left cutoff frequency for bandpass and bandstop filter. \n
109  Valid value from 0 to 1. \n
110  Here 0 corresponds to 0 Hz frequency, 1 corresponds to
111  Fs/2 Hz frequency. \n \n
112 
113 
114 \param[in] w1 Right cutoff frequency for bandpass and bandstop filter.\n
115  Valid value from 0 to 1. \n
116  Here 0 corresponds to 0 Hz frequency, 1 corresponds to
117  Fs/2 Hz frequency. \n
118  This parameter is ignored for LPF and HPF. \n \n
119 
120 \param[in] type Filter type. \n
121  This paramenter is combination of filter type flags:\n
122  \verbatim
123  DSPL_FILTER_LPF - lowpass filter;
124  DSPL_FILTER_HPF - highpass filter;
125  DSPL_FILTER_BPASS - bandpass filter;
126  DSPL_FILTER_BSTOP - bandstop filter,
127  \endverbatim
128  and filter approximation flags:
129  \verbatim
130  DSPL_FILTER_BUTTER - Buttetworth filter;
131  DSPL_FILTER_CHEBY1 - Chebyshev type 1 filter;
132  DSPL_FILTER_CHEBY2 - Chebyshev type 2 filter;
133  DSPL_FILTER_ELLIP - elliptic filter.
134  \endverbatim
135  \n \n
136 
137 \param[out] b Pointer to the vector of \f$H(z)\f$ numerator. \n
138  Vector size is `[ord+1 x 1]`.\n
139  Memory must be allocated. \n \n
140 
141 \param[out] a Pointer to the vector of \f$H(z)\f$ denominator. \n
142  Vector size is `[ord+1 x 1]`.\n
143  Memory must be allocated. \n \n
144 
145 \return
146  `RES_OK` if filter is calculated successfully. \n \n
147  Else \ref ERROR_CODE_GROUP "code error". \n
148 
149 Example:
150 
151 \include iir_test.c
152 
153 Program calculates filter coefficients for different
154 `type` parameter combination. Also program calculates filters magnitude and
155 draws plot:
156 
157 \image html iir_test.png
158 
159 \author Sergey Bakhurin www.dsplib.org
160 ******************************************************************************/
161 int DSPL_API iir(double rp, double rs, int ord, double w0, double w1,
162  int type, double* b, double* a)
163 {
164  double *bs = NULL;
165  double *as = NULL;
166  double *bt = NULL;
167  double *at = NULL;
168  double wa0, wa1, ws;
169  int err, ord_ap = ord;
170 
171  if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_LPF) ||
172  ((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_HPF))
173  {
174  bs = (double*)malloc((ord_ap+1)*sizeof(double));
175  as = (double*)malloc((ord_ap+1)*sizeof(double));
176  bt = (double*)malloc((ord_ap+1)*sizeof(double));
177  at = (double*)malloc((ord_ap+1)*sizeof(double));
178  }
179 
180 
181  if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_BPASS) ||
182  ((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_BSTOP))
183  {
184  if(ord % 2)
185  return ERROR_FILTER_ORD_BP;
186  else
187  {
188  ord_ap = ord / 2;
189  bs = (double*)malloc((ord_ap + 1)*sizeof(double));
190  as = (double*)malloc((ord_ap + 1)*sizeof(double));
191  bt = (double*)malloc((ord + 1)*sizeof(double));
192  at = (double*)malloc((ord + 1)*sizeof(double));
193  }
194  }
195  err = iir_ap(rp, rs, ord_ap, type, bs, as);
196  if(err != RES_OK)
197  goto error_proc;
198 
199  /* frequency transformation */
200  wa0 = tan(w0 * M_PI * 0.5);
201  wa1 = tan(w1 * M_PI * 0.5);
202 
203  switch(type & DSPL_FILTER_TYPE_MASK)
204  {
205 
206  case DSPL_FILTER_LPF:
207  err = low2low(bs, as, ord_ap, 1.0, wa0, bt, at);
208  break;
209 
210  case DSPL_FILTER_HPF:
211  ws = filter_ws1(ord_ap, rp, rs, type);
212  err = low2low( bs, as, ord_ap, 1.0, 1.0 / ws, bs, as);
213  err = low2high(bs, as, ord_ap, 1.0, wa0, bt, at);
214  break;
215 
216  case DSPL_FILTER_BPASS:
217  err = low2bp(bs, as, ord_ap, 1.0, wa0, wa1, bt, at);
218  break;
219 
220  case DSPL_FILTER_BSTOP:
221  /* need frequency transform ws -> 1 rad/s */
222 
223  ws = filter_ws1(ord_ap, rp, rs, type);
224  err = low2low( bs, as, ord_ap, 1.0, 1.0 / ws, bs, as);
225  err = low2bs(bs, as, ord_ap, 1.0, wa0, wa1, bt, at);
226  break;
227 
228  default:
229  err = ERROR_FILTER_TYPE;
230  break;
231  }
232  if(err != RES_OK)
233  goto error_proc;
234 
235 
236  err = bilinear(bt, at, ord, b, a);
237 
238 error_proc:
239 
240  if(bs)
241  free(bs);
242  if(as)
243  free(as);
244  if(bt)
245  free(bt);
246  if(at)
247  free(at);
248 
249  return err;
250 
251 }
252 
253 
254 
255 
256 
257 
258 /******************************************************************************
259 Analog prototype for IIR
260 *******************************************************************************/
261 int iir_ap(double rp, double rs, int ord, int type, double* b, double* a)
262 {
263  int err;
264  switch(type & DSPL_FILTER_APPROX_MASK)
265  {
266  case DSPL_FILTER_BUTTER:
267  err = butter_ap(rp, ord, b, a);
268  break;
269  case DSPL_FILTER_CHEBY1:
270  err = cheby1_ap(rp, ord, b, a);
271  break;
272  case DSPL_FILTER_CHEBY2:
273  err = cheby2_ap_wp1(rp, rs, ord, b, a);
274  break;
275  case DSPL_FILTER_ELLIP:
276  err = ellip_ap(rp, rs, ord, b, a);
277  break;
278  default:
279  err = ERROR_FILTER_APPROX;
280  }
281 
282 
283  return err;
284 }
285 
286 
287 
288 
int cheby1_ap(double rp, int ord, double *b, double *a)
Расчет передаточной характеристики аналогового нормированного ФНЧ Чебышёва первого рода.
Definition: filter_ap.c:129
int ratcompos(double *b, double *a, int n, double *c, double *d, int p, double *beta, double *alpha)
Рациональная композиця
Definition: filter_ft.c:204
int low2low(double *b, double *a, int ord, double w0, double w1, double *beta, double *alpha)
Частотное преобразование ФНЧ-ФНЧ
Definition: filter_ft.c:179
int bilinear(double *bs, double *as, int ord, double *bz, double *az)
Билинейное преобразование передаточной характеристики аналогового фильтра , в передаточную характерис...
Definition: filter_iir.c:79
int iir(double rp, double rs, int ord, double w0, double w1, int type, double *b, double *a)
Функция расчета коэффициентов передаточной характеристики цифрового фильтра БИХ.
Definition: filter_iir.c:161
#define ERROR_FILTER_TYPE
Неизвестный тип фильтра. Библиотека поддерживает следущие типы фильтров: ФНЧ, ФВЧ,...
Definition: dspl.h:115
int low2high(double *b, double *a, int ord, double w0, double w1, double *beta, double *alpha)
Частотное преобразование ФНЧ-ФВЧ
Definition: filter_ft.c:151
#define ERROR_FILTER_APPROX
Неизвестный тип аппроксимации цифрового или аналогового фильтра. Данная ошибка возникает при неверном...
Definition: dspl.h:109
int butter_ap(double rp, int ord, double *b, double *a)
Расчет передаточной характеристики аналогового нормированного ФНЧ Баттерворта.
Definition: filter_ap.c:33
int ellip_ap(double rp, double rs, int ord, double *b, double *a)
Расчет передаточной характеристики аналогового нормированного эллиптического ФНЧ.
Definition: filter_ap.c:390
#define RES_OK
Функция завершилась корректно. Ошибки отсутствуют.
Definition: dspl.h:94
#define ERROR_FILTER_ORD_BP
Порядок полосового или режекторного фильтра задан неверно. Порядок полосового и режекторного фильтра ...
Definition: dspl.h:112