Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libsamplerate/src_sinc.c
39475 views
1
/*
2
** Copyright (c) 2002-2021, Erik de Castro Lopo <[email protected]>
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
134
double_to_fp (double x)
135
{ return (increment_t) (lrint ((x) * FP_ONE)) ;
136
} /* double_to_fp */
137
138
static inline increment_t
139
int_to_fp (int x)
140
{ return (((increment_t) (x)) << SHIFT_BITS) ;
141
} /* int_to_fp */
142
143
static inline int
144
fp_to_int (increment_t x)
145
{ return (((x) >> SHIFT_BITS)) ;
146
} /* fp_to_int */
147
148
static inline increment_t
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
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
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 *
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 *
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
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
1256