mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-28 14:01:27 +00:00
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 0a3d7697b4
)
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;
|
||||
}
|
||||
|
||||
#define FILTER(i0, i1, i2, i3) \
|
||||
in = *src * c->gain \
|
||||
#define CONV_S16(dest, source) dest = av_clip_int16(lrintf(source));
|
||||
|
||||
#define CONV_FLT(dest, source) dest = source;
|
||||
|
||||
#define FILTER_BW_O4_1(i0, i1, i2, i3, fmt) \
|
||||
in = *src0 * c->gain \
|
||||
+ c->cy[0]*s->x[i0] + c->cy[1]*s->x[i1] \
|
||||
+ c->cy[2]*s->x[i2] + c->cy[3]*s->x[i3]; \
|
||||
res = (s->x[i0] + in )*1 \
|
||||
+ (s->x[i1] + s->x[i3])*4 \
|
||||
+ s->x[i2] *6; \
|
||||
*dst = av_clip_int16(lrintf(res)); \
|
||||
CONV_##fmt(*dst0, res) \
|
||||
s->x[i0] = in; \
|
||||
src += sstep; \
|
||||
dst += dstep; \
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(c->order == 4){
|
||||
for(i = 0; i < size; i += 4){
|
||||
float in, res;
|
||||
|
||||
FILTER(0, 1, 2, 3);
|
||||
FILTER(1, 2, 3, 0);
|
||||
FILTER(2, 3, 0, 1);
|
||||
FILTER(3, 0, 1, 2);
|
||||
}
|
||||
}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;
|
||||
if (c->order == 4) {
|
||||
FILTER_BW_O4(int16_t, S16)
|
||||
} else {
|
||||
FILTER_DIRECT_FORM_II(int16_t, S16)
|
||||
}
|
||||
}
|
||||
|
||||
void ff_iir_filter_flt(const struct FFIIRFilterCoeffs *c,
|
||||
struct FFIIRFilterState *s, int size,
|
||||
const float *src, int sstep, void *dst, int dstep)
|
||||
{
|
||||
if (c->order == 4) {
|
||||
FILTER_BW_O4(float, FLT)
|
||||
} else {
|
||||
FILTER_DIRECT_FORM_II(float, FLT)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs *coeffs);
|
||||
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 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,
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user