| @@ -65,11 +65,15 @@ typedef struct · 64 unmodified lines |
| 65 | 65 | coeff_t const *coeffs ; |
| 66 | 66 | |
| 67 | 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 | 71 | } SINC_FILTER ; |
| 70 | 72 | |
| 71 | 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 | 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 | 168 | temp_filter.channels = psrc->channels ; |
| 165 | 169 | |
| 166 | 170 | if (psrc->channels == 1) |
| 167 | | − { psrc->const_process = sinc_1chan_vari_process ; |
| 168 | | − psrc->vari_process = sinc_1chan_vari_process ; |
| 171 | + { psrc->const_process = sinc_mono_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 | 184 | else |
| 171 | 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 | 314 | return (left + right) ; |
| 301 | 315 | } /* calc_output_single */ |
| 302 | 316 | |
| 303 | | −static inline double |
| 304 | | −calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) |
| 305 | | −{ double fraction, left, right, icoeff ; |
| 317 | +static int |
| 318 | +sinc_mono_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) |
| 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 | 413 | increment_t filter_index, max_filter_index ; |
| 307 | 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 | 420 | filter_index = start_filter_index ; |
| 314 | 421 | coeff_count = (max_filter_index - filter_index) / increment ; |
| 315 | 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 | 426 | do |
| 320 | 427 | { fraction = fp_to_double (filter_index) ; |
| 321 | 428 | indx = fp_to_int (filter_index) ; |
| 322 | 429 | |
| 323 | 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 | 435 | filter_index -= increment ; |
| 328 | | − data_index = data_index + filter->channels ; |
| 436 | + data_index = data_index + 2 ; |
| 329 | 437 | } |
| 330 | 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 | 441 | filter_index = increment - start_filter_index ; |
| 334 | 442 | coeff_count = (max_filter_index - filter_index) / increment ; |
| 335 | 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 | 447 | do |
| 340 | 448 | { fraction = fp_to_double (filter_index) ; |
| 341 | 449 | indx = fp_to_int (filter_index) ; |
| 342 | 450 | |
| 343 | 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 | 456 | filter_index -= increment ; |
| 348 | 457 | data_index = data_index - filter->channels ; |
| 349 | 458 | } |
| 350 | 459 | while (filter_index > MAKE_INCREMENT_T (0)) ; |
| 351 | 460 | |
| 352 | | − return (left + right) ; |
| 353 | | −} /* calc_output_multi */ |
| 461 | + output [0] = scale * (left [0] + right [0]) ; |
| 462 | + output [1] = scale * (left [1] + right [1]) ; |
| 463 | +} /* calc_output_stereo */ |
| 354 | 464 | |
| 355 | 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 | 467 | { SINC_FILTER *filter ; |
| 358 | 468 | double input_index, src_ratio, count, float_increment, terminate, rem ; |
| 359 | 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 | 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) * |
| 426 | | − calc_output_single (filter, increment, start_filter_index)) ; |
| 427 | | − filter->out_gen ++ ; |
| 535 | + calc_output_stereo (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; |
| 536 | + filter->out_gen += 2 ; |
| 428 | 537 | |
| 429 | 538 | /* Figure out the next index. */ |
| 430 | 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 | 552 | data->output_frames_gen = filter->out_gen / filter->channels ; |
| 444 | 553 | |
| 445 | 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 | 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 | 620 | { SINC_FILTER *filter ; |
| 451 | 621 | double input_index, src_ratio, count, float_increment, terminate, rem ; |
| 452 | 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 | 625 | if (psrc->private_data == NULL) |
| 456 | 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 | 686 | start_filter_index = double_to_fp (input_index * float_increment) ; |
| 517 | 687 | |
| 518 | | − for (ch = 0 ; ch < filter->channels ; ch++) |
| 519 | | − { data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) * |
| 520 | | − calc_output_multi (filter, increment, start_filter_index, ch)) ; |
| 521 | | − filter->out_gen ++ ; |
| 688 | + calc_output_quad (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; |
| 689 | + filter->out_gen += 4 ; |
| 690 | + |
| 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 | 844 | /* Figure out the next index. */ |
| 525 | 845 | input_index += 1.0 / src_ratio ; |
| 526 | 846 | rem = fmod_one (input_index) ; |