| @@ -65,11 +65,15 @@ typedef struct · 64 unmodified lines |
| 65 | coeff_t const *coeffs ; | 65 | coeff_t const *coeffs ; |
| 66 | | 66 | |
| 67 | int b_current, b_end, b_real_end, b_len ; | 67 | int b_current, b_end, b_real_end, b_len ; |
| 68 | float buffer [1] ; | 68 | |
| | 69 | /* C99 struct flexible array. */ |
| | 70 | float buffer [] ; |
| 69 | } SINC_FILTER ; | 71 | } SINC_FILTER ; |
| 70 | | 72 | |
| 71 | static int sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; | 73 | 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 | static int sinc_quad_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; |
| | 75 | static int sinc_stereo_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; |
| | 76 | static int sinc_mono_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; |
| 73 | | 77 | |
| 74 | static void prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) ; | 78 | static void prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) ; |
| 75 | | 79 | |
| @@ -164,8 +168,18 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum) · 88 unmodified lines |
| 164 | temp_filter.channels = psrc->channels ; | 168 | temp_filter.channels = psrc->channels ; |
| 165 | | 169 | |
| 166 | if (psrc->channels == 1) | 170 | if (psrc->channels == 1) |
| 167 | { psrc->const_process = sinc_1chan_vari_process ; | 171 | { psrc->const_process = sinc_mono_vari_process ; |
| 168 | psrc->vari_process = sinc_1chan_vari_process ; | 172 | psrc->vari_process = sinc_mono_vari_process ; |
| | 173 | } |
| | 174 | else |
| | 175 | if (psrc->channels == 2) |
| | 176 | { psrc->const_process = sinc_stereo_vari_process ; |
| | 177 | psrc->vari_process = sinc_stereo_vari_process ; |
| | 178 | } |
| | 179 | else |
| | 180 | if (psrc->channels == 4) |
| | 181 | { psrc->const_process = sinc_quad_vari_process ; |
| | 182 | psrc->vari_process = sinc_quad_vari_process ; |
| 169 | } | 183 | } |
| 170 | else | 184 | else |
| 171 | { psrc->const_process = sinc_multichan_vari_process ; | 185 | { psrc->const_process = sinc_multichan_vari_process ; |
| @@ -300,9 +314,102 @@ calc_output_single (SINC_FILTER *filter, increment_t increment, increment_t star · 128 unmodified lines |
| 300 | return (left + right) ; | 314 | return (left + right) ; |
| 301 | } /* calc_output_single */ | 315 | } /* calc_output_single */ |
| 302 | | 316 | |
| 303 | static inline double | 317 | static int |
| 304 | calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) | 318 | sinc_mono_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) |
| 305 | { double fraction, left, right, icoeff ; | 319 | { SINC_FILTER *filter ; |
| | 320 | double input_index, src_ratio, count, float_increment, terminate, rem ; |
| | 321 | increment_t increment, start_filter_index ; |
| | 322 | int half_filter_chan_len, samples_in_hand ; |
| | 323 | |
| | 324 | if (psrc->private_data == NULL) |
| | 325 | return SRC_ERR_NO_PRIVATE ; |
| | 326 | |
| | 327 | filter = (SINC_FILTER*) psrc->private_data ; |
| | 328 | |
| | 329 | /* If there is not a problem, this will be optimised out. */ |
| | 330 | if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) |
| | 331 | return SRC_ERR_SIZE_INCOMPATIBILITY ; |
| | 332 | |
| | 333 | filter->in_count = data->input_frames * filter->channels ; |
| | 334 | filter->out_count = data->output_frames * filter->channels ; |
| | 335 | filter->in_used = filter->out_gen = 0 ; |
| | 336 | |
| | 337 | src_ratio = psrc->last_ratio ; |
| | 338 | |
| | 339 | /* Check the sample rate ratio wrt the buffer len. */ |
| | 340 | count = (filter->coeff_half_len + 2.0) / filter->index_inc ; |
| | 341 | if (MIN (psrc->last_ratio, data->src_ratio) < 1.0) |
| | 342 | count /= MIN (psrc->last_ratio, data->src_ratio) ; |
| | 343 | |
| | 344 | /* Maximum coefficientson either side of center point. */ |
| | 345 | half_filter_chan_len = filter->channels * (lrint (count) + 1) ; |
| | 346 | |
| | 347 | input_index = psrc->last_position ; |
| | 348 | float_increment = filter->index_inc ; |
| | 349 | |
| | 350 | rem = fmod_one (input_index) ; |
| | 351 | filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; |
| | 352 | input_index = rem ; |
| | 353 | |
| | 354 | terminate = 1.0 / src_ratio + 1e-20 ; |
| | 355 | |
| | 356 | /* Main processing loop. */ |
| | 357 | while (filter->out_gen < filter->out_count) |
| | 358 | { |
| | 359 | /* Need to reload buffer? */ |
| | 360 | samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; |
| | 361 | |
| | 362 | if (samples_in_hand <= half_filter_chan_len) |
| | 363 | { prepare_data (filter, data, half_filter_chan_len) ; |
| | 364 | |
| | 365 | samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; |
| | 366 | if (samples_in_hand <= half_filter_chan_len) |
| | 367 | break ; |
| | 368 | } ; |
| | 369 | |
| | 370 | /* This is the termination condition. */ |
| | 371 | if (filter->b_real_end >= 0) |
| | 372 | { if (filter->b_current + input_index + terminate >= filter->b_real_end) |
| | 373 | break ; |
| | 374 | } ; |
| | 375 | |
| | 376 | if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10) |
| | 377 | src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ; |
| | 378 | |
| | 379 | float_increment = filter->index_inc * 1.0 ; |
| | 380 | if (src_ratio < 1.0) |
| | 381 | float_increment = filter->index_inc * src_ratio ; |
| | 382 | |
| | 383 | increment = double_to_fp (float_increment) ; |
| | 384 | |
| | 385 | start_filter_index = double_to_fp (input_index * float_increment) ; |
| | 386 | |
| | 387 | data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) * |
| | 388 | calc_output_single (filter, increment, start_filter_index)) ; |
| | 389 | filter->out_gen ++ ; |
| | 390 | |
| | 391 | /* Figure out the next index. */ |
| | 392 | input_index += 1.0 / src_ratio ; |
| | 393 | rem = fmod_one (input_index) ; |
| | 394 | |
| | 395 | filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; |
| | 396 | input_index = rem ; |
| | 397 | } ; |
| | 398 | |
| | 399 | psrc->last_position = input_index ; |
| | 400 | |
| | 401 | /* Save current ratio rather then target ratio. */ |
| | 402 | psrc->last_ratio = src_ratio ; |
| | 403 | |
| | 404 | data->input_frames_used = filter->in_used / filter->channels ; |
| | 405 | data->output_frames_gen = filter->out_gen / filter->channels ; |
| | 406 | |
| | 407 | return SRC_ERR_NO_ERROR ; |
| | 408 | } /* sinc_mono_vari_process */ |
| | 409 | |
| | 410 | static inline void |
| | 411 | calc_output_stereo (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, double scale, float * output) |
| | 412 | { double fraction, left [2], right [2], icoeff ; |
| 306 | increment_t filter_index, max_filter_index ; | 413 | increment_t filter_index, max_filter_index ; |
| 307 | int data_index, coeff_count, indx ; | 414 | int data_index, coeff_count, indx ; |
| 308 | | 415 | |
| @@ -313,19 +420,20 @@ calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start · 4 unmodified lines |
| 313 | filter_index = start_filter_index ; | 420 | filter_index = start_filter_index ; |
| 314 | coeff_count = (max_filter_index - filter_index) / increment ; | 421 | coeff_count = (max_filter_index - filter_index) / increment ; |
| 315 | filter_index = filter_index + coeff_count * increment ; | 422 | filter_index = filter_index + coeff_count * increment ; |
| 316 | data_index = filter->b_current - filter->channels * coeff_count + ch ; | 423 | data_index = filter->b_current - filter->channels * coeff_count ; |
| 317 | | 424 | |
| 318 | left = 0.0 ; | 425 | left [0] = left [1] = 0.0 ; |
| 319 | do | 426 | do |
| 320 | { fraction = fp_to_double (filter_index) ; | 427 | { fraction = fp_to_double (filter_index) ; |
| 321 | indx = fp_to_int (filter_index) ; | 428 | indx = fp_to_int (filter_index) ; |
| 322 | | 429 | |
| 323 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | 430 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| 324 | | 431 | |
| 325 | left += icoeff * filter->buffer [data_index] ; | 432 | left [0] += icoeff * filter->buffer [data_index] ; |
| | 433 | left [1] += icoeff * filter->buffer [data_index + 1] ; |
| 326 | | 434 | |
| 327 | filter_index -= increment ; | 435 | filter_index -= increment ; |
| 328 | data_index = data_index + filter->channels ; | 436 | data_index = data_index + 2 ; |
| 329 | } | 437 | } |
| 330 | while (filter_index >= MAKE_INCREMENT_T (0)) ; | 438 | while (filter_index >= MAKE_INCREMENT_T (0)) ; |
| 331 | | 439 | |
| @@ -333,27 +441,29 @@ calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start · 1 unmodified line |
| 333 | filter_index = increment - start_filter_index ; | 441 | filter_index = increment - start_filter_index ; |
| 334 | coeff_count = (max_filter_index - filter_index) / increment ; | 442 | coeff_count = (max_filter_index - filter_index) / increment ; |
| 335 | filter_index = filter_index + coeff_count * increment ; | 443 | filter_index = filter_index + coeff_count * increment ; |
| 336 | data_index = filter->b_current + filter->channels * (1 + coeff_count) + ch ; | 444 | data_index = filter->b_current + filter->channels * (1 + coeff_count) ; |
| 337 | | 445 | |
| 338 | right = 0.0 ; | 446 | right [0] = right [1] = 0.0 ; |
| 339 | do | 447 | do |
| 340 | { fraction = fp_to_double (filter_index) ; | 448 | { fraction = fp_to_double (filter_index) ; |
| 341 | indx = fp_to_int (filter_index) ; | 449 | indx = fp_to_int (filter_index) ; |
| 342 | | 450 | |
| 343 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | 451 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| 344 | | 452 | |
| 345 | right += icoeff * filter->buffer [data_index] ; | 453 | right [0] += icoeff * filter->buffer [data_index] ; |
| | 454 | right [1] += icoeff * filter->buffer [data_index + 1] ; |
| 346 | | 455 | |
| 347 | filter_index -= increment ; | 456 | filter_index -= increment ; |
| 348 | data_index = data_index - filter->channels ; | 457 | data_index = data_index - filter->channels ; |
| 349 | } | 458 | } |
| 350 | while (filter_index > MAKE_INCREMENT_T (0)) ; | 459 | while (filter_index > MAKE_INCREMENT_T (0)) ; |
| 351 | | 460 | |
| 352 | return (left + right) ; | 461 | output [0] = scale * (left [0] + right [0]) ; |
| 353 | } /* calc_output_multi */ | 462 | output [1] = scale * (left [1] + right [1]) ; |
| | 463 | } /* calc_output_stereo */ |
| 354 | | 464 | |
| 355 | static int | 465 | static int |
| 356 | sinc_1chan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) | 466 | sinc_stereo_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) |
| 357 | { SINC_FILTER *filter ; | 467 | { SINC_FILTER *filter ; |
| 358 | double input_index, src_ratio, count, float_increment, terminate, rem ; | 468 | double input_index, src_ratio, count, float_increment, terminate, rem ; |
| 359 | increment_t increment, start_filter_index ; | 469 | increment_t increment, start_filter_index ; |
| @@ -422,9 +532,8 @@ sinc_1chan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) · 62 unmodified lines |
| 422 | | 532 | |
| 423 | start_filter_index = double_to_fp (input_index * float_increment) ; | 533 | start_filter_index = double_to_fp (input_index * float_increment) ; |
| 424 | | 534 | |
| 425 | data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) * | 535 | calc_output_stereo (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; |
| 426 | calc_output_single (filter, increment, start_filter_index)) ; | 536 | filter->out_gen += 2 ; |
| 427 | filter->out_gen ++ ; | | |
| 428 | | 537 | |
| 429 | /* Figure out the next index. */ | 538 | /* Figure out the next index. */ |
| 430 | input_index += 1.0 / src_ratio ; | 539 | input_index += 1.0 / src_ratio ; |
| @@ -443,14 +552,75 @@ sinc_1chan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) · 12 unmodified lines |
| 443 | data->output_frames_gen = filter->out_gen / filter->channels ; | 552 | data->output_frames_gen = filter->out_gen / filter->channels ; |
| 444 | | 553 | |
| 445 | return SRC_ERR_NO_ERROR ; | 554 | return SRC_ERR_NO_ERROR ; |
| 446 | } /* sinc_1chan_vari_process */ | 555 | } /* sinc_stereo_vari_process */ |
| | 556 | |
| | 557 | static inline void |
| | 558 | calc_output_quad (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, double scale, float * output) |
| | 559 | { double fraction, left [4], right [4], icoeff ; |
| | 560 | increment_t filter_index, max_filter_index ; |
| | 561 | int data_index, coeff_count, indx ; |
| | 562 | |
| | 563 | /* Convert input parameters into fixed point. */ |
| | 564 | max_filter_index = int_to_fp (filter->coeff_half_len) ; |
| | 565 | |
| | 566 | /* First apply the left half of the filter. */ |
| | 567 | filter_index = start_filter_index ; |
| | 568 | coeff_count = (max_filter_index - filter_index) / increment ; |
| | 569 | filter_index = filter_index + coeff_count * increment ; |
| | 570 | data_index = filter->b_current - filter->channels * coeff_count ; |
| | 571 | |
| | 572 | left [0] = left [1] = left [2] = left [3] = 0.0 ; |
| | 573 | do |
| | 574 | { fraction = fp_to_double (filter_index) ; |
| | 575 | indx = fp_to_int (filter_index) ; |
| | 576 | |
| | 577 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| | 578 | |
| | 579 | left [0] += icoeff * filter->buffer [data_index] ; |
| | 580 | left [1] += icoeff * filter->buffer [data_index + 1] ; |
| | 581 | left [2] += icoeff * filter->buffer [data_index + 2] ; |
| | 582 | left [3] += icoeff * filter->buffer [data_index + 3] ; |
| | 583 | |
| | 584 | filter_index -= increment ; |
| | 585 | data_index = data_index + 4 ; |
| | 586 | } |
| | 587 | while (filter_index >= MAKE_INCREMENT_T (0)) ; |
| | 588 | |
| | 589 | /* Now apply the right half of the filter. */ |
| | 590 | filter_index = increment - start_filter_index ; |
| | 591 | coeff_count = (max_filter_index - filter_index) / increment ; |
| | 592 | filter_index = filter_index + coeff_count * increment ; |
| | 593 | data_index = filter->b_current + filter->channels * (1 + coeff_count) ; |
| | 594 | |
| | 595 | right [0] = right [1] = right [2] = right [3] = 0.0 ; |
| | 596 | do |
| | 597 | { fraction = fp_to_double (filter_index) ; |
| | 598 | indx = fp_to_int (filter_index) ; |
| | 599 | |
| | 600 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| | 601 | |
| | 602 | right [0] += icoeff * filter->buffer [data_index] ; |
| | 603 | right [1] += icoeff * filter->buffer [data_index + 1] ; |
| | 604 | right [2] += icoeff * filter->buffer [data_index + 2] ; |
| | 605 | right [3] += icoeff * filter->buffer [data_index + 3] ; |
| | 606 | |
| | 607 | filter_index -= increment ; |
| | 608 | data_index = data_index - filter->channels ; |
| | 609 | } |
| | 610 | while (filter_index > MAKE_INCREMENT_T (0)) ; |
| | 611 | |
| | 612 | output [0] = scale * (left [0] + right [0]) ; |
| | 613 | output [1] = scale * (left [1] + right [1]) ; |
| | 614 | output [2] = scale * (left [2] + right [2]) ; |
| | 615 | output [3] = scale * (left [3] + right [3]) ; |
| | 616 | } /* calc_output_quad */ |
| 447 | | 617 | |
| 448 | static int | 618 | static int |
| 449 | sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) | 619 | sinc_quad_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) |
| 450 | { SINC_FILTER *filter ; | 620 | { SINC_FILTER *filter ; |
| 451 | double input_index, src_ratio, count, float_increment, terminate, rem ; | 621 | double input_index, src_ratio, count, float_increment, terminate, rem ; |
| 452 | increment_t increment, start_filter_index ; | 622 | increment_t increment, start_filter_index ; |
| 453 | int half_filter_chan_len, samples_in_hand, ch ; | 623 | int half_filter_chan_len, samples_in_hand ; |
| 454 | | 624 | |
| 455 | if (psrc->private_data == NULL) | 625 | if (psrc->private_data == NULL) |
| 456 | return SRC_ERR_NO_PRIVATE ; | 626 | return SRC_ERR_NO_PRIVATE ; |
| @@ -515,12 +685,162 @@ sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) · 58 unmodified lines |
| 515 | | 685 | |
| 516 | start_filter_index = double_to_fp (input_index * float_increment) ; | 686 | start_filter_index = double_to_fp (input_index * float_increment) ; |
| 517 | | 687 | |
| 518 | for (ch = 0 ; ch < filter->channels ; ch++) | 688 | calc_output_quad (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; |
| 519 | { data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) * | 689 | filter->out_gen += 4 ; |
| 520 | calc_output_multi (filter, increment, start_filter_index, ch)) ; | 690 | |
| 521 | filter->out_gen ++ ; | 691 | /* Figure out the next index. */ |
| | 692 | input_index += 1.0 / src_ratio ; |
| | 693 | rem = fmod_one (input_index) ; |
| | 694 | |
| | 695 | filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; |
| | 696 | input_index = rem ; |
| | 697 | } ; |
| | 698 | |
| | 699 | psrc->last_position = input_index ; |
| | 700 | |
| | 701 | /* Save current ratio rather then target ratio. */ |
| | 702 | psrc->last_ratio = src_ratio ; |
| | 703 | |
| | 704 | data->input_frames_used = filter->in_used / filter->channels ; |
| | 705 | data->output_frames_gen = filter->out_gen / filter->channels ; |
| | 706 | |
| | 707 | return SRC_ERR_NO_ERROR ; |
| | 708 | } /* sinc_quad_vari_process */ |
| | 709 | |
| | 710 | static inline void |
| | 711 | calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int channels, double scale, float * output) |
| | 712 | { double fraction, left [channels], right [channels], icoeff ; |
| | 713 | increment_t filter_index, max_filter_index ; |
| | 714 | int data_index, coeff_count, indx, ch ; |
| | 715 | |
| | 716 | /* Convert input parameters into fixed point. */ |
| | 717 | max_filter_index = int_to_fp (filter->coeff_half_len) ; |
| | 718 | |
| | 719 | /* First apply the left half of the filter. */ |
| | 720 | filter_index = start_filter_index ; |
| | 721 | coeff_count = (max_filter_index - filter_index) / increment ; |
| | 722 | filter_index = filter_index + coeff_count * increment ; |
| | 723 | data_index = filter->b_current - channels * coeff_count ; |
| | 724 | |
| | 725 | memset (left, 0, sizeof (left)) ; |
| | 726 | |
| | 727 | do |
| | 728 | { fraction = fp_to_double (filter_index) ; |
| | 729 | indx = fp_to_int (filter_index) ; |
| | 730 | |
| | 731 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| | 732 | |
| | 733 | ch = channels ; |
| | 734 | while (-- ch >= 0) |
| | 735 | left [ch] += icoeff * filter->buffer [data_index + ch] ; |
| | 736 | |
| | 737 | filter_index -= increment ; |
| | 738 | data_index = data_index + channels ; |
| | 739 | } |
| | 740 | while (filter_index >= MAKE_INCREMENT_T (0)) ; |
| | 741 | |
| | 742 | /* Now apply the right half of the filter. */ |
| | 743 | filter_index = increment - start_filter_index ; |
| | 744 | coeff_count = (max_filter_index - filter_index) / increment ; |
| | 745 | filter_index = filter_index + coeff_count * increment ; |
| | 746 | data_index = filter->b_current + channels * (1 + coeff_count) ; |
| | 747 | |
| | 748 | memset (right, 0, sizeof (right)) ; |
| | 749 | do |
| | 750 | { fraction = fp_to_double (filter_index) ; |
| | 751 | indx = fp_to_int (filter_index) ; |
| | 752 | |
| | 753 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| | 754 | |
| | 755 | ch = channels ; |
| | 756 | while (-- ch >= 0) |
| | 757 | right [ch] += icoeff * filter->buffer [data_index + ch] ; |
| | 758 | |
| | 759 | filter_index -= increment ; |
| | 760 | data_index = data_index - channels ; |
| | 761 | } |
| | 762 | while (filter_index > MAKE_INCREMENT_T (0)) ; |
| | 763 | |
| | 764 | ch = channels ; |
| | 765 | while (-- ch >= 0) |
| | 766 | output [ch] = scale * (left [ch] + right [ch]) ; |
| | 767 | |
| | 768 | return ; |
| | 769 | } /* calc_output_multi */ |
| | 770 | |
| | 771 | static int |
| | 772 | sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) |
| | 773 | { SINC_FILTER *filter ; |
| | 774 | double input_index, src_ratio, count, float_increment, terminate, rem ; |
| | 775 | increment_t increment, start_filter_index ; |
| | 776 | int half_filter_chan_len, samples_in_hand ; |
| | 777 | |
| | 778 | if (psrc->private_data == NULL) |
| | 779 | return SRC_ERR_NO_PRIVATE ; |
| | 780 | |
| | 781 | filter = (SINC_FILTER*) psrc->private_data ; |
| | 782 | |
| | 783 | /* If there is not a problem, this will be optimised out. */ |
| | 784 | if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) |
| | 785 | return SRC_ERR_SIZE_INCOMPATIBILITY ; |
| | 786 | |
| | 787 | filter->in_count = data->input_frames * filter->channels ; |
| | 788 | filter->out_count = data->output_frames * filter->channels ; |
| | 789 | filter->in_used = filter->out_gen = 0 ; |
| | 790 | |
| | 791 | src_ratio = psrc->last_ratio ; |
| | 792 | |
| | 793 | /* Check the sample rate ratio wrt the buffer len. */ |
| | 794 | count = (filter->coeff_half_len + 2.0) / filter->index_inc ; |
| | 795 | if (MIN (psrc->last_ratio, data->src_ratio) < 1.0) |
| | 796 | count /= MIN (psrc->last_ratio, data->src_ratio) ; |
| | 797 | |
| | 798 | /* Maximum coefficientson either side of center point. */ |
| | 799 | half_filter_chan_len = filter->channels * (lrint (count) + 1) ; |
| | 800 | |
| | 801 | input_index = psrc->last_position ; |
| | 802 | float_increment = filter->index_inc ; |
| | 803 | |
| | 804 | rem = fmod_one (input_index) ; |
| | 805 | filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; |
| | 806 | input_index = rem ; |
| | 807 | |
| | 808 | terminate = 1.0 / src_ratio + 1e-20 ; |
| | 809 | |
| | 810 | /* Main processing loop. */ |
| | 811 | while (filter->out_gen < filter->out_count) |
| | 812 | { |
| | 813 | /* Need to reload buffer? */ |
| | 814 | samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; |
| | 815 | |
| | 816 | if (samples_in_hand <= half_filter_chan_len) |
| | 817 | { prepare_data (filter, data, half_filter_chan_len) ; |
| | 818 | |
| | 819 | samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; |
| | 820 | if (samples_in_hand <= half_filter_chan_len) |
| | 821 | break ; |
| | 822 | } ; |
| | 823 | |
| | 824 | /* This is the termination condition. */ |
| | 825 | if (filter->b_real_end >= 0) |
| | 826 | { if (filter->b_current + input_index + terminate >= filter->b_real_end) |
| | 827 | break ; |
| 522 | } ; | 828 | } ; |
| 523 | | 829 | |
| | 830 | if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10) |
| | 831 | src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ; |
| | 832 | |
| | 833 | float_increment = filter->index_inc * 1.0 ; |
| | 834 | if (src_ratio < 1.0) |
| | 835 | float_increment = filter->index_inc * src_ratio ; |
| | 836 | |
| | 837 | increment = double_to_fp (float_increment) ; |
| | 838 | |
| | 839 | start_filter_index = double_to_fp (input_index * float_increment) ; |
| | 840 | |
| | 841 | calc_output_multi (filter, increment, start_filter_index, filter->channels, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; |
| | 842 | filter->out_gen += psrc->channels ; |
| | 843 | |
| 524 | /* Figure out the next index. */ | 844 | /* Figure out the next index. */ |
| 525 | input_index += 1.0 / src_ratio ; | 845 | input_index += 1.0 / src_ratio ; |
| 526 | rem = fmod_one (input_index) ; | 846 | rem = fmod_one (input_index) ; |