xref: /freebsd/contrib/libsamplerate/src_sinc.c (revision 1480c0b3f2daa048fb3763f589302f613ff2ae54)
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