[FFmpeg-devel] [RFC] Lowpass filter
Michael Niedermayer
michaelni
Mon Aug 25 19:13:35 CEST 2008
On Mon, Aug 25, 2008 at 12:38:31PM +0300, Kostya wrote:
> Here's my lowpass filter made more generic, so it will create
> lowpass filter for any even order with any cutoff frequency.
>
> I submit this in a plain form since it's easier to review
> this way (there's not too much left from the old implementation).
[...]
> #include "avcodec.h"
>
> struct FFLPFilterCoeffs;
> struct FFLPFilterState;
>
> /**
> * Initialize filter coefficients.
> *
> * @param order filter order
> * @param cutoff_ratio cutoff to input frequency ratio
> *
> * @return pointer to filter coefficients structure or NULL if filter cannot be created
> */
> struct FFLPFilterCoeffs* ff_lowpass_filter_init_coeffs(int order, float cutoff_ratio);
>
> /**
> * Create new filter state.
> *
> * @param order filter order
> *
> * @return pointer to new filter state or NULL if state creation fails
> */
> struct FFLPFilterState* ff_lowpass_filter_init_state(int order);
>
> /**
> * Free filter coefficients.
> *
> * @param coeffs pointer allocated with ff_lowpass_filter_init_coeffs()
> */
> void ff_lowpass_filter_free_coeffs(struct FFLPFilterCoeffs *coeffs);
>
> /**
> * Free filter state.
> *
> * @param state pointer allocated with ff_lowpass_filter_init_state()
> */
> void ff_lowpass_filter_free_state(struct FFLPFilterState *state);
>
> /**
> * Perform lowpass filtering on input samples.
> *
> * @param coeffs pointer to filter coefficients
> * @param state pointer to filter state
> * @param size input length
> * @param src source samples
> * @param sstep source stride
> * @param dst filtered samples (destination may be the same as input)
> * @param dstep destination stride
> */
> void ff_lowpass_filter(const struct FFLPFilterCoeffs *coeffs, struct FFLPFilterState *state, int size, int16_t *src, int sstep, int16_t *dst, int dstep);
>
> #endif /* FFMPEG_LOWPASS_H */
[...]
> struct FFLPFilterCoeffs* ff_lowpass_filter_init_coeffs(int order, float cutoff_ratio)
> {
> int i, j, size;
> FFLPFilterCoeffs *c;
> double wa;
> complex *p, *zp;
>
> if(order <= 1 || (order & 1) || cutoff_ratio >= 1.0)
> return NULL;
>
> c = av_malloc(sizeof(FFLPFilterCoeffs));
> c->cx = av_mallocz(sizeof(c->cx[0]) * (order + 1));
> c->cy = av_malloc (sizeof(c->cy[0]) * order);
> c->order = order;
>
> p = av_malloc(sizeof(p[0]) * (order + 1));
> zp = av_malloc(sizeof(zp[0]) * (order + 1));
Is there some largest order that makes sense?
of so and its not too large the mallocs could be avoided.
>
> wa = 2 * tan(M_PI * cutoff_ratio / 2.0);
M_PI * 0.5 * ...
so gcc can multiply the constants out at compile time
>
> for(i = 0; i <= order; i++){
> complex t;
> double th = (i + order/2 + 0.5) * M_PI / order;
>
> t = (cos(th) + I*sin(th)) * wa;
t= cexp(I*th)*wa
> zp[i] = (2.0 + t) / (2.0 - t);
> }
>
> c->cx[0] = 1;
> for(i = 0; i <= order; i++)
> for(j = i; j >= 1; j--)
> c->cx[j] += c->cx[j - 1];
for(i = 1; i <= order; i++)
c->cx[i]= c->cx[i-1]*(order-i+1)/i;
>
> p[0] = 1.0;
> for(i = 1; i <= order; i++)
> p[i] = 0.0;
> for(i = 0; i < order; i++){
> for(j = order; j >= 1; j--)
> p[j] = -zp[i]*p[j] + p[j - 1];
> p[0] *= -zp[i];
> }
this can be merged into the zp generating loop above and the zp array can
be droped
> c->gain = creal(p[order]);
> for(i = 0; i < order; i++){
> complex t = -p[i] / p[order];
> c->gain += creal(p[i]);
> c->cy[i] = creal(t);
t seems like a redundant local varible
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The misfortune of the wise is better than the prosperity of the fool.
-- Epicurus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080825/ffd29552/attachment.pgp>
More information about the ffmpeg-devel
mailing list