Go to the documentation of this file.
61 int order,
float cutoff_ratio,
70 "low-pass filter mode\n");
75 "even filter orders\n");
79 wa = 2 * tan(
M_PI * 0.5 * cutoff_ratio);
82 for (
i = 1;
i < (order >> 1) + 1;
i++)
83 c->cx[
i] =
c->cx[
i - 1] * (order -
i + 1LL) /
i;
87 for (
i = 1;
i <= order;
i++)
88 p[
i][0] = p[
i][1] = 0.0;
89 for (
i = 0;
i < order;
i++) {
91 double th = (
i + (order >> 1) + 0.5) *
M_PI / order;
92 double a_re, a_im, c_re, c_im;
99 zp[0] = (a_re * c_re + a_im * c_im) / (c_re * c_re + c_im * c_im);
100 zp[1] = (a_im * c_re - a_re * c_im) / (c_re * c_re + c_im * c_im);
102 for (j = order; j >= 1; j--) {
105 p[j][0] = a_re * zp[0] - a_im * zp[1] + p[j - 1][0];
106 p[j][1] = a_re * zp[1] + a_im * zp[0] + p[j - 1][1];
108 a_re = p[0][0] * zp[0] - p[0][1] * zp[1];
109 p[0][1] = p[0][0] * zp[1] + p[0][1] * zp[0];
112 c->gain = p[order][0];
113 for (
i = 0;
i < order;
i++) {
115 c->cy[
i] = (-p[
i][0] * p[order][0] + -p[
i][1] * p[order][1]) /
116 (p[order][0] * p[order][0] + p[order][1] * p[order][1]);
118 c->gain /= 1 << order;
125 float cutoff_ratio,
float stopband)
127 double cos_w0, sin_w0;
133 "high-pass and low-pass filter modes\n");
141 cos_w0 = cos(
M_PI * cutoff_ratio);
142 sin_w0 = sin(
M_PI * cutoff_ratio);
144 a0 = 1.0 + (sin_w0 / 2.0);
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->gain = ((1.0 - cos_w0) / 2.0) /
a0;
152 x0 = ((1.0 - cos_w0) / 2.0) /
a0;
153 x1 = (1.0 - cos_w0) /
a0;
155 c->cy[0] = (-1.0 + (sin_w0 / 2.0)) /
a0;
156 c->cy[1] = (2.0 * cos_w0) /
a0;
169 int order,
float cutoff_ratio,
170 float stopband,
float ripple)
175 if (order <= 0 || order >
MAXORDER || cutoff_ratio >= 1.0)
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]) \
282 const int16_t *
src, ptrdiff_t sstep,
283 int16_t *dst, ptrdiff_t dstep)
287 }
else if (
c->order == 4) {
307 const float *
src, ptrdiff_t sstep,
308 float *dst, ptrdiff_t dstep)
312 }
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