• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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