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 /*******************************************************************************
31 \ingroup IIR_FILTER_DESIGN_GROUP
32 \fn int bilinear(double* bs, double* as, int ord, double* bz, double* az)
33 \brief Analog filter transfer function H(s) bilinear transform to the
34  digital filter transfer function H(z).
35 
36 Function calculates digital filter coefficients by rational substitution
37 
38 \f[
39 s \leftarrow \frac{1 - z^{-1}}{1 - z^{-1}}.
40 \f]
41 
42 Digital filter order still the same as analog prototype order.
43 Analog prototype frequency \f$\Omega\f$ related with the digital filter
44 normalized frequency \f$\omega\f$ as:
45 
46 \f[
47 \Omega = \tan(\omega / 2).
48 \f]
49 
50 \param[in] bs Pointer to the numerator coefficients of an
51  analog prototype transfer function \f$H(s)\f$. \n
52  Array size is `[ord+1 x 1]`. \n
53  Memory must be allocated. \n \n
54 
55 \param[in] as Pointer to the denominator coefficients of an
56  analog prototype transfer function \f$H(s)\f$. \n
57  Array size is `[ord+1 x 1]`. \n
58  Memory must be allocated. \n \n
59 
60 \param[in] ord Filter order. \n
61  Number of coefficients \f$H(s)\f$ and \f$H(z)\f$
62  numerator and denominator equals `ord+1`. \n \n
63 
64 \param[out] bz Pointer to the numerator coefficients of a
65  digital filter transfer function \f$H(z)\f$. \n
66  Array size is `[ord+1 x 1]`. \n
67  Memory must be allocated. \n \n
68 
69 \param[out] az Pointer to the numerator coefficients of a
70  digital filter transfer function \f$H(z)\f$. \n
71  Array size is `[ord+1 x 1]`. \n
72  Memory must be allocated. \n \n
73 
74 \return
75  `RES_OK` if filter is calculated successfully. \n \n
76  Else \ref ERROR_CODE_GROUP "code error". \n
77 
78 \author Sergey Bakhurin www.dsplib.org
79 *******************************************************************************/
80 int DSPL_API bilinear(double* bs, double* as, int ord, double* bz, double* az)
81 {
82  double c[2] = {1.0, -1.0};
83  double d[2] = {1.0, 1.0};
84  return ratcompos(bs, as, ord, c, d, 1, bz, az);
85 }
86 
87 
88 
89 
90 /******************************************************************************
91 Digital IIR filter coefficients calculation
92 *******************************************************************************/
93 int DSPL_API iir(double rp, double rs, int ord, double w0, double w1,
94  int type, double* b, double* a)
95 {
96  double *bs = NULL;
97  double *as = NULL;
98  double *bt = NULL;
99  double *at = NULL;
100  double wa0, wa1, ws;
101  int err, ord_ap = ord;
102 
103  if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_LPF) ||
104  ((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_HPF))
105  {
106  bs = (double*)malloc((ord_ap+1)*sizeof(double));
107  as = (double*)malloc((ord_ap+1)*sizeof(double));
108  bt = (double*)malloc((ord_ap+1)*sizeof(double));
109  at = (double*)malloc((ord_ap+1)*sizeof(double));
110  }
111 
112 
113  if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_BPASS) ||
114  ((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_BSTOP))
115  {
116  if(ord % 2)
117  return ERROR_FILTER_ORD_BP;
118  else
119  {
120  ord_ap = ord / 2;
121  bs = (double*)malloc((ord_ap + 1)*sizeof(double));
122  as = (double*)malloc((ord_ap + 1)*sizeof(double));
123  bt = (double*)malloc((ord + 1)*sizeof(double));
124  at = (double*)malloc((ord + 1)*sizeof(double));
125  }
126  }
127  err = iir_ap(rp, rs, ord_ap, type, bs, as);
128  if(err != RES_OK)
129  goto error_proc;
130 
131  /* frequency transformation */
132  wa0 = tan(w0 * M_PI * 0.5);
133  wa1 = tan(w1 * M_PI * 0.5);
134 
135  switch(type & DSPL_FILTER_TYPE_MASK)
136  {
137 
138  case DSPL_FILTER_LPF:
139  err = low2low(bs, as, ord_ap, 1.0, wa0, bt, at);
140  break;
141 
142  case DSPL_FILTER_HPF:
143  ws = filter_ws1(ord_ap, rp, rs, type);
144  err = low2low( bs, as, ord_ap, 1.0, 1.0 / ws, bs, as);
145  err = low2high(bs, as, ord_ap, 1.0, wa0, bt, at);
146  break;
147 
148  case DSPL_FILTER_BPASS:
149  err = low2bp(bs, as, ord_ap, 1.0, wa0, wa1, bt, at);
150  break;
151 
152  case DSPL_FILTER_BSTOP:
153  /* need frequency transform ws -> 1 rad/s */
154 
155  ws = filter_ws1(ord_ap, rp, rs, type);
156  err = low2low( bs, as, ord_ap, 1.0, 1.0 / ws, bs, as);
157  err = low2bs(bs, as, ord_ap, 1.0, wa0, wa1, bt, at);
158  break;
159 
160  default:
161  err = ERROR_FILTER_TYPE;
162  break;
163  }
164  if(err != RES_OK)
165  goto error_proc;
166 
167 
168  err = bilinear(bt, at, ord, b, a);
169 
170 
171 error_proc:
172 
173  if(bs)
174  free(bs);
175  if(as)
176  free(as);
177  if(bt)
178  free(bt);
179  if(at)
180  free(at);
181 
182  return err;
183 
184 }
185 
186 
187 
188 
189 
190 
191 /******************************************************************************
192 Analog prototype for IIR
193 *******************************************************************************/
194 int iir_ap(double rp, double rs, int ord, int type, double* b, double* a)
195 {
196  int err;
197  switch(type & DSPL_FILTER_APPROX_MASK)
198  {
199  case DSPL_FILTER_BUTTER:
200  err = butter_ap(rp, ord, b, a);
201  break;
202  case DSPL_FILTER_CHEBY1:
203  err = cheby1_ap(rp, ord, b, a);
204  break;
205  case DSPL_FILTER_CHEBY2:
206  err = cheby2_ap_wp1(rp, rs, ord, b, a);
207  break;
208  case DSPL_FILTER_ELLIP:
209  err = ellip_ap(rp, rs, ord, b, a);
210  break;
211  default:
212  err = ERROR_FILTER_APPROX;
213  }
214 
215 
216  return err;
217 }
218 
219 
220 
221 
int low2low(double *b, double *a, int ord, double w0, double w1, double *beta, double *alpha)
Частотное преобразование ФНЧ-ФНЧ
Definition: filter_ft.c:179
int butter_ap(double rp, int ord, double *b, double *a)
Расчет передаточной характеристики аналогового нормированного ФНЧ Баттерворта.
Definition: filter_ap.c:33
int ratcompos(double *b, double *a, int n, double *c, double *d, int p, double *beta, double *alpha)
Рациональная композиця
Definition: filter_ft.c:204
int low2high(double *b, double *a, int ord, double w0, double w1, double *beta, double *alpha)
Частотное преобразование ФНЧ-ФВЧ
Definition: filter_ft.c:151
int bilinear(double *bs, double *as, int ord, double *bz, double *az)
Билинейное преобразование передаточной характеристики аналогового фильтра , в передаточную характерис...
Definition: filter_iir.c:80
int cheby1_ap(double rp, int ord, double *b, double *a)
Расчет передаточной характеристики аналогового нормированного ФНЧ Чебышёва первого рода.
Definition: filter_ap.c:129
#define RES_OK
Функция завершилась корректно. Ошибки отсутствуют.
Definition: dspl.h:94