[FFmpeg-devel] [PATCH] Port biquads filters from SoX

Michael Niedermayer michaelni at gmx.at
Thu Jan 31 02:39:53 CET 2013


On Wed, Jan 30, 2013 at 08:17:40PM +0000, Paul B Mahol wrote:
> Adds allpass, bandpass, bandreject, bass, biquad,
> equalizer, highpass, lowpass and treble filter.
[...]
> +#define BIQUAD_FILTER(name, type, min, max)                                   \
> +static void biquad_## name (const void *input, void *output, int len,         \
> +                            double *i1, double *i2, double *o1, double *o2,   \
> +                            double b0, double b1, double b2,                  \
> +                            double a1, double a2)                             \
> +{                                                                             \
> +    const type *ibuf = input;                                                 \
> +    type *obuf = output;                                                      \
> +    int i;                                                                    \
> +                                                                              \
> +    for (i = 0; i < len; i++) {                                               \
> +        double o0 = ibuf[i] * b0 + *i1 * b1 + *i2 * b2 - *o1 * a1 - *o2 * a2; \
> +        *i2 = *i1;                                                            \
> +        *i1 = ibuf[i];                                                        \
> +        *o2 = *o1;                                                            \
> +        *o1 = o0;                                                             \
> +        if (o0 < min) {                                                       \
> +            av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
> +            obuf[i] = min;                                                    \
> +        } else if (o0 > max) {                                                \
> +            av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
> +            obuf[i] = max;                                                    \
> +        } else {                                                              \
> +            obuf[i] = o0;                                                     \
> +        }                                                                     \
> +    }                                                                         \

i suspect the code would be faster if it uses local variables instead
of all the pointer dereferences (unless gcc manages to optimize that
out)

the assignments between i*/o* variables can also be removed by
unrolling the loop

also this looks like it can be done in SIMD
the FIR & cliping part is trivial. the IIR part can be shifted to
make dependancies more distant unless i miss something

o[i  ] = I[i  ] + a*o[i-1] + b*o[i-2]
o[i-1] = I[i-1] + a*o[i-2] + b*o[i-3]

o[i  ] = I[i  ] + a*(I[i-1] + a*o[i-2] + b*o[i-3]) + b*o[i-2]
o[i  ] = I[i  ] + a*I[i-1] + (a*a+b)*o[i-2] + a*b*o[i-3]

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Observe your enemies, for they first find out your faults. -- Antisthenes
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130131/82bfe1fc/attachment.asc>


More information about the ffmpeg-devel mailing list