Showing the changes to src (1 of 2 files). Show all
Unified · Split
| @@ -68,9 +68,8 @@ typedef struct · 67 unmodified lines | |||
| 68 | float buffer [1] ; | 68 | float buffer [1] ; |
| 69 | } SINC_FILTER ; | 69 | } SINC_FILTER ; |
| 70 | 70 | ||
| 71 | static int sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; | 71 | static int sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; |
| 72 | 72 | static int sinc_1chan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; | |
| 73 | static double calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) ; | ||
| 74 | 73 | ||
| 75 | static void prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) ; | 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 | temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ; | 166 | temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ; |
| 168 | temp_filter.channels = psrc->channels ; | 167 | temp_filter.channels = psrc->channels ; |
| 169 | 168 | ||
| 170 | psrc->const_process = sinc_vari_process ; | 169 | if (psrc->channels == 1) |
| 171 | psrc->vari_process = sinc_vari_process ; | 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 | psrc->reset = sinc_reset ; | 177 | psrc->reset = sinc_reset ; |
| 173 | 178 | ||
| 174 | switch (src_enum) | 179 | switch (src_enum) |
| @@ -246,8 +251,205 @@ sinc_reset (SRC_PRIVATE *psrc) · 71 unmodified lines | |||
| 246 | ** Beware all ye who dare pass this point. There be dragons here. | 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 | static int | 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 | { SINC_FILTER *filter ; | 453 | { SINC_FILTER *filter ; |
| 252 | double input_index, src_ratio, count, float_increment, terminate, rem ; | 454 | double input_index, src_ratio, count, float_increment, terminate, rem ; |
| 253 | increment_t increment, start_filter_index ; | 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 | for (ch = 0 ; ch < filter->channels ; ch++) | 521 | for (ch = 0 ; ch < filter->channels ; ch++) |
| 320 | { data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) * | 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 | filter->out_gen ++ ; | 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 | data->output_frames_gen = filter->out_gen / filter->channels ; | 541 | data->output_frames_gen = filter->out_gen / filter->channels ; |
| 340 | 542 | ||
| 341 | return SRC_ERR_NO_ERROR ; | 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 | } /* prepare_data */ | 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 | |||