Showing the changes to src (1 of 2 files). Show all
Unified · Split
| @@ -68,9 +68,8 @@ typedef struct · 67 unmodified lines | ||
| 68 | 68 | float buffer [1] ; |
| 69 | 69 | } SINC_FILTER ; |
| 70 | 70 | |
| 71 | −static int sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; | |
| 72 | − | |
| 73 | −static double calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) ; | |
| 71 | +static int sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; | |
| 72 | +static int sinc_1chan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; | |
| 74 | 73 | |
| 75 | 74 | static void prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) ; |
| 76 | 75 | |
| @@ -167,8 +166,14 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum) · 90 unmodified lines | ||
| 167 | 166 | temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ; |
| 168 | 167 | temp_filter.channels = psrc->channels ; |
| 169 | 168 | |
| 170 | − psrc->const_process = sinc_vari_process ; | |
| 171 | − psrc->vari_process = sinc_vari_process ; | |
| 169 | + if (psrc->channels == 1) | |
| 170 | + { psrc->const_process = sinc_1chan_vari_process ; | |
| 171 | + psrc->vari_process = sinc_1chan_vari_process ; | |
| 172 | + } | |
| 173 | + else | |
| 174 | + { psrc->const_process = sinc_multichan_vari_process ; | |
| 175 | + psrc->vari_process = sinc_multichan_vari_process ; | |
| 176 | + } ; | |
| 172 | 177 | psrc->reset = sinc_reset ; |
| 173 | 178 | |
| 174 | 179 | switch (src_enum) |
| @@ -246,8 +251,205 @@ sinc_reset (SRC_PRIVATE *psrc) · 71 unmodified lines | ||
| 246 | 251 | ** Beware all ye who dare pass this point. There be dragons here. |
| 247 | 252 | */ |
| 248 | 253 | |
| 254 | +static inline double | |
| 255 | +calc_output_single (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index) | |
| 256 | +{ double fraction, left, right, icoeff ; | |
| 257 | + increment_t filter_index, max_filter_index ; | |
| 258 | + int data_index, coeff_count, indx ; | |
| 259 | + | |
| 260 | + /* Convert input parameters into fixed point. */ | |
| 261 | + max_filter_index = int_to_fp (filter->coeff_half_len) ; | |
| 262 | + | |
| 263 | + /* First apply the left half of the filter. */ | |
| 264 | + filter_index = start_filter_index ; | |
| 265 | + coeff_count = (max_filter_index - filter_index) / increment ; | |
| 266 | + filter_index = filter_index + coeff_count * increment ; | |
| 267 | + data_index = filter->b_current - coeff_count ; | |
| 268 | + | |
| 269 | + left = 0.0 ; | |
| 270 | + do | |
| 271 | + { fraction = fp_to_double (filter_index) ; | |
| 272 | + indx = fp_to_int (filter_index) ; | |
| 273 | + | |
| 274 | + icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | |
| 275 | + | |
| 276 | + left += icoeff * filter->buffer [data_index] ; | |
| 277 | + | |
| 278 | + filter_index -= increment ; | |
| 279 | + data_index = data_index + 1 ; | |
| 280 | + } | |
| 281 | + while (filter_index >= MAKE_INCREMENT_T (0)) ; | |
| 282 | + | |
| 283 | + /* Now apply the right half of the filter. */ | |
| 284 | + filter_index = increment - start_filter_index ; | |
| 285 | + coeff_count = (max_filter_index - filter_index) / increment ; | |
| 286 | + filter_index = filter_index + coeff_count * increment ; | |
| 287 | + data_index = filter->b_current + 1 + coeff_count ; | |
| 288 | + | |
| 289 | + right = 0.0 ; | |
| 290 | + do | |
| 291 | + { fraction = fp_to_double (filter_index) ; | |
| 292 | + indx = fp_to_int (filter_index) ; | |
| 293 | + | |
| 294 | + icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | |
| 295 | + | |
| 296 | + right += icoeff * filter->buffer [data_index] ; | |
| 297 | + | |
| 298 | + filter_index -= increment ; | |
| 299 | + data_index = data_index - 1 ; | |
| 300 | + } | |
| 301 | + while (filter_index > MAKE_INCREMENT_T (0)) ; | |
| 302 | + | |
| 303 | + return (left + right) ; | |
| 304 | +} /* calc_output_single */ | |
| 305 | + | |
| 306 | +static inline double | |
| 307 | +calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) | |
| 308 | +{ double fraction, left, right, icoeff ; | |
| 309 | + increment_t filter_index, max_filter_index ; | |
| 310 | + int data_index, coeff_count, indx ; | |
| 311 | + | |
| 312 | + /* Convert input parameters into fixed point. */ | |
| 313 | + max_filter_index = int_to_fp (filter->coeff_half_len) ; | |
| 314 | + | |
| 315 | + /* First apply the left half of the filter. */ | |
| 316 | + filter_index = start_filter_index ; | |
| 317 | + coeff_count = (max_filter_index - filter_index) / increment ; | |
| 318 | + filter_index = filter_index + coeff_count * increment ; | |
| 319 | + data_index = filter->b_current - filter->channels * coeff_count + ch ; | |
| 320 | + | |
| 321 | + left = 0.0 ; | |
| 322 | + do | |
| 323 | + { fraction = fp_to_double (filter_index) ; | |
| 324 | + indx = fp_to_int (filter_index) ; | |
| 325 | + | |
| 326 | + icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | |
| 327 | + | |
| 328 | + left += icoeff * filter->buffer [data_index] ; | |
| 329 | + | |
| 330 | + filter_index -= increment ; | |
| 331 | + data_index = data_index + filter->channels ; | |
| 332 | + } | |
| 333 | + while (filter_index >= MAKE_INCREMENT_T (0)) ; | |
| 334 | + | |
| 335 | + /* Now apply the right half of the filter. */ | |
| 336 | + filter_index = increment - start_filter_index ; | |
| 337 | + coeff_count = (max_filter_index - filter_index) / increment ; | |
| 338 | + filter_index = filter_index + coeff_count * increment ; | |
| 339 | + data_index = filter->b_current + filter->channels * (1 + coeff_count) + ch ; | |
| 340 | + | |
| 341 | + right = 0.0 ; | |
| 342 | + do | |
| 343 | + { fraction = fp_to_double (filter_index) ; | |
| 344 | + indx = fp_to_int (filter_index) ; | |
| 345 | + | |
| 346 | + icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | |
| 347 | + | |
| 348 | + right += icoeff * filter->buffer [data_index] ; | |
| 349 | + | |
| 350 | + filter_index -= increment ; | |
| 351 | + data_index = data_index - filter->channels ; | |
| 352 | + } | |
| 353 | + while (filter_index > MAKE_INCREMENT_T (0)) ; | |
| 354 | + | |
| 355 | + return (left + right) ; | |
| 356 | +} /* calc_output_multi */ | |
| 357 | + | |
| 358 | +static int | |
| 359 | +sinc_1chan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) | |
| 360 | +{ SINC_FILTER *filter ; | |
| 361 | + double input_index, src_ratio, count, float_increment, terminate, rem ; | |
| 362 | + increment_t increment, start_filter_index ; | |
| 363 | + int half_filter_chan_len, samples_in_hand ; | |
| 364 | + | |
| 365 | + if (psrc->private_data == NULL) | |
| 366 | + return SRC_ERR_NO_PRIVATE ; | |
| 367 | + | |
| 368 | + filter = (SINC_FILTER*) psrc->private_data ; | |
| 369 | + | |
| 370 | + /* If there is not a problem, this will be optimised out. */ | |
| 371 | + if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) | |
| 372 | + return SRC_ERR_SIZE_INCOMPATIBILITY ; | |
| 373 | + | |
| 374 | + filter->in_count = data->input_frames * filter->channels ; | |
| 375 | + filter->out_count = data->output_frames * filter->channels ; | |
| 376 | + filter->in_used = filter->out_gen = 0 ; | |
| 377 | + | |
| 378 | + src_ratio = psrc->last_ratio ; | |
| 379 | + | |
| 380 | + /* Check the sample rate ratio wrt the buffer len. */ | |
| 381 | + count = (filter->coeff_half_len + 2.0) / filter->index_inc ; | |
| 382 | + if (MIN (psrc->last_ratio, data->src_ratio) < 1.0) | |
| 383 | + count /= MIN (psrc->last_ratio, data->src_ratio) ; | |
| 384 | + | |
| 385 | + /* Maximum coefficientson either side of center point. */ | |
| 386 | + half_filter_chan_len = filter->channels * (lrint (count) + 1) ; | |
| 387 | + | |
| 388 | + input_index = psrc->last_position ; | |
| 389 | + float_increment = filter->index_inc ; | |
| 390 | + | |
| 391 | + rem = fmod_one (input_index) ; | |
| 392 | + filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; | |
| 393 | + input_index = rem ; | |
| 394 | + | |
| 395 | + terminate = 1.0 / src_ratio + 1e-20 ; | |
| 396 | + | |
| 397 | + /* Main processing loop. */ | |
| 398 | + while (filter->out_gen < filter->out_count) | |
| 399 | + { | |
| 400 | + /* Need to reload buffer? */ | |
| 401 | + samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; | |
| 402 | + | |
| 403 | + if (samples_in_hand <= half_filter_chan_len) | |
| 404 | + { prepare_data (filter, data, half_filter_chan_len) ; | |
| 405 | + | |
| 406 | + samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; | |
| 407 | + if (samples_in_hand <= half_filter_chan_len) | |
| 408 | + break ; | |
| 409 | + } ; | |
| 410 | + | |
| 411 | + /* This is the termination condition. */ | |
| 412 | + if (filter->b_real_end >= 0) | |
| 413 | + { if (filter->b_current + input_index + terminate >= filter->b_real_end) | |
| 414 | + break ; | |
| 415 | + } ; | |
| 416 | + | |
| 417 | + if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10) | |
| 418 | + src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ; | |
| 419 | + | |
| 420 | + float_increment = filter->index_inc * 1.0 ; | |
| 421 | + if (src_ratio < 1.0) | |
| 422 | + float_increment = filter->index_inc * src_ratio ; | |
| 423 | + | |
| 424 | + increment = double_to_fp (float_increment) ; | |
| 425 | + | |
| 426 | + start_filter_index = double_to_fp (input_index * float_increment) ; | |
| 427 | + | |
| 428 | + data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) * | |
| 429 | + calc_output_single (filter, increment, start_filter_index)) ; | |
| 430 | + filter->out_gen ++ ; | |
| 431 | + | |
| 432 | + /* Figure out the next index. */ | |
| 433 | + input_index += 1.0 / src_ratio ; | |
| 434 | + rem = fmod_one (input_index) ; | |
| 435 | + | |
| 436 | + filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; | |
| 437 | + input_index = rem ; | |
| 438 | + } ; | |
| 439 | + | |
| 440 | + psrc->last_position = input_index ; | |
| 441 | + | |
| 442 | + /* Save current ratio rather then target ratio. */ | |
| 443 | + psrc->last_ratio = src_ratio ; | |
| 444 | + | |
| 445 | + data->input_frames_used = filter->in_used / filter->channels ; | |
| 446 | + data->output_frames_gen = filter->out_gen / filter->channels ; | |
| 447 | + | |
| 448 | + return SRC_ERR_NO_ERROR ; | |
| 449 | +} /* sinc_1chan_vari_process */ | |
| 450 | + | |
| 249 | 451 | static int |
| 250 | −sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) | |
| 452 | +sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) | |
| 251 | 453 | { SINC_FILTER *filter ; |
| 252 | 454 | double input_index, src_ratio, count, float_increment, terminate, rem ; |
| 253 | 455 | increment_t increment, start_filter_index ; |
| @@ -318,7 +520,7 @@ sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) · 64 unmodified lines | ||
| 318 | 520 | |
| 319 | 521 | for (ch = 0 ; ch < filter->channels ; ch++) |
| 320 | 522 | { data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) * |
| 321 | − calc_output (filter, increment, start_filter_index, ch)) ; | |
| 523 | + calc_output_multi (filter, increment, start_filter_index, ch)) ; | |
| 322 | 524 | filter->out_gen ++ ; |
| 323 | 525 | } ; |
| 324 | 526 | |
| @@ -339,7 +541,7 @@ sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) · 14 unmodified lines | ||
| 339 | 541 | data->output_frames_gen = filter->out_gen / filter->channels ; |
| 340 | 542 | |
| 341 | 543 | return SRC_ERR_NO_ERROR ; |
| 342 | −} /* sinc_vari_process */ | |
| 544 | +} /* sinc_multichan_vari_process */ | |
| 343 | 545 | |
| 344 | 546 | /*---------------------------------------------------------------------------------------- |
| 345 | 547 | */ |
| @@ -412,55 +614,3 @@ prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) · 66 unmodified lines | ||
| 412 | 614 | } /* prepare_data */ |
| 413 | 615 | |
| 414 | 616 | |
| 415 | −static double | |
| 416 | −calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) | |
| 417 | −{ double fraction, left, right, icoeff ; | |
| 418 | − increment_t filter_index, max_filter_index ; | |
| 419 | − int data_index, coeff_count, indx ; | |
| 420 | − | |
| 421 | − /* Convert input parameters into fixed point. */ | |
| 422 | − max_filter_index = int_to_fp (filter->coeff_half_len) ; | |
| 423 | − | |
| 424 | − /* First apply the left half of the filter. */ | |
| 425 | − filter_index = start_filter_index ; | |
| 426 | − coeff_count = (max_filter_index - filter_index) / increment ; | |
| 427 | − filter_index = filter_index + coeff_count * increment ; | |
| 428 | − data_index = filter->b_current - filter->channels * coeff_count + ch ; | |
| 429 | − | |
| 430 | − left = 0.0 ; | |
| 431 | − do | |
| 432 | − { fraction = fp_to_double (filter_index) ; | |
| 433 | − indx = fp_to_int (filter_index) ; | |
| 434 | − | |
| 435 | − icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | |
| 436 | − | |
| 437 | − left += icoeff * filter->buffer [data_index] ; | |
| 438 | − | |
| 439 | − filter_index -= increment ; | |
| 440 | − data_index = data_index + filter->channels ; | |
| 441 | − } | |
| 442 | − while (filter_index >= MAKE_INCREMENT_T (0)) ; | |
| 443 | − | |
| 444 | − /* Now apply the right half of the filter. */ | |
| 445 | − filter_index = increment - start_filter_index ; | |
| 446 | − coeff_count = (max_filter_index - filter_index) / increment ; | |
| 447 | − filter_index = filter_index + coeff_count * increment ; | |
| 448 | − data_index = filter->b_current + filter->channels * (1 + coeff_count) + ch ; | |
| 449 | − | |
| 450 | − right = 0.0 ; | |
| 451 | − do | |
| 452 | − { fraction = fp_to_double (filter_index) ; | |
| 453 | − indx = fp_to_int (filter_index) ; | |
| 454 | − | |
| 455 | − icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | |
| 456 | − | |
| 457 | − right += icoeff * filter->buffer [data_index] ; | |
| 458 | − | |
| 459 | − filter_index -= increment ; | |
| 460 | − data_index = data_index - filter->channels ; | |
| 461 | − } | |
| 462 | − while (filter_index > MAKE_INCREMENT_T (0)) ; | |
| 463 | − | |
| 464 | − return (left + right) ; | |
| 465 | −} /* calc_output */ | |
| 466 | − | |