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 | if (!tab || !sin_lut) | 155 | if (!tab || !sin_lut) |
| 156 | goto fail; | 156 | goto fail; |
| 157 | 157 | ||
| 158 | av_assert0(tap_count == 1 || tap_count % 2 == 0); | ||
| 159 | |||
| 158 | /* if upsampling, only need to interpolate, no filter */ | 160 | /* if upsampling, only need to interpolate, no filter */ |
| 159 | if (factor > 1.0) | 161 | if (factor > 1.0) |
| 160 | factor = 1.0; | 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 | for(ph = 0; ph < ph_nb; ph++) { | 168 | for(ph = 0; ph < ph_nb; ph++) { |
| 167 | s = sin_lut[ph]; | 169 | s = sin_lut[ph]; |
| 168 | for(i=0;i<=tap_count;i++) { | 170 | for(i=0;i<tap_count;i++) { |
| 169 | x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor; | 171 | x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor; |
| 170 | if (x == 0) y = 1.0; | 172 | if (x == 0) y = 1.0; |
| 171 | else if (factor == 1.0) | 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 | tab[i] = y; | 197 | tab[i] = y; |
| 196 | s = -s; | 198 | s = -s; |
| 197 | if (!ph && i < tap_count) | 199 | if (!ph) |
| 198 | norm += y; | 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 | for(i=0;i<tap_count;i++) | 206 | for(i=0;i<tap_count;i++) |
| 205 | ((int16_t*)filter)[ph * alloc + i] = av_clip_int16(lrintf(tab[i] * scale / norm)); | 207 | ((int16_t*)filter)[ph * alloc + i] = av_clip_int16(lrintf(tab[i] * scale / norm)); |
| 206 | if (phase_count % 2) break; | 208 | if (phase_count % 2) break; |
| 207 | if (tap_count % 2 == 0 || tap_count == 1) { | 209 | for (i = 0; i < tap_count; i++) |
| 208 | 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]; |
| 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 | } | ||
| 216 | break; | 211 | break; |
| 217 | case AV_SAMPLE_FMT_S32P: | 212 | case AV_SAMPLE_FMT_S32P: |
| 218 | for(i=0;i<tap_count;i++) | 213 | for(i=0;i<tap_count;i++) |
| 219 | ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm)); | 214 | ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm)); |
| 220 | if (phase_count % 2) break; | 215 | if (phase_count % 2) break; |
| 221 | if (tap_count % 2 == 0 || tap_count == 1) { | 216 | for (i = 0; i < tap_count; i++) |
| 222 | 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]; |
| 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 | } | ||
| 230 | break; | 218 | break; |
| 231 | case AV_SAMPLE_FMT_FLTP: | 219 | case AV_SAMPLE_FMT_FLTP: |
| 232 | for(i=0;i<tap_count;i++) | 220 | for(i=0;i<tap_count;i++) |
| 233 | ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm; | 221 | ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm; |
| 234 | if (phase_count % 2) break; | 222 | if (phase_count % 2) break; |
| 235 | if (tap_count % 2 == 0 || tap_count == 1) { | 223 | for (i = 0; i < tap_count; i++) |
| 236 | for (i = 0; i < tap_count; i++) | 224 | ((float*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((float*)filter)[ph * alloc + 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 | } | ||
| 243 | break; | 225 | break; |
| 244 | case AV_SAMPLE_FMT_DBLP: | 226 | case AV_SAMPLE_FMT_DBLP: |
| 245 | for(i=0;i<tap_count;i++) | 227 | for(i=0;i<tap_count;i++) |
| 246 | ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm; | 228 | ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm; |
| 247 | if (phase_count % 2) break; | 229 | if (phase_count % 2) break; |
| 248 | if (tap_count % 2 == 0 || tap_count == 1) { | 230 | for (i = 0; i < tap_count; i++) |
| 249 | for (i = 0; i < tap_count; i++) | 231 | ((double*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((double*)filter)[ph * alloc + 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 | } | ||
| 256 | break; | 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 | double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); | 284 | double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); |
| 309 | int phase_count= 1<<phase_shift; | 285 | int phase_count= 1<<phase_shift; |
| 310 | int phase_count_compensation = phase_count; | 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 | if (exact_rational) { | 292 | if (exact_rational) { |
| 313 | int phase_count_exact, phase_count_exact_den; | 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 | if (!c || c->phase_count != phase_count || c->linear!=linear || c->factor != factor | 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 | || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) { | 304 | || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) { |
| 325 | c = av_mallocz(sizeof(*c)); | 305 | c = av_mallocz(sizeof(*c)); |
| 326 | if (!c) | 306 | if (!c) |
| @@ -354,7 +334,7 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r · 27 unmodified lines | |||
| 354 | c->phase_count = phase_count; | 334 | c->phase_count = phase_count; |
| 355 | c->linear = linear; | 335 | c->linear = linear; |
| 356 | c->factor = factor; | 336 | c->factor = factor; |
| 357 | c->filter_length = FFMAX((int)ceil(filter_size/factor), 1); | 337 | c->filter_length = filter_length; |
| 358 | c->filter_alloc = FFALIGN(c->filter_length, 8); | 338 | c->filter_alloc = FFALIGN(c->filter_length, 8); |
| 359 | c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size); | 339 | c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size); |
| 360 | c->filter_type = filter_type; | 340 | c->filter_type = filter_type; |