Go to the documentation of this file.
57 int order,
float cutoff_ratio,
66 "low-pass filter mode\n");
71 "even filter orders\n");
75 wa = 2 * tan(
M_PI * 0.5 * cutoff_ratio);
78 for (
i = 1;
i < (order >> 1) + 1;
i++)
79 c->cx[
i] =
c->cx[
i - 1] * (order -
i + 1LL) /
i;
83 for (
i = 1;
i <= order;
i++)
84 p[
i][0] = p[
i][1] = 0.0;
85 for (
i = 0;
i < order;
i++) {
87 double th = (
i + (order >> 1) + 0.5) *
M_PI / order;
88 double a_re, a_im, c_re, c_im;
95 zp[0] = (a_re * c_re + a_im * c_im) / (c_re * c_re + c_im * c_im);
96 zp[1] = (a_im * c_re - a_re * c_im) / (c_re * c_re + c_im * c_im);
98 for (j = order; j >= 1; j--) {
101 p[j][0] = a_re * zp[0] - a_im * zp[1] + p[j - 1][0];
102 p[j][1] = a_re * zp[1] + a_im * zp[0] + p[j - 1][1];
104 a_re = p[0][0] * zp[0] - p[0][1] * zp[1];
105 p[0][1] = p[0][0] * zp[1] + p[0][1] * zp[0];
108 c->gain = p[order][0];
109 for (
i = 0;
i < order;
i++) {
111 c->cy[
i] = (-p[
i][0] * p[order][0] + -p[
i][1] * p[order][1]) /
112 (p[order][0] * p[order][0] + p[order][1] * p[order][1]);
114 c->gain /= 1 << order;
121 float cutoff_ratio,
float stopband)
123 double cos_w0, sin_w0;
129 "high-pass and low-pass filter modes\n");
137 cos_w0 = cos(
M_PI * cutoff_ratio);
138 sin_w0 = sin(
M_PI * cutoff_ratio);
140 a0 = 1.0 + (sin_w0 / 2.0);
143 c->gain = ((1.0 + cos_w0) / 2.0) /
a0;
144 x0 = ((1.0 + cos_w0) / 2.0) /
a0;
145 x1 = (-(1.0 + cos_w0)) /
a0;
147 c->gain = ((1.0 - cos_w0) / 2.0) /
a0;
148 x0 = ((1.0 - cos_w0) / 2.0) /
a0;
149 x1 = (1.0 - cos_w0) /
a0;
151 c->cy[0] = (-1.0 + (sin_w0 / 2.0)) /
a0;
152 c->cy[1] = (2.0 * cos_w0) /
a0;
165 int order,
float cutoff_ratio,
166 float stopband,
float ripple)
171 if (order <= 0 || order >
MAXORDER || cutoff_ratio >= 1.0)
207 #define CONV_S16(dest, source) dest = av_clip_int16(lrintf(source));
209 #define CONV_FLT(dest, source) dest = source;
211 #define FILTER_BW_O4_1(i0, i1, i2, i3, fmt) \
212 in = *src0 * c->gain + \
213 c->cy[0] * s->x[i0] + \
214 c->cy[1] * s->x[i1] + \
215 c->cy[2] * s->x[i2] + \
216 c->cy[3] * s->x[i3]; \
217 res = (s->x[i0] + in) * 1 + \
218 (s->x[i1] + s->x[i3]) * 4 + \
220 CONV_ ## fmt(*dst0, res) \
225 #define FILTER_BW_O4(type, fmt) { \
227 const type *src0 = src; \
229 for (i = 0; i < size; i += 4) { \
231 FILTER_BW_O4_1(0, 1, 2, 3, fmt); \
232 FILTER_BW_O4_1(1, 2, 3, 0, fmt); \
233 FILTER_BW_O4_1(2, 3, 0, 1, fmt); \
234 FILTER_BW_O4_1(3, 0, 1, 2, fmt); \
238 #define FILTER_DIRECT_FORM_II(type, fmt) { \
240 const type *src0 = src; \
242 for (i = 0; i < size; i++) { \
245 in = *src0 * c->gain; \
246 for (j = 0; j < c->order; j++) \
247 in += c->cy[j] * s->x[j]; \
248 res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1]; \
249 for (j = 1; j < c->order >> 1; j++) \
250 res += (s->x[j] + s->x[c->order - j]) * c->cx[j]; \
251 for (j = 0; j < c->order - 1; j++) \
252 s->x[j] = s->x[j + 1]; \
253 CONV_ ## fmt(*dst0, res) \
254 s->x[c->order - 1] = in; \
260 #define FILTER_O2(type, fmt) { \
262 const type *src0 = src; \
264 for (i = 0; i < size; i++) { \
265 float in = *src0 * c->gain + \
266 s->x[0] * c->cy[0] + \
267 s->x[1] * c->cy[1]; \
268 CONV_ ## fmt(*dst0, s->x[0] + in + s->x[1] * c->cx[1]) \
278 const int16_t *
src, ptrdiff_t sstep,
279 int16_t *dst, ptrdiff_t dstep)
283 }
else if (
c->order == 4) {
303 const float *
src, ptrdiff_t sstep,
304 float *dst, ptrdiff_t dstep)
308 }
else if (
c->order == 4) {
#define MAXORDER
maximum supported filter order
#define FILTER_BW_O4(type, fmt)
void ff_iir_filter(const struct FFIIRFilterCoeffs *c, struct FFIIRFilterState *s, int size, const int16_t *src, ptrdiff_t sstep, int16_t *dst, ptrdiff_t dstep)
Perform IIR filtering on signed 16-bit input samples.
IIR filter global parameters.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static void iir_filter_flt(const struct FFIIRFilterCoeffs *c, struct FFIIRFilterState *s, int size, const float *src, ptrdiff_t sstep, float *dst, ptrdiff_t dstep)
Perform IIR filtering on floating-point input samples.
void ff_iir_filter_init(FFIIRFilterContext *f)
Initialize FFIIRFilterContext.
av_cold struct FFIIRFilterCoeffs * ff_iir_filter_init_coeffs(void *avc, enum IIRFilterType filt_type, enum IIRFilterMode filt_mode, int order, float cutoff_ratio, float stopband, float ripple)
Initialize filter coefficients.
@ FF_FILTER_MODE_HIGHPASS
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
#define FILTER_O2(type, fmt)
static av_cold int biquad_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c, enum IIRFilterMode filt_mode, int order, float cutoff_ratio, float stopband)
#define i(width, name, range_min, range_max)
av_cold void ff_iir_filter_free_coeffsp(struct FFIIRFilterCoeffs **coeffsp)
Free filter coefficients.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
void ff_iir_filter_init_mips(FFIIRFilterContext *f)
#define FILTER_DIRECT_FORM_II(type, fmt)
av_cold struct FFIIRFilterState * ff_iir_filter_init_state(int order)
Create new filter state.
static av_cold int butterworth_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c, enum IIRFilterMode filt_mode, int order, float cutoff_ratio, float stopband)
av_cold void ff_iir_filter_free_statep(struct FFIIRFilterState **state)
Free and zero filter state.
@ FF_FILTER_TYPE_BUTTERWORTH