except filter_length == 1 odd filter_length gives worse frequency response, even when compared with shorter filter_length also makes build_filter simpler
Showing the changes to libswresample (1 of 2 files). Show all
Unified · Split
| @@ -155,6 +155,8 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap · 154 unmodified lines | ||
| 155 | 155 | if (!tab || !sin_lut) |
| 156 | 156 | goto fail; |
| 157 | 157 | |
| 158 | + av_assert0(tap_count == 1 || tap_count % 2 == 0); | |
| 159 | + | |
| 158 | 160 | /* if upsampling, only need to interpolate, no filter */ |
| 159 | 161 | if (factor > 1.0) |
| 160 | 162 | factor = 1.0; |
| @@ -165,7 +167,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap · 4 unmodified lines | ||
| 165 | 167 | } |
| 166 | 168 | for(ph = 0; ph < ph_nb; ph++) { |
| 167 | 169 | s = sin_lut[ph]; |
| 168 | − for(i=0;i<=tap_count;i++) { | |
| 170 | + for(i=0;i<tap_count;i++) { | |
| 169 | 171 | x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor; |
| 170 | 172 | if (x == 0) y = 1.0; |
| 171 | 173 | else if (factor == 1.0) |
| @@ -194,7 +196,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap · 22 unmodified lines | ||
| 194 | 196 | |
| 195 | 197 | tab[i] = y; |
| 196 | 198 | s = -s; |
| 197 | − if (!ph && i < tap_count) | |
| 199 | + if (!ph) | |
| 198 | 200 | norm += y; |
| 199 | 201 | } |
| 200 | 202 | |
| @@ -204,55 +206,29 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap · 3 unmodified lines | ||
| 204 | 206 | for(i=0;i<tap_count;i++) |
| 205 | 207 | ((int16_t*)filter)[ph * alloc + i] = av_clip_int16(lrintf(tab[i] * scale / norm)); |
| 206 | 208 | if (phase_count % 2) break; |
| 207 | − if (tap_count % 2 == 0 || tap_count == 1) { | |
| 208 | − for (i = 0; i < tap_count; i++) | |
| 209 | − ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int16_t*)filter)[ph * alloc + i]; | |
| 210 | − } | |
| 211 | − else { | |
| 212 | − for (i = 1; i <= tap_count; i++) | |
| 213 | − ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = | |
| 214 | − av_clip_int16(lrintf(tab[i] * scale / norm)); | |
| 215 | − } | |
| 209 | + for (i = 0; i < tap_count; i++) | |
| 210 | + ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int16_t*)filter)[ph * alloc + i]; | |
| 216 | 211 | break; |
| 217 | 212 | case AV_SAMPLE_FMT_S32P: |
| 218 | 213 | for(i=0;i<tap_count;i++) |
| 219 | 214 | ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm)); |
| 220 | 215 | if (phase_count % 2) break; |
| 221 | − if (tap_count % 2 == 0 || tap_count == 1) { | |
| 222 | − for (i = 0; i < tap_count; i++) | |
| 223 | − ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int32_t*)filter)[ph * alloc + i]; | |
| 224 | − } | |
| 225 | − else { | |
| 226 | − for (i = 1; i <= tap_count; i++) | |
| 227 | − ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = | |
| 228 | − av_clipl_int32(llrint(tab[i] * scale / norm)); | |
| 229 | − } | |
| 216 | + for (i = 0; i < tap_count; i++) | |
| 217 | + ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int32_t*)filter)[ph * alloc + i]; | |
| 230 | 218 | break; |
| 231 | 219 | case AV_SAMPLE_FMT_FLTP: |
| 232 | 220 | for(i=0;i<tap_count;i++) |
| 233 | 221 | ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm; |
| 234 | 222 | if (phase_count % 2) break; |
| 235 | − if (tap_count % 2 == 0 || tap_count == 1) { | |
| 236 | − for (i = 0; i < tap_count; i++) | |
| 237 | − ((float*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((float*)filter)[ph * alloc + i]; | |
| 238 | − } | |
| 239 | − else { | |
| 240 | − for (i = 1; i <= tap_count; i++) | |
| 241 | − ((float*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / norm; | |
| 242 | − } | |
| 223 | + for (i = 0; i < tap_count; i++) | |
| 224 | + ((float*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((float*)filter)[ph * alloc + i]; | |
| 243 | 225 | break; |
| 244 | 226 | case AV_SAMPLE_FMT_DBLP: |
| 245 | 227 | for(i=0;i<tap_count;i++) |
| 246 | 228 | ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm; |
| 247 | 229 | if (phase_count % 2) break; |
| 248 | − if (tap_count % 2 == 0 || tap_count == 1) { | |
| 249 | − for (i = 0; i < tap_count; i++) | |
| 250 | − ((double*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((double*)filter)[ph * alloc + i]; | |
| 251 | − } | |
| 252 | − else { | |
| 253 | − for (i = 1; i <= tap_count; i++) | |
| 254 | − ((double*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / norm; | |
| 255 | − } | |
| 230 | + for (i = 0; i < tap_count; i++) | |
| 231 | + ((double*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((double*)filter)[ph * alloc + i]; | |
| 256 | 232 | break; |
| 257 | 233 | } |
| 258 | 234 | } |
| @@ -308,6 +284,10 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r · 49 unmodified lines | ||
| 308 | 284 | double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); |
| 309 | 285 | int phase_count= 1<<phase_shift; |
| 310 | 286 | int phase_count_compensation = phase_count; |
| 287 | + int filter_length = FFMAX((int)ceil(filter_size/factor), 1); | |
| 288 | + | |
| 289 | + if (filter_length > 1) | |
| 290 | + filter_length = FFALIGN(filter_length, 2); | |
| 311 | 291 | |
| 312 | 292 | if (exact_rational) { |
| 313 | 293 | int phase_count_exact, phase_count_exact_den; |
| @@ -320,7 +300,7 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r · 6 unmodified lines | ||
| 320 | 300 | } |
| 321 | 301 | |
| 322 | 302 | if (!c || c->phase_count != phase_count || c->linear!=linear || c->factor != factor |
| 323 | − || c->filter_length != FFMAX((int)ceil(filter_size/factor), 1) || c->format != format | |
| 303 | + || c->filter_length != filter_length || c->format != format | |
| 324 | 304 | || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) { |
| 325 | 305 | c = av_mallocz(sizeof(*c)); |
| 326 | 306 | if (!c) |
| @@ -354,7 +334,7 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r · 27 unmodified lines | ||
| 354 | 334 | c->phase_count = phase_count; |
| 355 | 335 | c->linear = linear; |
| 356 | 336 | c->factor = factor; |
| 357 | − c->filter_length = FFMAX((int)ceil(filter_size/factor), 1); | |
| 337 | + c->filter_length = filter_length; | |
| 358 | 338 | c->filter_alloc = FFALIGN(c->filter_length, 8); |
| 359 | 339 | c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size); |
| 360 | 340 | c->filter_type = filter_type; |