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