1 /* 2 ** Copyright (c) 2002-2021, Erik de Castro Lopo <erikd@mega-nerd.com> 3 ** All rights reserved. 4 ** 5 ** This code is released under 2-clause BSD license. Please see the 6 ** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING 7 */ 8 9 #ifdef HAVE_CONFIG_H 10 #include "config.h" 11 #endif 12 13 #include <assert.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <math.h> 18 19 #include "common.h" 20 21 #define SINC_MAGIC_MARKER MAKE_MAGIC (' ', 's', 'i', 'n', 'c', ' ') 22 23 /*======================================================================================== 24 */ 25 26 #define MAKE_INCREMENT_T(x) ((increment_t) (x)) 27 28 #define SHIFT_BITS 12 29 #define FP_ONE ((double) (((increment_t) 1) << SHIFT_BITS)) 30 #define INV_FP_ONE (1.0 / FP_ONE) 31 32 /* Customixe max channls from Kconfig. */ 33 #ifndef CONFIG_CHAN_NR 34 #define MAX_CHANNELS 128 35 #else 36 #define MAX_CHANNELS CONFIG_CHAN_NR 37 #endif 38 39 /*======================================================================================== 40 */ 41 42 typedef int32_t increment_t ; 43 typedef float coeff_t ; 44 typedef int _CHECK_SHIFT_BITS[2 * (SHIFT_BITS < sizeof (increment_t) * 8 - 1) - 1]; /* sanity check. */ 45 46 #ifdef ENABLE_SINC_FAST_CONVERTER 47 #include "fastest_coeffs.h" 48 #endif 49 #ifdef ENABLE_SINC_MEDIUM_CONVERTER 50 #include "mid_qual_coeffs.h" 51 #endif 52 #ifdef ENABLE_SINC_BEST_CONVERTER 53 #include "high_qual_coeffs.h" 54 #endif 55 56 typedef struct 57 { int sinc_magic_marker ; 58 59 long in_count, in_used ; 60 long out_count, out_gen ; 61 62 int coeff_half_len, index_inc ; 63 64 double src_ratio, input_index ; 65 66 coeff_t const *coeffs ; 67 68 int b_current, b_end, b_real_end, b_len ; 69 70 /* Sure hope noone does more than 128 channels at once. */ 71 double left_calc [MAX_CHANNELS], right_calc [MAX_CHANNELS] ; 72 73 float *buffer ; 74 } SINC_FILTER ; 75 76 static SRC_ERROR sinc_multichan_vari_process (SRC_STATE *state, SRC_DATA *data) ; 77 static SRC_ERROR sinc_hex_vari_process (SRC_STATE *state, SRC_DATA *data) ; 78 static SRC_ERROR sinc_quad_vari_process (SRC_STATE *state, SRC_DATA *data) ; 79 static SRC_ERROR sinc_stereo_vari_process (SRC_STATE *state, SRC_DATA *data) ; 80 static SRC_ERROR sinc_mono_vari_process (SRC_STATE *state, SRC_DATA *data) ; 81 82 static SRC_ERROR prepare_data (SINC_FILTER *filter, int channels, SRC_DATA *data, int half_filter_chan_len) WARN_UNUSED ; 83 84 static void sinc_reset (SRC_STATE *state) ; 85 static SRC_STATE *sinc_copy (SRC_STATE *state) ; 86 static void sinc_close (SRC_STATE *state) ; 87 88 static SRC_STATE_VT sinc_multichan_state_vt = 89 { 90 sinc_multichan_vari_process, 91 sinc_multichan_vari_process, 92 sinc_reset, 93 sinc_copy, 94 sinc_close 95 } ; 96 97 static SRC_STATE_VT sinc_hex_state_vt = 98 { 99 sinc_hex_vari_process, 100 sinc_hex_vari_process, 101 sinc_reset, 102 sinc_copy, 103 sinc_close 104 } ; 105 106 static SRC_STATE_VT sinc_quad_state_vt = 107 { 108 sinc_quad_vari_process, 109 sinc_quad_vari_process, 110 sinc_reset, 111 sinc_copy, 112 sinc_close 113 } ; 114 115 static SRC_STATE_VT sinc_stereo_state_vt = 116 { 117 sinc_stereo_vari_process, 118 sinc_stereo_vari_process, 119 sinc_reset, 120 sinc_copy, 121 sinc_close 122 } ; 123 124 static SRC_STATE_VT sinc_mono_state_vt = 125 { 126 sinc_mono_vari_process, 127 sinc_mono_vari_process, 128 sinc_reset, 129 sinc_copy, 130 sinc_close 131 } ; 132 133 static inline increment_t 134 double_to_fp (double x) 135 { return (increment_t) (lrint ((x) * FP_ONE)) ; 136 } /* double_to_fp */ 137 138 static inline increment_t 139 int_to_fp (int x) 140 { return (((increment_t) (x)) << SHIFT_BITS) ; 141 } /* int_to_fp */ 142 143 static inline int 144 fp_to_int (increment_t x) 145 { return (((x) >> SHIFT_BITS)) ; 146 } /* fp_to_int */ 147 148 static inline increment_t 149 fp_fraction_part (increment_t x) 150 { return ((x) & ((((increment_t) 1) << SHIFT_BITS) - 1)) ; 151 } /* fp_fraction_part */ 152 153 static inline double 154 fp_to_double (increment_t x) 155 { return fp_fraction_part (x) * INV_FP_ONE ; 156 } /* fp_to_double */ 157 158 static inline int 159 int_div_ceil (int divident, int divisor) /* == (int) ceil ((float) divident / divisor) */ 160 { assert (divident >= 0 && divisor > 0) ; /* For positive numbers only */ 161 return (divident + (divisor - 1)) / divisor ; 162 } 163 164 /*---------------------------------------------------------------------------------------- 165 */ 166 167 #if 0 168 LIBSAMPLERATE_DLL_PRIVATE const char* 169 sinc_get_name (int src_enum) 170 { 171 switch (src_enum) 172 { case SRC_SINC_BEST_QUALITY : 173 return "Best Sinc Interpolator" ; 174 175 case SRC_SINC_MEDIUM_QUALITY : 176 return "Medium Sinc Interpolator" ; 177 178 case SRC_SINC_FASTEST : 179 return "Fastest Sinc Interpolator" ; 180 181 default: break ; 182 } ; 183 184 return NULL ; 185 } /* sinc_get_descrition */ 186 187 LIBSAMPLERATE_DLL_PRIVATE const char* 188 sinc_get_description (int src_enum) 189 { 190 switch (src_enum) 191 { case SRC_SINC_FASTEST : 192 return "Band limited sinc interpolation, fastest, 97dB SNR, 80% BW." ; 193 194 case SRC_SINC_MEDIUM_QUALITY : 195 return "Band limited sinc interpolation, medium quality, 121dB SNR, 90% BW." ; 196 197 case SRC_SINC_BEST_QUALITY : 198 return "Band limited sinc interpolation, best quality, 144dB SNR, 96% BW." ; 199 200 default : 201 break ; 202 } ; 203 204 return NULL ; 205 } /* sinc_get_descrition */ 206 #endif 207 208 static SINC_FILTER * 209 sinc_filter_new (int converter_type, int channels) 210 { 211 assert (converter_type == SRC_SINC_FASTEST || 212 converter_type == SRC_SINC_MEDIUM_QUALITY || 213 converter_type == SRC_SINC_BEST_QUALITY) ; 214 assert (channels > 0 && channels <= MAX_CHANNELS) ; 215 216 SINC_FILTER *priv = (SINC_FILTER *) calloc (1, sizeof (SINC_FILTER)) ; 217 if (priv) 218 { 219 priv->sinc_magic_marker = SINC_MAGIC_MARKER ; 220 switch (converter_type) 221 { 222 #ifdef ENABLE_SINC_FAST_CONVERTER 223 case SRC_SINC_FASTEST : 224 priv->coeffs = fastest_coeffs.coeffs ; 225 priv->coeff_half_len = ARRAY_LEN (fastest_coeffs.coeffs) - 2 ; 226 priv->index_inc = fastest_coeffs.increment ; 227 break ; 228 #endif 229 #ifdef ENABLE_SINC_MEDIUM_CONVERTER 230 case SRC_SINC_MEDIUM_QUALITY : 231 priv->coeffs = slow_mid_qual_coeffs.coeffs ; 232 priv->coeff_half_len = ARRAY_LEN (slow_mid_qual_coeffs.coeffs) - 2 ; 233 priv->index_inc = slow_mid_qual_coeffs.increment ; 234 break ; 235 #endif 236 #ifdef ENABLE_SINC_BEST_CONVERTER 237 case SRC_SINC_BEST_QUALITY : 238 priv->coeffs = slow_high_qual_coeffs.coeffs ; 239 priv->coeff_half_len = ARRAY_LEN (slow_high_qual_coeffs.coeffs) - 2 ; 240 priv->index_inc = slow_high_qual_coeffs.increment ; 241 break ; 242 #endif 243 } 244 245 priv->b_len = 3 * (int) lrint ((priv->coeff_half_len + 2.0) / priv->index_inc * SRC_MAX_RATIO + 1) ; 246 priv->b_len = MAX (priv->b_len, 4096) ; 247 priv->b_len *= channels ; 248 priv->b_len += 1 ; // There is a <= check against samples_in_hand requiring a buffer bigger than the calculation above 249 250 251 priv->buffer = (float *) calloc (priv->b_len + channels, sizeof (float)) ; 252 if (!priv->buffer) 253 { 254 free (priv) ; 255 priv = NULL ; 256 } 257 } 258 259 return priv ; 260 } 261 262 LIBSAMPLERATE_DLL_PRIVATE SRC_STATE * 263 sinc_state_new (int converter_type, int channels, SRC_ERROR *error) 264 { 265 assert (converter_type == SRC_SINC_FASTEST || 266 converter_type == SRC_SINC_MEDIUM_QUALITY || 267 converter_type == SRC_SINC_BEST_QUALITY) ; 268 assert (channels > 0) ; 269 assert (error != NULL) ; 270 271 if (channels > MAX_CHANNELS) 272 { 273 *error = SRC_ERR_BAD_CHANNEL_COUNT ; 274 return NULL ; 275 } 276 277 SRC_STATE *state = (SRC_STATE *) calloc (1, sizeof (SRC_STATE)) ; 278 if (!state) 279 { 280 *error = SRC_ERR_MALLOC_FAILED ; 281 return NULL ; 282 } 283 284 state->channels = channels ; 285 state->mode = SRC_MODE_PROCESS ; 286 287 if (state->channels == 1) 288 state->vt = &sinc_mono_state_vt ; 289 else if (state->channels == 2) 290 state->vt = &sinc_stereo_state_vt ; 291 else if (state->channels == 4) 292 state->vt = &sinc_quad_state_vt ; 293 else if (state->channels == 6) 294 state->vt = &sinc_hex_state_vt ; 295 else 296 state->vt = &sinc_multichan_state_vt ; 297 298 state->private_data = sinc_filter_new (converter_type, state->channels) ; 299 if (!state->private_data) 300 { 301 free (state) ; 302 *error = SRC_ERR_MALLOC_FAILED ; 303 return NULL ; 304 } 305 306 sinc_reset (state) ; 307 308 *error = SRC_ERR_NO_ERROR ; 309 310 return state ; 311 } 312 313 static void 314 sinc_reset (SRC_STATE *state) 315 { SINC_FILTER *filter ; 316 317 filter = (SINC_FILTER*) state->private_data ; 318 if (filter == NULL) 319 return ; 320 321 filter->b_current = filter->b_end = 0 ; 322 filter->b_real_end = -1 ; 323 324 filter->src_ratio = filter->input_index = 0.0 ; 325 326 memset (filter->buffer, 0, filter->b_len * sizeof (filter->buffer [0])) ; 327 328 /* Set this for a sanity check */ 329 memset (filter->buffer + filter->b_len, 0xAA, state->channels * sizeof (filter->buffer [0])) ; 330 } /* sinc_reset */ 331 332 static SRC_STATE * 333 sinc_copy (SRC_STATE *state) 334 { 335 assert (state != NULL) ; 336 337 if (state->private_data == NULL) 338 return NULL ; 339 340 SRC_STATE *to = (SRC_STATE *) calloc (1, sizeof (SRC_STATE)) ; 341 if (!to) 342 return NULL ; 343 memcpy (to, state, sizeof (SRC_STATE)) ; 344 345 346 SINC_FILTER* from_filter = (SINC_FILTER*) state->private_data ; 347 SINC_FILTER *to_filter = (SINC_FILTER *) calloc (1, sizeof (SINC_FILTER)) ; 348 if (!to_filter) 349 { 350 free (to) ; 351 return NULL ; 352 } 353 memcpy (to_filter, from_filter, sizeof (SINC_FILTER)) ; 354 to_filter->buffer = (float *) malloc (sizeof (float) * (from_filter->b_len + state->channels)) ; 355 if (!to_filter->buffer) 356 { 357 free (to) ; 358 free (to_filter) ; 359 return NULL ; 360 } 361 memcpy (to_filter->buffer, from_filter->buffer, sizeof (float) * (from_filter->b_len + state->channels)) ; 362 363 to->private_data = to_filter ; 364 365 return to ; 366 } /* sinc_copy */ 367 368 /*======================================================================================== 369 ** Beware all ye who dare pass this point. There be dragons here. 370 */ 371 372 static inline double 373 calc_output_single (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index) 374 { double fraction, left, right, icoeff ; 375 increment_t filter_index, max_filter_index ; 376 int data_index, coeff_count, indx ; 377 378 /* Convert input parameters into fixed point. */ 379 max_filter_index = int_to_fp (filter->coeff_half_len) ; 380 381 /* First apply the left half of the filter. */ 382 filter_index = start_filter_index ; 383 coeff_count = (max_filter_index - filter_index) / increment ; 384 filter_index = filter_index + coeff_count * increment ; 385 data_index = filter->b_current - coeff_count ; 386 387 if (data_index < 0) /* Avoid underflow access to filter->buffer. */ 388 { int steps = -data_index ; 389 /* If the assert triggers we would have to take care not to underflow/overflow */ 390 assert (steps <= int_div_ceil (filter_index, increment)) ; 391 filter_index -= increment * steps ; 392 data_index += steps ; 393 } 394 left = 0.0 ; 395 while (filter_index >= MAKE_INCREMENT_T (0)) 396 { fraction = fp_to_double (filter_index) ; 397 indx = fp_to_int (filter_index) ; 398 assert (indx >= 0 && indx + 1 < filter->coeff_half_len + 2) ; 399 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 400 assert (data_index >= 0 && data_index < filter->b_len) ; 401 assert (data_index < filter->b_end) ; 402 left += icoeff * filter->buffer [data_index] ; 403 404 filter_index -= increment ; 405 data_index = data_index + 1 ; 406 } ; 407 408 /* Now apply the right half of the filter. */ 409 filter_index = increment - start_filter_index ; 410 coeff_count = (max_filter_index - filter_index) / increment ; 411 filter_index = filter_index + coeff_count * increment ; 412 data_index = filter->b_current + 1 + coeff_count ; 413 414 right = 0.0 ; 415 do 416 { fraction = fp_to_double (filter_index) ; 417 indx = fp_to_int (filter_index) ; 418 assert (indx < filter->coeff_half_len + 2) ; 419 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 420 assert (data_index >= 0 && data_index < filter->b_len) ; 421 assert (data_index < filter->b_end) ; 422 right += icoeff * filter->buffer [data_index] ; 423 424 filter_index -= increment ; 425 data_index = data_index - 1 ; 426 } 427 while (filter_index > MAKE_INCREMENT_T (0)) ; 428 429 return (left + right) ; 430 } /* calc_output_single */ 431 432 static SRC_ERROR 433 sinc_mono_vari_process (SRC_STATE *state, SRC_DATA *data) 434 { SINC_FILTER *filter ; 435 double input_index, src_ratio, count, float_increment, terminate, rem ; 436 increment_t increment, start_filter_index ; 437 int half_filter_chan_len, samples_in_hand ; 438 439 if (state->private_data == NULL) 440 return SRC_ERR_NO_PRIVATE ; 441 442 filter = (SINC_FILTER*) state->private_data ; 443 444 /* If there is not a problem, this will be optimised out. */ 445 if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) 446 return SRC_ERR_SIZE_INCOMPATIBILITY ; 447 448 filter->in_count = data->input_frames * state->channels ; 449 filter->out_count = data->output_frames * state->channels ; 450 filter->in_used = filter->out_gen = 0 ; 451 452 src_ratio = state->last_ratio ; 453 454 if (is_bad_src_ratio (src_ratio)) 455 return SRC_ERR_BAD_INTERNAL_STATE ; 456 457 /* Check the sample rate ratio wrt the buffer len. */ 458 count = (filter->coeff_half_len + 2.0) / filter->index_inc ; 459 if (MIN (state->last_ratio, data->src_ratio) < 1.0) 460 count /= MIN (state->last_ratio, data->src_ratio) ; 461 462 /* Maximum coefficientson either side of center point. */ 463 half_filter_chan_len = state->channels * (int) (lrint (count) + 1) ; 464 465 input_index = state->last_position ; 466 467 rem = fmod_one (input_index) ; 468 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 469 input_index = rem ; 470 471 terminate = 1.0 / src_ratio + 1e-20 ; 472 473 /* Main processing loop. */ 474 while (filter->out_gen < filter->out_count) 475 { 476 /* Need to reload buffer? */ 477 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 478 479 if (samples_in_hand <= half_filter_chan_len) 480 { if ((state->error = prepare_data (filter, state->channels, data, half_filter_chan_len)) != 0) 481 return state->error ; 482 483 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 484 if (samples_in_hand <= half_filter_chan_len) 485 break ; 486 } ; 487 488 /* This is the termination condition. */ 489 if (filter->b_real_end >= 0) 490 { if (filter->b_current + input_index + terminate > filter->b_real_end) 491 break ; 492 } ; 493 494 if (filter->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > 1e-10) 495 src_ratio = state->last_ratio + filter->out_gen * (data->src_ratio - state->last_ratio) / filter->out_count ; 496 497 float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ; 498 increment = double_to_fp (float_increment) ; 499 500 start_filter_index = double_to_fp (input_index * float_increment) ; 501 502 data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) * 503 calc_output_single (filter, increment, start_filter_index)) ; 504 filter->out_gen ++ ; 505 506 /* Figure out the next index. */ 507 input_index += 1.0 / src_ratio ; 508 rem = fmod_one (input_index) ; 509 510 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 511 input_index = rem ; 512 } ; 513 514 state->last_position = input_index ; 515 516 /* Save current ratio rather then target ratio. */ 517 state->last_ratio = src_ratio ; 518 519 data->input_frames_used = filter->in_used / state->channels ; 520 data->output_frames_gen = filter->out_gen / state->channels ; 521 522 return SRC_ERR_NO_ERROR ; 523 } /* sinc_mono_vari_process */ 524 525 static inline void 526 calc_output_stereo (SINC_FILTER *filter, int channels, increment_t increment, increment_t start_filter_index, double scale, float * output) 527 { double fraction, left [2], right [2], icoeff ; 528 increment_t filter_index, max_filter_index ; 529 int data_index, coeff_count, indx ; 530 531 /* Convert input parameters into fixed point. */ 532 max_filter_index = int_to_fp (filter->coeff_half_len) ; 533 534 /* First apply the left half of the filter. */ 535 filter_index = start_filter_index ; 536 coeff_count = (max_filter_index - filter_index) / increment ; 537 filter_index = filter_index + coeff_count * increment ; 538 data_index = filter->b_current - channels * coeff_count ; 539 540 if (data_index < 0) /* Avoid underflow access to filter->buffer. */ 541 { int steps = int_div_ceil (-data_index, 2) ; 542 /* If the assert triggers we would have to take care not to underflow/overflow */ 543 assert (steps <= int_div_ceil (filter_index, increment)) ; 544 filter_index -= increment * steps ; 545 data_index += steps * 2; 546 } 547 left [0] = left [1] = 0.0 ; 548 while (filter_index >= MAKE_INCREMENT_T (0)) 549 { fraction = fp_to_double (filter_index) ; 550 indx = fp_to_int (filter_index) ; 551 assert (indx >= 0 && indx + 1 < filter->coeff_half_len + 2) ; 552 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 553 assert (data_index >= 0 && data_index + 1 < filter->b_len) ; 554 assert (data_index + 1 < filter->b_end) ; 555 for (int ch = 0; ch < 2; ch++) 556 left [ch] += icoeff * filter->buffer [data_index + ch] ; 557 558 filter_index -= increment ; 559 data_index = data_index + 2 ; 560 } ; 561 562 /* Now apply the right half of the filter. */ 563 filter_index = increment - start_filter_index ; 564 coeff_count = (max_filter_index - filter_index) / increment ; 565 filter_index = filter_index + coeff_count * increment ; 566 data_index = filter->b_current + channels * (1 + coeff_count) ; 567 568 right [0] = right [1] = 0.0 ; 569 do 570 { fraction = fp_to_double (filter_index) ; 571 indx = fp_to_int (filter_index) ; 572 assert (indx >= 0 && indx + 1 < filter->coeff_half_len + 2) ; 573 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 574 assert (data_index >= 0 && data_index + 1 < filter->b_len) ; 575 assert (data_index + 1 < filter->b_end) ; 576 for (int ch = 0; ch < 2; ch++) 577 right [ch] += icoeff * filter->buffer [data_index + ch] ; 578 579 filter_index -= increment ; 580 data_index = data_index - 2 ; 581 } 582 while (filter_index > MAKE_INCREMENT_T (0)) ; 583 584 for (int ch = 0; ch < 2; ch++) 585 output [ch] = (float) (scale * (left [ch] + right [ch])) ; 586 } /* calc_output_stereo */ 587 588 SRC_ERROR 589 sinc_stereo_vari_process (SRC_STATE *state, SRC_DATA *data) 590 { SINC_FILTER *filter ; 591 double input_index, src_ratio, count, float_increment, terminate, rem ; 592 increment_t increment, start_filter_index ; 593 int half_filter_chan_len, samples_in_hand ; 594 595 if (state->private_data == NULL) 596 return SRC_ERR_NO_PRIVATE ; 597 598 filter = (SINC_FILTER*) state->private_data ; 599 600 /* If there is not a problem, this will be optimised out. */ 601 if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) 602 return SRC_ERR_SIZE_INCOMPATIBILITY ; 603 604 filter->in_count = data->input_frames * state->channels ; 605 filter->out_count = data->output_frames * state->channels ; 606 filter->in_used = filter->out_gen = 0 ; 607 608 src_ratio = state->last_ratio ; 609 610 if (is_bad_src_ratio (src_ratio)) 611 return SRC_ERR_BAD_INTERNAL_STATE ; 612 613 /* Check the sample rate ratio wrt the buffer len. */ 614 count = (filter->coeff_half_len + 2.0) / filter->index_inc ; 615 if (MIN (state->last_ratio, data->src_ratio) < 1.0) 616 count /= MIN (state->last_ratio, data->src_ratio) ; 617 618 /* Maximum coefficientson either side of center point. */ 619 half_filter_chan_len = state->channels * (int) (lrint (count) + 1) ; 620 621 input_index = state->last_position ; 622 623 rem = fmod_one (input_index) ; 624 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 625 input_index = rem ; 626 627 terminate = 1.0 / src_ratio + 1e-20 ; 628 629 /* Main processing loop. */ 630 while (filter->out_gen < filter->out_count) 631 { 632 /* Need to reload buffer? */ 633 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 634 635 if (samples_in_hand <= half_filter_chan_len) 636 { if ((state->error = prepare_data (filter, state->channels, data, half_filter_chan_len)) != 0) 637 return state->error ; 638 639 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 640 if (samples_in_hand <= half_filter_chan_len) 641 break ; 642 } ; 643 644 /* This is the termination condition. */ 645 if (filter->b_real_end >= 0) 646 { if (filter->b_current + input_index + terminate >= filter->b_real_end) 647 break ; 648 } ; 649 650 if (filter->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > 1e-10) 651 src_ratio = state->last_ratio + filter->out_gen * (data->src_ratio - state->last_ratio) / filter->out_count ; 652 653 float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ; 654 increment = double_to_fp (float_increment) ; 655 656 start_filter_index = double_to_fp (input_index * float_increment) ; 657 658 calc_output_stereo (filter, state->channels, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; 659 filter->out_gen += 2 ; 660 661 /* Figure out the next index. */ 662 input_index += 1.0 / src_ratio ; 663 rem = fmod_one (input_index) ; 664 665 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 666 input_index = rem ; 667 } ; 668 669 state->last_position = input_index ; 670 671 /* Save current ratio rather then target ratio. */ 672 state->last_ratio = src_ratio ; 673 674 data->input_frames_used = filter->in_used / state->channels ; 675 data->output_frames_gen = filter->out_gen / state->channels ; 676 677 return SRC_ERR_NO_ERROR ; 678 } /* sinc_stereo_vari_process */ 679 680 static inline void 681 calc_output_quad (SINC_FILTER *filter, int channels, increment_t increment, increment_t start_filter_index, double scale, float * output) 682 { double fraction, left [4], right [4], icoeff ; 683 increment_t filter_index, max_filter_index ; 684 int data_index, coeff_count, indx ; 685 686 /* Convert input parameters into fixed point. */ 687 max_filter_index = int_to_fp (filter->coeff_half_len) ; 688 689 /* First apply the left half of the filter. */ 690 filter_index = start_filter_index ; 691 coeff_count = (max_filter_index - filter_index) / increment ; 692 filter_index = filter_index + coeff_count * increment ; 693 data_index = filter->b_current - channels * coeff_count ; 694 695 if (data_index < 0) /* Avoid underflow access to filter->buffer. */ 696 { int steps = int_div_ceil (-data_index, 4) ; 697 /* If the assert triggers we would have to take care not to underflow/overflow */ 698 assert (steps <= int_div_ceil (filter_index, increment)) ; 699 filter_index -= increment * steps ; 700 data_index += steps * 4; 701 } 702 left [0] = left [1] = left [2] = left [3] = 0.0 ; 703 while (filter_index >= MAKE_INCREMENT_T (0)) 704 { fraction = fp_to_double (filter_index) ; 705 indx = fp_to_int (filter_index) ; 706 assert (indx >= 0 && indx + 1 < filter->coeff_half_len + 2) ; 707 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 708 assert (data_index >= 0 && data_index + 3 < filter->b_len) ; 709 assert (data_index + 3 < filter->b_end) ; 710 for (int ch = 0; ch < 4; ch++) 711 left [ch] += icoeff * filter->buffer [data_index + ch] ; 712 713 filter_index -= increment ; 714 data_index = data_index + 4 ; 715 } ; 716 717 /* Now apply the right half of the filter. */ 718 filter_index = increment - start_filter_index ; 719 coeff_count = (max_filter_index - filter_index) / increment ; 720 filter_index = filter_index + coeff_count * increment ; 721 data_index = filter->b_current + channels * (1 + coeff_count) ; 722 723 right [0] = right [1] = right [2] = right [3] = 0.0 ; 724 do 725 { fraction = fp_to_double (filter_index) ; 726 indx = fp_to_int (filter_index) ; 727 assert (indx >= 0 && indx + 1 < filter->coeff_half_len + 2) ; 728 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 729 assert (data_index >= 0 && data_index + 3 < filter->b_len) ; 730 assert (data_index + 3 < filter->b_end) ; 731 for (int ch = 0; ch < 4; ch++) 732 right [ch] += icoeff * filter->buffer [data_index + ch] ; 733 734 735 filter_index -= increment ; 736 data_index = data_index - 4 ; 737 } 738 while (filter_index > MAKE_INCREMENT_T (0)) ; 739 740 for (int ch = 0; ch < 4; ch++) 741 output [ch] = (float) (scale * (left [ch] + right [ch])) ; 742 } /* calc_output_quad */ 743 744 SRC_ERROR 745 sinc_quad_vari_process (SRC_STATE *state, SRC_DATA *data) 746 { SINC_FILTER *filter ; 747 double input_index, src_ratio, count, float_increment, terminate, rem ; 748 increment_t increment, start_filter_index ; 749 int half_filter_chan_len, samples_in_hand ; 750 751 if (state->private_data == NULL) 752 return SRC_ERR_NO_PRIVATE ; 753 754 filter = (SINC_FILTER*) state->private_data ; 755 756 /* If there is not a problem, this will be optimised out. */ 757 if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) 758 return SRC_ERR_SIZE_INCOMPATIBILITY ; 759 760 filter->in_count = data->input_frames * state->channels ; 761 filter->out_count = data->output_frames * state->channels ; 762 filter->in_used = filter->out_gen = 0 ; 763 764 src_ratio = state->last_ratio ; 765 766 if (is_bad_src_ratio (src_ratio)) 767 return SRC_ERR_BAD_INTERNAL_STATE ; 768 769 /* Check the sample rate ratio wrt the buffer len. */ 770 count = (filter->coeff_half_len + 2.0) / filter->index_inc ; 771 if (MIN (state->last_ratio, data->src_ratio) < 1.0) 772 count /= MIN (state->last_ratio, data->src_ratio) ; 773 774 /* Maximum coefficientson either side of center point. */ 775 half_filter_chan_len = state->channels * (int) (lrint (count) + 1) ; 776 777 input_index = state->last_position ; 778 779 rem = fmod_one (input_index) ; 780 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 781 input_index = rem ; 782 783 terminate = 1.0 / src_ratio + 1e-20 ; 784 785 /* Main processing loop. */ 786 while (filter->out_gen < filter->out_count) 787 { 788 /* Need to reload buffer? */ 789 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 790 791 if (samples_in_hand <= half_filter_chan_len) 792 { if ((state->error = prepare_data (filter, state->channels, data, half_filter_chan_len)) != 0) 793 return state->error ; 794 795 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 796 if (samples_in_hand <= half_filter_chan_len) 797 break ; 798 } ; 799 800 /* This is the termination condition. */ 801 if (filter->b_real_end >= 0) 802 { if (filter->b_current + input_index + terminate >= filter->b_real_end) 803 break ; 804 } ; 805 806 if (filter->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > 1e-10) 807 src_ratio = state->last_ratio + filter->out_gen * (data->src_ratio - state->last_ratio) / filter->out_count ; 808 809 float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ; 810 increment = double_to_fp (float_increment) ; 811 812 start_filter_index = double_to_fp (input_index * float_increment) ; 813 814 calc_output_quad (filter, state->channels, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; 815 filter->out_gen += 4 ; 816 817 /* Figure out the next index. */ 818 input_index += 1.0 / src_ratio ; 819 rem = fmod_one (input_index) ; 820 821 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 822 input_index = rem ; 823 } ; 824 825 state->last_position = input_index ; 826 827 /* Save current ratio rather then target ratio. */ 828 state->last_ratio = src_ratio ; 829 830 data->input_frames_used = filter->in_used / state->channels ; 831 data->output_frames_gen = filter->out_gen / state->channels ; 832 833 return SRC_ERR_NO_ERROR ; 834 } /* sinc_quad_vari_process */ 835 836 static inline void 837 calc_output_hex (SINC_FILTER *filter, int channels, increment_t increment, increment_t start_filter_index, double scale, float * output) 838 { double fraction, left [6], right [6], icoeff ; 839 increment_t filter_index, max_filter_index ; 840 int data_index, coeff_count, indx ; 841 842 /* Convert input parameters into fixed point. */ 843 max_filter_index = int_to_fp (filter->coeff_half_len) ; 844 845 /* First apply the left half of the filter. */ 846 filter_index = start_filter_index ; 847 coeff_count = (max_filter_index - filter_index) / increment ; 848 filter_index = filter_index + coeff_count * increment ; 849 data_index = filter->b_current - channels * coeff_count ; 850 851 if (data_index < 0) /* Avoid underflow access to filter->buffer. */ 852 { int steps = int_div_ceil (-data_index, 6) ; 853 /* If the assert triggers we would have to take care not to underflow/overflow */ 854 assert (steps <= int_div_ceil (filter_index, increment)) ; 855 filter_index -= increment * steps ; 856 data_index += steps * 6; 857 } 858 left [0] = left [1] = left [2] = left [3] = left [4] = left [5] = 0.0 ; 859 while (filter_index >= MAKE_INCREMENT_T (0)) 860 { fraction = fp_to_double (filter_index) ; 861 indx = fp_to_int (filter_index) ; 862 assert (indx >= 0 && indx + 1 < filter->coeff_half_len + 2) ; 863 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 864 assert (data_index >= 0 && data_index + 5 < filter->b_len) ; 865 assert (data_index + 5 < filter->b_end) ; 866 for (int ch = 0; ch < 6; ch++) 867 left [ch] += icoeff * filter->buffer [data_index + ch] ; 868 869 filter_index -= increment ; 870 data_index = data_index + 6 ; 871 } ; 872 873 /* Now apply the right half of the filter. */ 874 filter_index = increment - start_filter_index ; 875 coeff_count = (max_filter_index - filter_index) / increment ; 876 filter_index = filter_index + coeff_count * increment ; 877 data_index = filter->b_current + channels * (1 + coeff_count) ; 878 879 right [0] = right [1] = right [2] = right [3] = right [4] = right [5] = 0.0 ; 880 do 881 { fraction = fp_to_double (filter_index) ; 882 indx = fp_to_int (filter_index) ; 883 assert (indx >= 0 && indx + 1 < filter->coeff_half_len + 2) ; 884 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 885 assert (data_index >= 0 && data_index + 5 < filter->b_len) ; 886 assert (data_index + 5 < filter->b_end) ; 887 for (int ch = 0; ch < 6; ch++) 888 right [ch] += icoeff * filter->buffer [data_index + ch] ; 889 890 filter_index -= increment ; 891 data_index = data_index - 6 ; 892 } 893 while (filter_index > MAKE_INCREMENT_T (0)) ; 894 895 for (int ch = 0; ch < 6; ch++) 896 output [ch] = (float) (scale * (left [ch] + right [ch])) ; 897 } /* calc_output_hex */ 898 899 SRC_ERROR 900 sinc_hex_vari_process (SRC_STATE *state, SRC_DATA *data) 901 { SINC_FILTER *filter ; 902 double input_index, src_ratio, count, float_increment, terminate, rem ; 903 increment_t increment, start_filter_index ; 904 int half_filter_chan_len, samples_in_hand ; 905 906 if (state->private_data == NULL) 907 return SRC_ERR_NO_PRIVATE ; 908 909 filter = (SINC_FILTER*) state->private_data ; 910 911 /* If there is not a problem, this will be optimised out. */ 912 if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) 913 return SRC_ERR_SIZE_INCOMPATIBILITY ; 914 915 filter->in_count = data->input_frames * state->channels ; 916 filter->out_count = data->output_frames * state->channels ; 917 filter->in_used = filter->out_gen = 0 ; 918 919 src_ratio = state->last_ratio ; 920 921 if (is_bad_src_ratio (src_ratio)) 922 return SRC_ERR_BAD_INTERNAL_STATE ; 923 924 /* Check the sample rate ratio wrt the buffer len. */ 925 count = (filter->coeff_half_len + 2.0) / filter->index_inc ; 926 if (MIN (state->last_ratio, data->src_ratio) < 1.0) 927 count /= MIN (state->last_ratio, data->src_ratio) ; 928 929 /* Maximum coefficientson either side of center point. */ 930 half_filter_chan_len = state->channels * (int) (lrint (count) + 1) ; 931 932 input_index = state->last_position ; 933 934 rem = fmod_one (input_index) ; 935 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 936 input_index = rem ; 937 938 terminate = 1.0 / src_ratio + 1e-20 ; 939 940 /* Main processing loop. */ 941 while (filter->out_gen < filter->out_count) 942 { 943 /* Need to reload buffer? */ 944 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 945 946 if (samples_in_hand <= half_filter_chan_len) 947 { if ((state->error = prepare_data (filter, state->channels, data, half_filter_chan_len)) != 0) 948 return state->error ; 949 950 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 951 if (samples_in_hand <= half_filter_chan_len) 952 break ; 953 } ; 954 955 /* This is the termination condition. */ 956 if (filter->b_real_end >= 0) 957 { if (filter->b_current + input_index + terminate >= filter->b_real_end) 958 break ; 959 } ; 960 961 if (filter->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > 1e-10) 962 src_ratio = state->last_ratio + filter->out_gen * (data->src_ratio - state->last_ratio) / filter->out_count ; 963 964 float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ; 965 increment = double_to_fp (float_increment) ; 966 967 start_filter_index = double_to_fp (input_index * float_increment) ; 968 969 calc_output_hex (filter, state->channels, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; 970 filter->out_gen += 6 ; 971 972 /* Figure out the next index. */ 973 input_index += 1.0 / src_ratio ; 974 rem = fmod_one (input_index) ; 975 976 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 977 input_index = rem ; 978 } ; 979 980 state->last_position = input_index ; 981 982 /* Save current ratio rather then target ratio. */ 983 state->last_ratio = src_ratio ; 984 985 data->input_frames_used = filter->in_used / state->channels ; 986 data->output_frames_gen = filter->out_gen / state->channels ; 987 988 return SRC_ERR_NO_ERROR ; 989 } /* sinc_hex_vari_process */ 990 991 static inline void 992 calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int channels, double scale, float * output) 993 { double fraction, icoeff ; 994 /* The following line is 1999 ISO Standard C. If your compiler complains, get a better compiler. */ 995 double *left, *right ; 996 increment_t filter_index, max_filter_index ; 997 int data_index, coeff_count, indx ; 998 999 left = filter->left_calc ; 1000 right = filter->right_calc ; 1001 1002 /* Convert input parameters into fixed point. */ 1003 max_filter_index = int_to_fp (filter->coeff_half_len) ; 1004 1005 /* First apply the left half of the filter. */ 1006 filter_index = start_filter_index ; 1007 coeff_count = (max_filter_index - filter_index) / increment ; 1008 filter_index = filter_index + coeff_count * increment ; 1009 data_index = filter->b_current - channels * coeff_count ; 1010 1011 if (data_index < 0) /* Avoid underflow access to filter->buffer. */ 1012 { int steps = int_div_ceil (-data_index, channels) ; 1013 /* If the assert triggers we would have to take care not to underflow/overflow */ 1014 assert (steps <= int_div_ceil (filter_index, increment)) ; 1015 filter_index -= increment * steps ; 1016 data_index += steps * channels ; 1017 } 1018 1019 memset (left, 0, sizeof (left [0]) * channels) ; 1020 1021 while (filter_index >= MAKE_INCREMENT_T (0)) 1022 { fraction = fp_to_double (filter_index) ; 1023 indx = fp_to_int (filter_index) ; 1024 assert (indx >= 0 && indx + 1 < filter->coeff_half_len + 2) ; 1025 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 1026 1027 assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ; 1028 assert (data_index + channels - 1 < filter->b_end) ; 1029 for (int ch = 0; ch < channels; ch++) 1030 left [ch] += icoeff * filter->buffer [data_index + ch] ; 1031 1032 filter_index -= increment ; 1033 data_index = data_index + channels ; 1034 } ; 1035 1036 /* Now apply the right half of the filter. */ 1037 filter_index = increment - start_filter_index ; 1038 coeff_count = (max_filter_index - filter_index) / increment ; 1039 filter_index = filter_index + coeff_count * increment ; 1040 data_index = filter->b_current + channels * (1 + coeff_count) ; 1041 1042 memset (right, 0, sizeof (right [0]) * channels) ; 1043 do 1044 { fraction = fp_to_double (filter_index) ; 1045 indx = fp_to_int (filter_index) ; 1046 assert (indx >= 0 && indx + 1 < filter->coeff_half_len + 2) ; 1047 icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; 1048 assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ; 1049 assert (data_index + channels - 1 < filter->b_end) ; 1050 for (int ch = 0; ch < channels; ch++) 1051 right [ch] += icoeff * filter->buffer [data_index + ch] ; 1052 1053 filter_index -= increment ; 1054 data_index = data_index - channels ; 1055 } 1056 while (filter_index > MAKE_INCREMENT_T (0)) ; 1057 1058 for(int ch = 0; ch < channels; ch++) 1059 output [ch] = (float) (scale * (left [ch] + right [ch])) ; 1060 1061 return ; 1062 } /* calc_output_multi */ 1063 1064 static SRC_ERROR 1065 sinc_multichan_vari_process (SRC_STATE *state, SRC_DATA *data) 1066 { SINC_FILTER *filter ; 1067 double input_index, src_ratio, count, float_increment, terminate, rem ; 1068 increment_t increment, start_filter_index ; 1069 int half_filter_chan_len, samples_in_hand ; 1070 1071 if (state->private_data == NULL) 1072 return SRC_ERR_NO_PRIVATE ; 1073 1074 filter = (SINC_FILTER*) state->private_data ; 1075 1076 /* If there is not a problem, this will be optimised out. */ 1077 if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) 1078 return SRC_ERR_SIZE_INCOMPATIBILITY ; 1079 1080 filter->in_count = data->input_frames * state->channels ; 1081 filter->out_count = data->output_frames * state->channels ; 1082 filter->in_used = filter->out_gen = 0 ; 1083 1084 src_ratio = state->last_ratio ; 1085 1086 if (is_bad_src_ratio (src_ratio)) 1087 return SRC_ERR_BAD_INTERNAL_STATE ; 1088 1089 /* Check the sample rate ratio wrt the buffer len. */ 1090 count = (filter->coeff_half_len + 2.0) / filter->index_inc ; 1091 if (MIN (state->last_ratio, data->src_ratio) < 1.0) 1092 count /= MIN (state->last_ratio, data->src_ratio) ; 1093 1094 /* Maximum coefficientson either side of center point. */ 1095 half_filter_chan_len = state->channels * (int) (lrint (count) + 1) ; 1096 1097 input_index = state->last_position ; 1098 1099 rem = fmod_one (input_index) ; 1100 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 1101 input_index = rem ; 1102 1103 terminate = 1.0 / src_ratio + 1e-20 ; 1104 1105 /* Main processing loop. */ 1106 while (filter->out_gen < filter->out_count) 1107 { 1108 /* Need to reload buffer? */ 1109 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 1110 1111 if (samples_in_hand <= half_filter_chan_len) 1112 { if ((state->error = prepare_data (filter, state->channels, data, half_filter_chan_len)) != 0) 1113 return state->error ; 1114 1115 samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; 1116 if (samples_in_hand <= half_filter_chan_len) 1117 break ; 1118 } ; 1119 1120 /* This is the termination condition. */ 1121 if (filter->b_real_end >= 0) 1122 { if (filter->b_current + input_index + terminate >= filter->b_real_end) 1123 break ; 1124 } ; 1125 1126 if (filter->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > 1e-10) 1127 src_ratio = state->last_ratio + filter->out_gen * (data->src_ratio - state->last_ratio) / filter->out_count ; 1128 1129 float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ; 1130 increment = double_to_fp (float_increment) ; 1131 1132 start_filter_index = double_to_fp (input_index * float_increment) ; 1133 1134 calc_output_multi (filter, increment, start_filter_index, state->channels, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; 1135 filter->out_gen += state->channels ; 1136 1137 /* Figure out the next index. */ 1138 input_index += 1.0 / src_ratio ; 1139 rem = fmod_one (input_index) ; 1140 1141 filter->b_current = (filter->b_current + state->channels * lrint (input_index - rem)) % filter->b_len ; 1142 input_index = rem ; 1143 } ; 1144 1145 state->last_position = input_index ; 1146 1147 /* Save current ratio rather then target ratio. */ 1148 state->last_ratio = src_ratio ; 1149 1150 data->input_frames_used = filter->in_used / state->channels ; 1151 data->output_frames_gen = filter->out_gen / state->channels ; 1152 1153 return SRC_ERR_NO_ERROR ; 1154 } /* sinc_multichan_vari_process */ 1155 1156 /*---------------------------------------------------------------------------------------- 1157 */ 1158 1159 static SRC_ERROR 1160 prepare_data (SINC_FILTER *filter, int channels, SRC_DATA *data, int half_filter_chan_len) 1161 { int len = 0 ; 1162 1163 if (filter->b_real_end >= 0) 1164 return SRC_ERR_NO_ERROR ; /* Should be terminating. Just return. */ 1165 1166 if (data->data_in == NULL) 1167 return SRC_ERR_NO_ERROR ; 1168 1169 if (filter->b_current == 0) 1170 { /* Initial state. Set up zeros at the start of the buffer and 1171 ** then load new data after that. 1172 */ 1173 len = filter->b_len - 2 * half_filter_chan_len ; 1174 1175 filter->b_current = filter->b_end = half_filter_chan_len ; 1176 } 1177 else if (filter->b_end + half_filter_chan_len + channels < filter->b_len) 1178 { /* Load data at current end position. */ 1179 len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ; 1180 } 1181 else 1182 { /* Move data at end of buffer back to the start of the buffer. */ 1183 len = filter->b_end - filter->b_current ; 1184 memmove (filter->buffer, filter->buffer + filter->b_current - half_filter_chan_len, 1185 (half_filter_chan_len + len) * sizeof (filter->buffer [0])) ; 1186 1187 filter->b_current = half_filter_chan_len ; 1188 filter->b_end = filter->b_current + len ; 1189 1190 /* Now load data at current end of buffer. */ 1191 len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ; 1192 } ; 1193 1194 len = MIN ((int) (filter->in_count - filter->in_used), len) ; 1195 len -= (len % channels) ; 1196 1197 if (len < 0 || filter->b_end + len > filter->b_len) 1198 return SRC_ERR_SINC_PREPARE_DATA_BAD_LEN ; 1199 1200 memcpy (filter->buffer + filter->b_end, data->data_in + filter->in_used, 1201 len * sizeof (filter->buffer [0])) ; 1202 1203 filter->b_end += len ; 1204 filter->in_used += len ; 1205 1206 if (filter->in_used == filter->in_count && 1207 filter->b_end - filter->b_current < 2 * half_filter_chan_len && data->end_of_input) 1208 { /* Handle the case where all data in the current buffer has been 1209 ** consumed and this is the last buffer. 1210 */ 1211 1212 if (filter->b_len - filter->b_end < half_filter_chan_len + 5) 1213 { /* If necessary, move data down to the start of the buffer. */ 1214 len = filter->b_end - filter->b_current ; 1215 memmove (filter->buffer, filter->buffer + filter->b_current - half_filter_chan_len, 1216 (half_filter_chan_len + len) * sizeof (filter->buffer [0])) ; 1217 1218 filter->b_current = half_filter_chan_len ; 1219 filter->b_end = filter->b_current + len ; 1220 } ; 1221 1222 filter->b_real_end = filter->b_end ; 1223 len = half_filter_chan_len + 5 ; 1224 1225 if (len < 0 || filter->b_end + len > filter->b_len) 1226 len = filter->b_len - filter->b_end ; 1227 1228 memset (filter->buffer + filter->b_end, 0, len * sizeof (filter->buffer [0])) ; 1229 filter->b_end += len ; 1230 } ; 1231 1232 return SRC_ERR_NO_ERROR ; 1233 } /* prepare_data */ 1234 1235 static void 1236 sinc_close (SRC_STATE *state) 1237 { 1238 if (state) 1239 { 1240 SINC_FILTER *sinc = (SINC_FILTER *) state->private_data ; 1241 if (sinc) 1242 { 1243 if (sinc->buffer) 1244 { 1245 free (sinc->buffer) ; 1246 sinc->buffer = NULL ; 1247 } 1248 free (sinc) ; 1249 sinc = NULL ; 1250 } 1251 free (state) ; 1252 state = NULL ; 1253 } 1254 } /* sinc_close */ 1255