118 |
118 |
return s;
|
119 |
119 |
}
|
120 |
120 |
|
121 |
|
#define FILTER(i0, i1, i2, i3) \
|
122 |
|
in = *src * c->gain \
|
123 |
|
+ c->cy[0]*s->x[i0] + c->cy[1]*s->x[i1] \
|
124 |
|
+ c->cy[2]*s->x[i2] + c->cy[3]*s->x[i3]; \
|
125 |
|
res = (s->x[i0] + in )*1 \
|
126 |
|
+ (s->x[i1] + s->x[i3])*4 \
|
127 |
|
+ s->x[i2] *6; \
|
128 |
|
*dst = av_clip_int16(lrintf(res)); \
|
129 |
|
s->x[i0] = in; \
|
130 |
|
src += sstep; \
|
131 |
|
dst += dstep; \
|
|
121 |
#define CONV_S16(dest, source) dest = av_clip_int16(lrintf(source));
|
|
122 |
|
|
123 |
#define CONV_FLT(dest, source) dest = source;
|
|
124 |
|
|
125 |
#define FILTER_BW_O4_1(i0, i1, i2, i3, fmt) \
|
|
126 |
in = *src0 * c->gain \
|
|
127 |
+ c->cy[0]*s->x[i0] + c->cy[1]*s->x[i1] \
|
|
128 |
+ c->cy[2]*s->x[i2] + c->cy[3]*s->x[i3]; \
|
|
129 |
res = (s->x[i0] + in )*1 \
|
|
130 |
+ (s->x[i1] + s->x[i3])*4 \
|
|
131 |
+ s->x[i2] *6; \
|
|
132 |
CONV_##fmt(*dst0, res) \
|
|
133 |
s->x[i0] = in; \
|
|
134 |
src0 += sstep; \
|
|
135 |
dst0 += dstep;
|
|
136 |
|
|
137 |
#define FILTER_BW_O4(type, fmt) { \
|
|
138 |
int i; \
|
|
139 |
const type *src0 = src; \
|
|
140 |
type *dst0 = dst; \
|
|
141 |
for (i = 0; i < size; i += 4) { \
|
|
142 |
float in, res; \
|
|
143 |
FILTER_BW_O4_1(0, 1, 2, 3, fmt); \
|
|
144 |
FILTER_BW_O4_1(1, 2, 3, 0, fmt); \
|
|
145 |
FILTER_BW_O4_1(2, 3, 0, 1, fmt); \
|
|
146 |
FILTER_BW_O4_1(3, 0, 1, 2, fmt); \
|
|
147 |
} \
|
|
148 |
}
|
|
149 |
|
|
150 |
#define FILTER_DIRECT_FORM_II(type, fmt) { \
|
|
151 |
int i; \
|
|
152 |
const type *src0 = src; \
|
|
153 |
type *dst0 = dst; \
|
|
154 |
for (i = 0; i < size; i++) { \
|
|
155 |
int j; \
|
|
156 |
float in, res; \
|
|
157 |
in = *src0 * c->gain; \
|
|
158 |
for(j = 0; j < c->order; j++) \
|
|
159 |
in += c->cy[j] * s->x[j]; \
|
|
160 |
res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1]; \
|
|
161 |
for(j = 1; j < c->order >> 1; j++) \
|
|
162 |
res += (s->x[j] + s->x[c->order - j]) * c->cx[j]; \
|
|
163 |
for(j = 0; j < c->order - 1; j++) \
|
|
164 |
s->x[j] = s->x[j + 1]; \
|
|
165 |
CONV_##fmt(*dst0, res) \
|
|
166 |
s->x[c->order - 1] = in; \
|
|
167 |
src0 += sstep; \
|
|
168 |
dst0 += dstep; \
|
|
169 |
} \
|
|
170 |
}
|
132 |
171 |
|
133 |
172 |
void ff_iir_filter(const struct FFIIRFilterCoeffs *c, struct FFIIRFilterState *s, int size, const int16_t *src, int sstep, int16_t *dst, int dstep)
|
134 |
173 |
{
|
135 |
|
int i;
|
136 |
|
|
137 |
|
if(c->order == 4){
|
138 |
|
for(i = 0; i < size; i += 4){
|
139 |
|
float in, res;
|
|
174 |
if (c->order == 4) {
|
|
175 |
FILTER_BW_O4(int16_t, S16)
|
|
176 |
} else {
|
|
177 |
FILTER_DIRECT_FORM_II(int16_t, S16)
|
|
178 |
}
|
|
179 |
}
|
140 |
180 |
|
141 |
|
FILTER(0, 1, 2, 3);
|
142 |
|
FILTER(1, 2, 3, 0);
|
143 |
|
FILTER(2, 3, 0, 1);
|
144 |
|
FILTER(3, 0, 1, 2);
|
145 |
|
}
|
146 |
|
}else{
|
147 |
|
for(i = 0; i < size; i++){
|
148 |
|
int j;
|
149 |
|
float in, res;
|
150 |
|
in = *src * c->gain;
|
151 |
|
for(j = 0; j < c->order; j++)
|
152 |
|
in += c->cy[j] * s->x[j];
|
153 |
|
res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1];
|
154 |
|
for(j = 1; j < c->order >> 1; j++)
|
155 |
|
res += (s->x[j] + s->x[c->order - j]) * c->cx[j];
|
156 |
|
for(j = 0; j < c->order - 1; j++)
|
157 |
|
s->x[j] = s->x[j + 1];
|
158 |
|
*dst = av_clip_int16(lrintf(res));
|
159 |
|
s->x[c->order - 1] = in;
|
160 |
|
src += sstep;
|
161 |
|
dst += dstep;
|
162 |
|
}
|
|
181 |
void ff_iir_filter_flt(const struct FFIIRFilterCoeffs *c,
|
|
182 |
struct FFIIRFilterState *s, int size,
|
|
183 |
const float *src, int sstep, void *dst, int dstep)
|
|
184 |
{
|
|
185 |
if (c->order == 4) {
|
|
186 |
FILTER_BW_O4(float, FLT)
|
|
187 |
} else {
|
|
188 |
FILTER_DIRECT_FORM_II(float, FLT)
|
163 |
189 |
}
|
164 |
190 |
}
|
165 |
191 |
|