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) (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 #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 *
sinc_filter_new(int converter_type,int channels)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 *
sinc_state_new(int converter_type,int channels,SRC_ERROR * error)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
sinc_reset(SRC_STATE * state)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 *
sinc_copy(SRC_STATE * 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
calc_output_single(SINC_FILTER * filter,increment_t increment,increment_t start_filter_index)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
sinc_mono_vari_process(SRC_STATE * state,SRC_DATA * data)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
calc_output_stereo(SINC_FILTER * filter,int channels,increment_t increment,increment_t start_filter_index,double scale,float * output)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
sinc_stereo_vari_process(SRC_STATE * state,SRC_DATA * data)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
calc_output_quad(SINC_FILTER * filter,int channels,increment_t increment,increment_t start_filter_index,double scale,float * output)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
sinc_quad_vari_process(SRC_STATE * state,SRC_DATA * data)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
calc_output_hex(SINC_FILTER * filter,int channels,increment_t increment,increment_t start_filter_index,double scale,float * output)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
sinc_hex_vari_process(SRC_STATE * state,SRC_DATA * data)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
calc_output_multi(SINC_FILTER * filter,increment_t increment,increment_t start_filter_index,int channels,double scale,float * output)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
sinc_multichan_vari_process(SRC_STATE * state,SRC_DATA * data)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
prepare_data(SINC_FILTER * filter,int channels,SRC_DATA * data,int half_filter_chan_len)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
sinc_close(SRC_STATE * state)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