3 * Copyright (c) 2008 Konstantin Shishkov
5 * This file is part of FFmpeg.
7 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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
27 #include "iirfilter.h"
32 * IIR filter global parameters
34 typedef struct FFIIRFilterCoeffs
{
44 typedef struct FFIIRFilterState
{
48 /// maximum supported filter order
51 struct FFIIRFilterCoeffs
* ff_iir_filter_init_coeffs(enum IIRFilterType filt_type
,
52 enum IIRFilterMode filt_mode
,
53 int order
, float cutoff_ratio
,
54 float stopband
, float ripple
)
59 complex p
[MAXORDER
+ 1];
61 if(filt_type
!= FF_FILTER_TYPE_BUTTERWORTH
|| filt_mode
!= FF_FILTER_MODE_LOWPASS
)
63 if(order
<= 1 || (order
& 1) || order
> MAXORDER
|| cutoff_ratio
>= 1.0)
66 c
= av_malloc(sizeof(FFIIRFilterCoeffs
));
67 c
->cx
= av_malloc(sizeof(c
->cx
[0]) * ((order
>> 1) + 1));
68 c
->cy
= av_malloc(sizeof(c
->cy
[0]) * order
);
71 wa
= 2 * tan(M_PI
* 0.5 * cutoff_ratio
);
74 for(i
= 1; i
< (order
>> 1) + 1; i
++)
75 c
->cx
[i
] = c
->cx
[i
- 1] * (order
- i
+ 1LL) / i
;
78 for(i
= 1; i
<= order
; i
++)
80 for(i
= 0; i
< order
; i
++){
82 double th
= (i
+ (order
>> 1) + 0.5) * M_PI
/ order
;
84 zp
= (zp
+ 2.0) / (zp
- 2.0);
86 for(j
= order
; j
>= 1; j
--)
87 p
[j
] = zp
*p
[j
] + p
[j
- 1];
90 c
->gain
= creal(p
[order
]);
91 for(i
= 0; i
< order
; i
++){
92 c
->gain
+= creal(p
[i
]);
93 c
->cy
[i
] = creal(-p
[i
] / p
[order
]);
95 c
->gain
/= 1 << order
;
100 struct FFIIRFilterState
* ff_iir_filter_init_state(int order
)
102 FFIIRFilterState
* s
= av_mallocz(sizeof(FFIIRFilterState
) + sizeof(s
->x
[0]) * (order
- 1));
106 #define FILTER(i0, i1, i2, i3) \
107 in = *src * c->gain \
108 + c->cy[0]*s->x[i0] + c->cy[1]*s->x[i1] \
109 + c->cy[2]*s->x[i2] + c->cy[3]*s->x[i3]; \
110 res = (s->x[i0] + in )*1 \
111 + (s->x[i1] + s->x[i3])*4 \
113 *dst = av_clip_int16(lrintf(res)); \
118 void ff_iir_filter(const struct FFIIRFilterCoeffs *c, struct FFIIRFilterState *s, int size, const int16_t *src, int sstep, int16_t *dst, int dstep)
123 for(i
= 0; i
< size
; i
+= 4){
132 for(i
= 0; i
< size
; i
++){
136 for(j
= 0; j
< c
->order
; j
++)
137 in
+= c
->cy
[j
] * s
->x
[j
];
138 res
= s
->x
[0] + in
+ s
->x
[c
->order
>> 1] * c
->cx
[c
->order
>> 1];
139 for(j
= 1; j
< c
->order
>> 1; j
++)
140 res
+= (s
->x
[j
] + s
->x
[c
->order
- j
]) * c
->cx
[j
];
141 for(j
= 0; j
< c
->order
- 1; j
++)
142 s
->x
[j
] = s
->x
[j
+ 1];
143 *dst
= av_clip_int16(lrintf(res
));
144 s
->x
[c
->order
- 1] = in
;
151 void ff_iir_filter_free_state(struct FFIIRFilterState
*state
)
156 void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs
*coeffs
)