3 * Copyright (c) 2008 Konstantin Shishkov
5 * This file is part of Libav.
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * Libav 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 GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * different IIR filters implementation
29 #include "libavutil/attributes.h"
30 #include "libavutil/common.h"
31 #include "libavutil/log.h"
33 #include "iirfilter.h"
36 * IIR filter global parameters
38 typedef struct FFIIRFilterCoeffs
{
48 typedef struct FFIIRFilterState
{
52 /// maximum supported filter order
55 static av_cold
int butterworth_init_coeffs(void *avc
,
56 struct FFIIRFilterCoeffs
*c
,
57 enum IIRFilterMode filt_mode
,
58 int order
, float cutoff_ratio
,
63 double p
[MAXORDER
+ 1][2];
65 if (filt_mode
!= FF_FILTER_MODE_LOWPASS
) {
66 av_log(avc
, AV_LOG_ERROR
, "Butterworth filter currently only supports "
67 "low-pass filter mode\n");
71 av_log(avc
, AV_LOG_ERROR
, "Butterworth filter currently only supports "
72 "even filter orders\n");
76 wa
= 2 * tan(M_PI
* 0.5 * cutoff_ratio
);
79 for (i
= 1; i
< (order
>> 1) + 1; i
++)
80 c
->cx
[i
] = c
->cx
[i
- 1] * (order
- i
+ 1LL) / i
;
84 for (i
= 1; i
<= order
; i
++)
85 p
[i
][0] = p
[i
][1] = 0.0;
86 for (i
= 0; i
< order
; i
++) {
88 double th
= (i
+ (order
>> 1) + 0.5) * M_PI
/ order
;
89 double a_re
, a_im
, c_re
, c_im
;
96 zp
[0] = (a_re
* c_re
+ a_im
* c_im
) / (c_re
* c_re
+ c_im
* c_im
);
97 zp
[1] = (a_im
* c_re
- a_re
* c_im
) / (c_re
* c_re
+ c_im
* c_im
);
99 for (j
= order
; j
>= 1; j
--) {
102 p
[j
][0] = a_re
* zp
[0] - a_im
* zp
[1] + p
[j
- 1][0];
103 p
[j
][1] = a_re
* zp
[1] + a_im
* zp
[0] + p
[j
- 1][1];
105 a_re
= p
[0][0] * zp
[0] - p
[0][1] * zp
[1];
106 p
[0][1] = p
[0][0] * zp
[1] + p
[0][1] * zp
[0];
109 c
->gain
= p
[order
][0];
110 for (i
= 0; i
< order
; i
++) {
112 c
->cy
[i
] = (-p
[i
][0] * p
[order
][0] + -p
[i
][1] * p
[order
][1]) /
113 (p
[order
][0] * p
[order
][0] + p
[order
][1] * p
[order
][1]);
115 c
->gain
/= 1 << order
;
120 static av_cold
int biquad_init_coeffs(void *avc
, struct FFIIRFilterCoeffs
*c
,
121 enum IIRFilterMode filt_mode
, int order
,
122 float cutoff_ratio
, float stopband
)
124 double cos_w0
, sin_w0
;
127 if (filt_mode
!= FF_FILTER_MODE_HIGHPASS
&&
128 filt_mode
!= FF_FILTER_MODE_LOWPASS
) {
129 av_log(avc
, AV_LOG_ERROR
, "Biquad filter currently only supports "
130 "high-pass and low-pass filter modes\n");
134 av_log(avc
, AV_LOG_ERROR
, "Biquad filter must have order of 2\n");
138 cos_w0
= cos(M_PI
* cutoff_ratio
);
139 sin_w0
= sin(M_PI
* cutoff_ratio
);
141 a0
= 1.0 + (sin_w0
/ 2.0);
143 if (filt_mode
== FF_FILTER_MODE_HIGHPASS
) {
144 c
->gain
= ((1.0 + cos_w0
) / 2.0) / a0
;
145 x0
= ((1.0 + cos_w0
) / 2.0) / a0
;
146 x1
= (-(1.0 + cos_w0
)) / a0
;
147 } else { // FF_FILTER_MODE_LOWPASS
148 c
->gain
= ((1.0 - cos_w0
) / 2.0) / a0
;
149 x0
= ((1.0 - cos_w0
) / 2.0) / a0
;
150 x1
= (1.0 - cos_w0
) / a0
;
152 c
->cy
[0] = (-1.0 + (sin_w0
/ 2.0)) / a0
;
153 c
->cy
[1] = (2.0 * cos_w0
) / a0
;
155 // divide by gain to make the x coeffs integers.
156 // during filtering, the delay state will include the gain multiplication
157 c
->cx
[0] = lrintf(x0
/ c
->gain
);
158 c
->cx
[1] = lrintf(x1
/ c
->gain
);
163 av_cold
struct FFIIRFilterCoeffs
*ff_iir_filter_init_coeffs(void *avc
,
164 enum IIRFilterType filt_type
,
165 enum IIRFilterMode filt_mode
,
166 int order
, float cutoff_ratio
,
167 float stopband
, float ripple
)
169 FFIIRFilterCoeffs
*c
;
172 if (order
<= 0 || order
> MAXORDER
|| cutoff_ratio
>= 1.0)
175 FF_ALLOCZ_OR_GOTO(avc
, c
, sizeof(FFIIRFilterCoeffs
),
177 FF_ALLOC_OR_GOTO(avc
, c
->cx
, sizeof(c
->cx
[0]) * ((order
>> 1) + 1),
179 FF_ALLOC_OR_GOTO(avc
, c
->cy
, sizeof(c
->cy
[0]) * order
,
184 case FF_FILTER_TYPE_BUTTERWORTH
:
185 ret
= butterworth_init_coeffs(avc
, c
, filt_mode
, order
, cutoff_ratio
,
188 case FF_FILTER_TYPE_BIQUAD
:
189 ret
= biquad_init_coeffs(avc
, c
, filt_mode
, order
, cutoff_ratio
,
193 av_log(avc
, AV_LOG_ERROR
, "filter type is not currently implemented\n");
201 ff_iir_filter_free_coeffs(c
);
205 av_cold
struct FFIIRFilterState
*ff_iir_filter_init_state(int order
)
207 FFIIRFilterState
*s
= av_mallocz(sizeof(FFIIRFilterState
) + sizeof(s
->x
[0]) * (order
- 1));
211 #define CONV_S16(dest, source) dest = av_clip_int16(lrintf(source));
213 #define CONV_FLT(dest, source) dest = source;
215 #define FILTER_BW_O4_1(i0, i1, i2, i3, fmt) \
216 in = *src0 * c->gain + \
217 c->cy[0] * s->x[i0] + \
218 c->cy[1] * s->x[i1] + \
219 c->cy[2] * s->x[i2] + \
220 c->cy[3] * s->x[i3]; \
221 res = (s->x[i0] + in) * 1 + \
222 (s->x[i1] + s->x[i3]) * 4 + \
224 CONV_ ## fmt(*dst0, res) \
229 #define FILTER_BW_O4(type, fmt) { \
231 const type *src0 = src; \
233 for (i = 0; i < size; i += 4) { \
235 FILTER_BW_O4_1(0, 1, 2, 3, fmt); \
236 FILTER_BW_O4_1(1, 2, 3, 0, fmt); \
237 FILTER_BW_O4_1(2, 3, 0, 1, fmt); \
238 FILTER_BW_O4_1(3, 0, 1, 2, fmt); \
242 #define FILTER_DIRECT_FORM_II(type, fmt) { \
244 const type *src0 = src; \
246 for (i = 0; i < size; i++) { \
249 in = *src0 * c->gain; \
250 for (j = 0; j < c->order; j++) \
251 in += c->cy[j] * s->x[j]; \
252 res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1]; \
253 for (j = 1; j < c->order >> 1; j++) \
254 res += (s->x[j] + s->x[c->order - j]) * c->cx[j]; \
255 for (j = 0; j < c->order - 1; j++) \
256 s->x[j] = s->x[j + 1]; \
257 CONV_ ## fmt(*dst0, res) \
258 s->x[c->order - 1] = in; \
264 #define FILTER_O2(type, fmt) { \
266 const type *src0 = src; \
268 for (i = 0; i < size; i++) { \
269 float in = *src0 * c->gain + \
270 s->x[0] * c->cy[0] + \
271 s->x[1] * c->cy[1]; \
272 CONV_ ## fmt(*dst0, s->x[0] + in + s->x[1] * c->cx[1]) \
280 void ff_iir_filter(const struct FFIIRFilterCoeffs
*c
,
281 struct FFIIRFilterState
*s
, int size
,
282 const int16_t *src
, ptrdiff_t sstep
,
283 int16_t *dst
, ptrdiff_t dstep
)
286 FILTER_O2(int16_t, S16
)
287 } else if (c
->order
== 4) {
288 FILTER_BW_O4(int16_t, S16
)
290 FILTER_DIRECT_FORM_II(int16_t, S16
)
294 void ff_iir_filter_flt(const struct FFIIRFilterCoeffs
*c
,
295 struct FFIIRFilterState
*s
, int size
,
296 const float *src
, ptrdiff_t sstep
,
297 float *dst
, ptrdiff_t dstep
)
300 FILTER_O2(float, FLT
)
301 } else if (c
->order
== 4) {
302 FILTER_BW_O4(float, FLT
)
304 FILTER_DIRECT_FORM_II(float, FLT
)
308 av_cold
void ff_iir_filter_free_state(struct FFIIRFilterState
*state
)
313 av_cold
void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs
*coeffs
)