Add function ff_iir_filter_flt() to accept floating-point input and output.
Signed-off-by: Mans Rullgard <mans@mansr.com> (cherry picked from commit 0a3d7697b4fcb62305cd4a893b621a406a029ff0)
This commit is contained in:
parent
236bb68d76
commit
b3b8b930fc
@ -118,48 +118,74 @@ av_cold struct FFIIRFilterState* ff_iir_filter_init_state(int order)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FILTER(i0, i1, i2, i3) \
|
#define CONV_S16(dest, source) dest = av_clip_int16(lrintf(source));
|
||||||
in = *src * c->gain \
|
|
||||||
+ c->cy[0]*s->x[i0] + c->cy[1]*s->x[i1] \
|
#define CONV_FLT(dest, source) dest = source;
|
||||||
+ c->cy[2]*s->x[i2] + c->cy[3]*s->x[i3]; \
|
|
||||||
res = (s->x[i0] + in )*1 \
|
#define FILTER_BW_O4_1(i0, i1, i2, i3, fmt) \
|
||||||
+ (s->x[i1] + s->x[i3])*4 \
|
in = *src0 * c->gain \
|
||||||
+ s->x[i2] *6; \
|
+ c->cy[0]*s->x[i0] + c->cy[1]*s->x[i1] \
|
||||||
*dst = av_clip_int16(lrintf(res)); \
|
+ c->cy[2]*s->x[i2] + c->cy[3]*s->x[i3]; \
|
||||||
s->x[i0] = in; \
|
res = (s->x[i0] + in )*1 \
|
||||||
src += sstep; \
|
+ (s->x[i1] + s->x[i3])*4 \
|
||||||
dst += dstep; \
|
+ s->x[i2] *6; \
|
||||||
|
CONV_##fmt(*dst0, res) \
|
||||||
|
s->x[i0] = in; \
|
||||||
|
src0 += sstep; \
|
||||||
|
dst0 += dstep;
|
||||||
|
|
||||||
|
#define FILTER_BW_O4(type, fmt) { \
|
||||||
|
int i; \
|
||||||
|
const type *src0 = src; \
|
||||||
|
type *dst0 = dst; \
|
||||||
|
for (i = 0; i < size; i += 4) { \
|
||||||
|
float in, res; \
|
||||||
|
FILTER_BW_O4_1(0, 1, 2, 3, fmt); \
|
||||||
|
FILTER_BW_O4_1(1, 2, 3, 0, fmt); \
|
||||||
|
FILTER_BW_O4_1(2, 3, 0, 1, fmt); \
|
||||||
|
FILTER_BW_O4_1(3, 0, 1, 2, fmt); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FILTER_DIRECT_FORM_II(type, fmt) { \
|
||||||
|
int i; \
|
||||||
|
const type *src0 = src; \
|
||||||
|
type *dst0 = dst; \
|
||||||
|
for (i = 0; i < size; i++) { \
|
||||||
|
int j; \
|
||||||
|
float in, res; \
|
||||||
|
in = *src0 * c->gain; \
|
||||||
|
for(j = 0; j < c->order; j++) \
|
||||||
|
in += c->cy[j] * s->x[j]; \
|
||||||
|
res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1]; \
|
||||||
|
for(j = 1; j < c->order >> 1; j++) \
|
||||||
|
res += (s->x[j] + s->x[c->order - j]) * c->cx[j]; \
|
||||||
|
for(j = 0; j < c->order - 1; j++) \
|
||||||
|
s->x[j] = s->x[j + 1]; \
|
||||||
|
CONV_##fmt(*dst0, res) \
|
||||||
|
s->x[c->order - 1] = in; \
|
||||||
|
src0 += sstep; \
|
||||||
|
dst0 += dstep; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
void ff_iir_filter(const struct FFIIRFilterCoeffs *c, struct FFIIRFilterState *s, int size, const int16_t *src, int sstep, int16_t *dst, int dstep)
|
void ff_iir_filter(const struct FFIIRFilterCoeffs *c, struct FFIIRFilterState *s, int size, const int16_t *src, int sstep, int16_t *dst, int dstep)
|
||||||
{
|
{
|
||||||
int i;
|
if (c->order == 4) {
|
||||||
|
FILTER_BW_O4(int16_t, S16)
|
||||||
|
} else {
|
||||||
|
FILTER_DIRECT_FORM_II(int16_t, S16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(c->order == 4){
|
void ff_iir_filter_flt(const struct FFIIRFilterCoeffs *c,
|
||||||
for(i = 0; i < size; i += 4){
|
struct FFIIRFilterState *s, int size,
|
||||||
float in, res;
|
const float *src, int sstep, void *dst, int dstep)
|
||||||
|
{
|
||||||
FILTER(0, 1, 2, 3);
|
if (c->order == 4) {
|
||||||
FILTER(1, 2, 3, 0);
|
FILTER_BW_O4(float, FLT)
|
||||||
FILTER(2, 3, 0, 1);
|
} else {
|
||||||
FILTER(3, 0, 1, 2);
|
FILTER_DIRECT_FORM_II(float, FLT)
|
||||||
}
|
|
||||||
}else{
|
|
||||||
for(i = 0; i < size; i++){
|
|
||||||
int j;
|
|
||||||
float in, res;
|
|
||||||
in = *src * c->gain;
|
|
||||||
for(j = 0; j < c->order; j++)
|
|
||||||
in += c->cy[j] * s->x[j];
|
|
||||||
res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1];
|
|
||||||
for(j = 1; j < c->order >> 1; j++)
|
|
||||||
res += (s->x[j] + s->x[c->order - j]) * c->cx[j];
|
|
||||||
for(j = 0; j < c->order - 1; j++)
|
|
||||||
s->x[j] = s->x[j + 1];
|
|
||||||
*dst = av_clip_int16(lrintf(res));
|
|
||||||
s->x[c->order - 1] = in;
|
|
||||||
src += sstep;
|
|
||||||
dst += dstep;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs *coeffs);
|
|||||||
void ff_iir_filter_free_state(struct FFIIRFilterState *state);
|
void ff_iir_filter_free_state(struct FFIIRFilterState *state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform lowpass filtering on input samples.
|
* Perform IIR filtering on signed 16-bit input samples.
|
||||||
*
|
*
|
||||||
* @param coeffs pointer to filter coefficients
|
* @param coeffs pointer to filter coefficients
|
||||||
* @param state pointer to filter state
|
* @param state pointer to filter state
|
||||||
@ -100,4 +100,19 @@ void ff_iir_filter_free_state(struct FFIIRFilterState *state);
|
|||||||
void ff_iir_filter(const struct FFIIRFilterCoeffs *coeffs, struct FFIIRFilterState *state,
|
void ff_iir_filter(const struct FFIIRFilterCoeffs *coeffs, struct FFIIRFilterState *state,
|
||||||
int size, const int16_t *src, int sstep, int16_t *dst, int dstep);
|
int size, const int16_t *src, int sstep, int16_t *dst, int dstep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform IIR filtering on floating-point 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_iir_filter_flt(const struct FFIIRFilterCoeffs *coeffs,
|
||||||
|
struct FFIIRFilterState *state, int size,
|
||||||
|
const float *src, int sstep, void *dst, int dstep);
|
||||||
|
|
||||||
#endif /* AVCODEC_IIRFILTER_H */
|
#endif /* AVCODEC_IIRFILTER_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user