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)
210 #define CONV_S16(dest, source) dest = av_clip_int16(lrintf(source));
212 #define CONV_FLT(dest, source) dest = source;
214 #define FILTER_BW_O4_1(i0, i1, i2, i3, fmt) \
215 in = *src0 * c->gain + \
216 c->cy[0] * s->x[i0] + \
217 c->cy[1] * s->x[i1] + \
218 c->cy[2] * s->x[i2] + \
219 c->cy[3] * s->x[i3]; \
220 res = (s->x[i0] + in) * 1 + \
221 (s->x[i1] + s->x[i3]) * 4 + \
223 CONV_ ## fmt(*dst0, res) \
228 #define FILTER_BW_O4(type, fmt) { \
230 const type *src0 = src; \
232 for (i = 0; i < size; i += 4) { \
234 FILTER_BW_O4_1(0, 1, 2, 3, fmt); \
235 FILTER_BW_O4_1(1, 2, 3, 0, fmt); \
236 FILTER_BW_O4_1(2, 3, 0, 1, fmt); \
237 FILTER_BW_O4_1(3, 0, 1, 2, fmt); \
241 #define FILTER_DIRECT_FORM_II(type, fmt) { \
243 const type *src0 = src; \
245 for (i = 0; i < size; i++) { \
248 in = *src0 * c->gain; \
249 for (j = 0; j < c->order; j++) \
250 in += c->cy[j] * s->x[j]; \
251 res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1]; \
252 for (j = 1; j < c->order >> 1; j++) \
253 res += (s->x[j] + s->x[c->order - j]) * c->cx[j]; \
254 for (j = 0; j < c->order - 1; j++) \
255 s->x[j] = s->x[j + 1]; \
256 CONV_ ## fmt(*dst0, res) \
257 s->x[c->order - 1] = in; \
263 #define FILTER_O2(type, fmt) { \
265 const type *src0 = src; \
267 for (i = 0; i < size; i++) { \
268 float in = *src0 * c->gain + \
269 s->x[0] * c->cy[0] + \
270 s->x[1] * c->cy[1]; \
271 CONV_ ## fmt(*dst0, s->x[0] + in + s->x[1] * c->cx[1]) \
281 const int16_t *
src, ptrdiff_t sstep,
282 int16_t *dst, ptrdiff_t dstep)
286 }
else if (
c->order == 4) {
295 const float *
src, ptrdiff_t sstep,
296 float *dst, ptrdiff_t dstep)
300 }
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.
void ff_iir_filter_init(FFIIRFilterContext *f)
Initialize FFIIRFilterContext.
void ff_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.
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)
#define FF_ALLOC_OR_GOTO(ctx, p, size, label)
av_cold void ff_iir_filter_free_statep(struct FFIIRFilterState **state)
Free and zero filter state.
@ FF_FILTER_TYPE_BUTTERWORTH
#define FF_ALLOCZ_OR_GOTO(ctx, p, size, label)