102
81
static void sinc_reset (SRC_PRIVATE *psrc) ;
104
static coeff_f_t const high_qual_coeffs_f [] =
106
#include "high_qual_coeffs.h"
107
} ; /* high_qual_coeffs */
109
static coeff_f_t const mid_qual_coeffs_f [] =
111
#include "mid_qual_coeffs.h"
112
} ; /* mid_qual_coeffs */
114
static coeff_f_t const fastest_coeffs_f [] =
116
#include "fastest_coeffs.h"
117
} ; /* fastest_coeffs */
119
static coeff_d_t const high_qual_coeffs_d [] =
121
#include "high_qual_coeffs.h"
122
} ; /* high_qual_coeffs */
124
static coeff_d_t const mid_qual_coeffs_d [] =
126
#include "mid_qual_coeffs.h"
127
} ; /* mid_qual_coeffs */
129
static coeff_d_t const fastest_coeffs_d [] =
131
#include "fastest_coeffs.h"
132
} ; /* fastest_coeffs */
83
static inline increment_t
84
double_to_fp (double x)
85
{ if (sizeof (increment_t) == 8)
86
return (llrint ((x) * FP_ONE)) ;
87
return (lrint ((x) * FP_ONE)) ;
90
static inline increment_t
92
{ return (((increment_t) (x)) << SHIFT_BITS) ;
96
fp_to_int (increment_t x)
97
{ return (((x) >> SHIFT_BITS)) ;
100
static inline increment_t
101
fp_fraction_part (increment_t x)
102
{ return ((x) & ((((increment_t) 1) << SHIFT_BITS) - 1)) ;
103
} /* fp_fraction_part */
106
fp_to_double (increment_t x)
107
{ return fp_fraction_part (x) * INV_FP_ONE ;
135
111
/*----------------------------------------------------------------------------------------
139
gavl_sinc_get_name (int src_enum)
142
{ case SRC_SINC_BEST_QUALITY :
143
return "Best Sinc Interpolator" ;
145
case SRC_SINC_MEDIUM_QUALITY :
146
return "Medium Sinc Interpolator" ;
148
case SRC_SINC_FASTEST :
149
return "Fastest Sinc Interpolator" ;
153
} /* sinc_get_descrition */
156
gavl_sinc_get_description (int src_enum)
159
{ case SRC_SINC_BEST_QUALITY :
160
return "Band limited sinc interpolation, best quality, 97dB SNR, 96% BW." ;
162
case SRC_SINC_MEDIUM_QUALITY :
163
return "Band limited sinc interpolation, medium quality, 97dB SNR, 90% BW." ;
165
case SRC_SINC_FASTEST :
166
return "Band limited sinc interpolation, fastest, 97dB SNR, 80% BW." ;
170
} /* sinc_get_descrition */
115
sinc_get_name (int src_enum)
118
{ case SRC_SINC_BEST_QUALITY :
119
return "Best Sinc Interpolator" ;
121
case SRC_SINC_MEDIUM_QUALITY :
122
return "Medium Sinc Interpolator" ;
124
case SRC_SINC_FASTEST :
125
return "Fastest Sinc Interpolator" ;
131
} /* sinc_get_descrition */
134
sinc_get_description (int src_enum)
137
{ case SRC_SINC_FASTEST :
138
return "Band limited sinc interpolation, fastest, 97dB SNR, 80% BW." ;
140
case SRC_SINC_MEDIUM_QUALITY :
141
return "Band limited sinc interpolation, medium quality, 121dB SNR, 90% BW." ;
143
case SRC_SINC_BEST_QUALITY :
144
return "Band limited sinc interpolation, best quality, 145dB SNR, 96% BW." ;
151
} /* sinc_get_descrition */
173
154
gavl_sinc_set_converter (SRC_PRIVATE *psrc, int src_enum, int d)
174
{ SINC_FILTER *filter, temp_filter ;
177
/* Quick sanity check. */
178
if (SHIFT_BITS >= sizeof (increment_t) * 8 - 1)
179
return SRC_ERR_SHIFT_BITS ;
181
if (psrc->private_data != NULL)
182
{ filter = (SINC_FILTER*) psrc->private_data ;
183
if (filter->sinc_magic_marker != SINC_MAGIC_MARKER)
184
{ free (psrc->private_data) ;
185
psrc->private_data = NULL ;
189
memset (&temp_filter, 0, sizeof (temp_filter)) ;
191
temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ;
192
temp_filter.channels = psrc->channels ;
195
psrc->process = sinc_process_d ;
197
psrc->process = sinc_process_f ;
198
psrc->reset = sinc_reset ;
201
{ case SRC_SINC_BEST_QUALITY :
202
temp_filter.coeffs_d = high_qual_coeffs_d ;
203
temp_filter.coeffs_f = high_qual_coeffs_f ;
204
temp_filter.coeff_half_len = ARRAY_LEN (high_qual_coeffs_f) - 1 ;
205
temp_filter.index_inc = 128 ;
206
temp_filter.has_diffs = SRC_FALSE ;
207
temp_filter.coeff_len = ARRAY_LEN (high_qual_coeffs_f) ;
210
case SRC_SINC_MEDIUM_QUALITY :
211
temp_filter.coeffs_d = mid_qual_coeffs_d ;
212
temp_filter.coeffs_f = mid_qual_coeffs_f ;
213
temp_filter.coeff_half_len = ARRAY_LEN (mid_qual_coeffs_f) - 1 ;
214
temp_filter.index_inc = 128 ;
215
temp_filter.has_diffs = SRC_FALSE ;
216
temp_filter.coeff_len = ARRAY_LEN (mid_qual_coeffs_f) ;
219
case SRC_SINC_FASTEST :
220
temp_filter.coeffs_d = fastest_coeffs_d ;
221
temp_filter.coeffs_f = fastest_coeffs_f ;
222
temp_filter.coeff_half_len = ARRAY_LEN (fastest_coeffs_f) - 1 ;
223
temp_filter.index_inc = 128 ;
224
temp_filter.has_diffs = SRC_FALSE ;
225
temp_filter.coeff_len = ARRAY_LEN (fastest_coeffs_f) ;
229
return SRC_ERR_BAD_CONVERTER ;
233
** FIXME : This needs to be looked at more closely to see if there is
234
** a better way. Need to look at prepare_data () at the same time.
237
temp_filter.b_len = 1000 + 2 * lrint (0.5 + temp_filter.coeff_len / (temp_filter.index_inc * 1.0) * SRC_MAX_RATIO) ;
238
temp_filter.b_len *= temp_filter.channels ;
242
if ((filter = calloc (1, sizeof (SINC_FILTER) + sizeof (filter->buffer_d [0]) * (temp_filter.b_len + temp_filter.channels))) == NULL)
243
return SRC_ERR_MALLOC_FAILED ;
247
if ((filter = calloc (1, sizeof (SINC_FILTER) + sizeof (filter->buffer_f [0]) * (temp_filter.b_len + temp_filter.channels))) == NULL)
248
return SRC_ERR_MALLOC_FAILED ;
253
*filter = temp_filter ;
254
memset (&temp_filter, 0xEE, sizeof (temp_filter)) ;
256
psrc->private_data = filter ;
260
count = filter->coeff_half_len ;
261
for (bits = 0 ; (1 << bits) < count ; bits++)
262
count |= (1 << bits) ;
264
if (bits + SHIFT_BITS - 1 >= (int) (sizeof (increment_t) * 8))
265
return SRC_ERR_FILTER_LEN ;
267
return SRC_ERR_NO_ERROR ;
268
} /* sinc_set_converter */
155
{ SINC_FILTER *filter, temp_filter ;
159
/* Quick sanity check. */
160
if (SHIFT_BITS >= sizeof (increment_t) * 8 - 1)
161
return SRC_ERR_SHIFT_BITS ;
163
if (psrc->private_data != NULL)
164
{ filter = (SINC_FILTER*) psrc->private_data ;
165
if (filter->sinc_magic_marker != SINC_MAGIC_MARKER)
166
{ free (psrc->private_data) ;
167
psrc->private_data = NULL ;
171
memset (&temp_filter, 0, sizeof (temp_filter)) ;
173
temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ;
174
temp_filter.channels = psrc->channels ;
177
psrc->const_process = sinc_vari_process_d ;
178
psrc->vari_process = sinc_vari_process_d ;
182
psrc->const_process = sinc_vari_process_f ;
183
psrc->vari_process = sinc_vari_process_f ;
185
psrc->reset = sinc_reset ;
188
{ case SRC_SINC_FASTEST :
189
temp_filter.coeffs = fastest_coeffs.coeffs ;
190
temp_filter.coeff_half_len = ARRAY_LEN (fastest_coeffs.coeffs) - 1 ;
191
temp_filter.index_inc = fastest_coeffs.increment ;
194
case SRC_SINC_MEDIUM_QUALITY :
195
temp_filter.coeffs = slow_mid_qual_coeffs.coeffs ;
196
temp_filter.coeff_half_len = ARRAY_LEN (slow_mid_qual_coeffs.coeffs) - 1 ;
197
temp_filter.index_inc = slow_mid_qual_coeffs.increment ;
200
case SRC_SINC_BEST_QUALITY :
201
temp_filter.coeffs = slow_high_qual_coeffs.coeffs ;
202
temp_filter.coeff_half_len = ARRAY_LEN (slow_high_qual_coeffs.coeffs) - 1 ;
203
temp_filter.index_inc = slow_high_qual_coeffs.increment ;
207
return SRC_ERR_BAD_CONVERTER ;
211
** FIXME : This needs to be looked at more closely to see if there is
212
** a better way. Need to look at prepare_data () at the same time.
215
temp_filter.b_len = 2 * lrint (1.0 + temp_filter.coeff_half_len / (temp_filter.index_inc * 1.0) * SRC_MAX_RATIO) ;
216
temp_filter.b_len = MAX (temp_filter.b_len, 4096) ;
217
temp_filter.b_len *= temp_filter.channels ;
221
if ((filter = calloc (1, sizeof (SINC_FILTER) + sizeof (filter->buffer_d [0]) * (temp_filter.b_len + temp_filter.channels))) == NULL)
222
return SRC_ERR_MALLOC_FAILED ;
227
if ((filter = calloc (1, sizeof (SINC_FILTER) + sizeof (filter->buffer_f [0]) * (temp_filter.b_len + temp_filter.channels))) == NULL)
228
return SRC_ERR_MALLOC_FAILED ;
231
*filter = temp_filter ;
232
memset (&temp_filter, 0xEE, sizeof (temp_filter)) ;
234
psrc->private_data = filter ;
238
count = filter->coeff_half_len ;
239
for (bits = 0 ; (MAKE_INCREMENT_T (1) << bits) < count ; bits++)
240
count |= (MAKE_INCREMENT_T (1) << bits) ;
242
if (bits + SHIFT_BITS - 1 >= (int) (sizeof (increment_t) * 8))
243
return SRC_ERR_FILTER_LEN ;
245
return SRC_ERR_NO_ERROR ;
246
} /* sinc_set_converter */
271
249
sinc_reset (SRC_PRIVATE *psrc)
272
{ SINC_FILTER *filter ;
274
filter = (SINC_FILTER*) psrc->private_data ;
278
filter->b_current = filter->b_end = 0 ;
279
filter->b_real_end = -1 ;
281
filter->src_ratio = filter->input_index = 0.0 ;
284
memset (filter->buffer_f, 0, filter->b_len * sizeof (filter->buffer_f [0])) ;
286
memset (filter->buffer_d, 0, filter->b_len * sizeof (filter->buffer_d [0])) ;
288
/* Set this for a sanity check */
290
memset (filter->buffer_f + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer_f [0])) ;
292
memset (filter->buffer_d + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer_d [0])) ;
250
{ SINC_FILTER *filter ;
252
filter = (SINC_FILTER*) psrc->private_data ;
256
filter->b_current = filter->b_end = 0 ;
257
filter->b_real_end = -1 ;
259
filter->src_ratio = filter->input_index = 0.0 ;
262
memset (filter->buffer_d, 0, filter->b_len * sizeof (filter->buffer_d [0])) ;
263
/* Set this for a sanity check */
264
memset (filter->buffer_d + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer_d [0])) ;
268
memset (filter->buffer_f, 0, filter->b_len * sizeof (filter->buffer_f [0])) ;
269
/* Set this for a sanity check */
270
memset (filter->buffer_f + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer_f [0])) ;
295
275
/*========================================================================================
296
276
** Beware all ye who dare pass this point. There be dragons here.
300
sinc_process_f (SRC_PRIVATE *psrc, SRC_DATA *data)
301
{ SINC_FILTER *filter ;
302
double input_index, src_ratio, count, float_increment, terminate, rem ;
303
increment_t increment, start_filter_index ;
304
int half_filter_chan_len, samples_in_hand, ch ;
306
if (psrc->private_data == NULL)
307
return SRC_ERR_NO_PRIVATE ;
309
filter = (SINC_FILTER*) psrc->private_data ;
311
/* If there is not a problem, this will be optimised out. */
312
if (sizeof (filter->buffer_f [0]) != sizeof (data->data_in_f [0]))
313
return SRC_ERR_SIZE_INCOMPATIBILITY ;
315
filter->in_count = data->input_frames * filter->channels ;
316
filter->out_count = data->output_frames * filter->channels ;
317
filter->in_used = filter->out_gen = 0 ;
319
src_ratio = psrc->last_ratio ;
321
/* Check the sample rate ratio wrt the buffer len. */
322
count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
323
if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
324
count /= MIN (psrc->last_ratio, data->src_ratio) ;
326
/* Maximum coefficientson either side of center point. */
327
half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
329
input_index = psrc->last_position ;
330
float_increment = filter->index_inc ;
332
rem = fmod (input_index, 1.0) ;
333
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
336
terminate = 1.0 / src_ratio + 1e-20 ;
338
/* Main processing loop. */
339
while (filter->out_gen < filter->out_count)
341
/* Need to reload buffer? */
342
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
344
if (samples_in_hand <= half_filter_chan_len)
345
{ prepare_data_f (filter, data, half_filter_chan_len) ;
347
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
348
if (samples_in_hand <= half_filter_chan_len)
352
/* This is the termination condition. */
353
if (filter->b_real_end >= 0)
354
{ if (filter->b_current + input_index + terminate >= filter->b_real_end)
358
if (fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
359
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / (filter->out_count - 1) ;
361
float_increment = filter->index_inc * 1.0 ;
363
float_increment = filter->index_inc * src_ratio ;
365
increment = DOUBLE_TO_FP (float_increment) ;
367
start_filter_index = DOUBLE_TO_FP (input_index * float_increment) ;
369
for (ch = 0 ; ch < filter->channels ; ch++)
370
{ data->data_out_f [filter->out_gen] = (float_increment / filter->index_inc) *
371
calc_output_f (filter, increment, start_filter_index, ch) ;
375
/* Figure out the next index. */
376
input_index += 1.0 / src_ratio ;
377
rem = fmod (input_index, 1.0) ;
379
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
383
psrc->last_position = input_index ;
385
/* Save current ratio rather then target ratio. */
386
psrc->last_ratio = src_ratio ;
388
data->input_frames_used = filter->in_used / filter->channels ;
389
data->output_frames_gen = filter->out_gen / filter->channels ;
391
return SRC_ERR_NO_ERROR ;
280
sinc_vari_process_f (SRC_PRIVATE *psrc, SRC_DATA *data)
281
{ SINC_FILTER *filter ;
282
double input_index, src_ratio, count, float_increment, terminate, rem ;
283
increment_t increment, start_filter_index ;
284
int half_filter_chan_len, samples_in_hand, ch ;
286
if (psrc->private_data == NULL)
287
return SRC_ERR_NO_PRIVATE ;
289
filter = (SINC_FILTER*) psrc->private_data ;
291
/* If there is not a problem, this will be optimised out. */
292
if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
293
return SRC_ERR_SIZE_INCOMPATIBILITY ;
295
filter->in_count = data->input_frames * filter->channels ;
296
filter->out_count = data->output_frames * filter->channels ;
297
filter->in_used = filter->out_gen = 0 ;
299
src_ratio = psrc->last_ratio ;
301
/* Check the sample rate ratio wrt the buffer len. */
302
count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
303
if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
304
count /= MIN (psrc->last_ratio, data->src_ratio) ;
306
/* Maximum coefficientson either side of center point. */
307
half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
309
input_index = psrc->last_position ;
310
float_increment = filter->index_inc ;
312
rem = fmod_one (input_index) ;
313
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
316
terminate = 1.0 / src_ratio + 1e-20 ;
318
/* Main processing loop. */
319
while (filter->out_gen < filter->out_count)
321
/* Need to reload buffer? */
322
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
324
if (samples_in_hand <= half_filter_chan_len)
325
{ prepare_data_f (filter, data, half_filter_chan_len) ;
327
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
328
if (samples_in_hand <= half_filter_chan_len)
332
/* This is the termination condition. */
333
if (filter->b_real_end >= 0)
334
{ if (filter->b_current + input_index + terminate >= filter->b_real_end)
338
if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
339
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
341
float_increment = filter->index_inc * 1.0 ;
343
float_increment = filter->index_inc * src_ratio ;
345
increment = double_to_fp (float_increment) ;
347
start_filter_index = double_to_fp (input_index * float_increment) ;
349
for (ch = 0 ; ch < filter->channels ; ch++)
350
{ data->data_out_f [filter->out_gen] = (float) ((float_increment / filter->index_inc) *
351
calc_output_f (filter, increment, start_filter_index, ch)) ;
355
/* Figure out the next index. */
356
input_index += 1.0 / src_ratio ;
357
rem = fmod_one (input_index) ;
359
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
363
psrc->last_position = input_index ;
365
/* Save current ratio rather then target ratio. */
366
psrc->last_ratio = src_ratio ;
368
data->input_frames_used = filter->in_used / filter->channels ;
369
data->output_frames_gen = filter->out_gen / filter->channels ;
371
return SRC_ERR_NO_ERROR ;
372
} /* sinc_vari_process_f */
395
sinc_process_d (SRC_PRIVATE *psrc, SRC_DATA *data)
396
{ SINC_FILTER *filter ;
397
double input_index, src_ratio, count, float_increment, terminate, rem ;
398
increment_t increment, start_filter_index ;
399
int half_filter_chan_len, samples_in_hand, ch ;
401
if (psrc->private_data == NULL)
402
return SRC_ERR_NO_PRIVATE ;
404
filter = (SINC_FILTER*) psrc->private_data ;
406
/* If there is not a problem, this will be optimised out. */
407
if (sizeof (filter->buffer_d [0]) != sizeof (data->data_in_d [0]))
408
return SRC_ERR_SIZE_INCOMPATIBILITY ;
410
filter->in_count = data->input_frames * filter->channels ;
411
filter->out_count = data->output_frames * filter->channels ;
412
filter->in_used = filter->out_gen = 0 ;
414
src_ratio = psrc->last_ratio ;
416
/* Check the sample rate ratio wrt the buffer len. */
417
count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
418
if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
419
count /= MIN (psrc->last_ratio, data->src_ratio) ;
421
/* Maximum coefficientson either side of center point. */
422
half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
424
input_index = psrc->last_position ;
425
float_increment = filter->index_inc ;
427
rem = fmod (input_index, 1.0) ;
428
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
431
terminate = 1.0 / src_ratio + 1e-20 ;
433
/* Main processing loop. */
434
while (filter->out_gen < filter->out_count)
436
/* Need to reload buffer? */
437
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
439
if (samples_in_hand <= half_filter_chan_len)
440
{ prepare_data_d (filter, data, half_filter_chan_len) ;
442
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
443
if (samples_in_hand <= half_filter_chan_len)
447
/* This is the termination condition. */
448
if (filter->b_real_end >= 0)
449
{ if (filter->b_current + input_index + terminate >= filter->b_real_end)
453
if (fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
454
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / (filter->out_count - 1) ;
456
float_increment = filter->index_inc * 1.0 ;
458
float_increment = filter->index_inc * src_ratio ;
460
increment = DOUBLE_TO_FP (float_increment) ;
462
start_filter_index = DOUBLE_TO_FP (input_index * float_increment) ;
464
for (ch = 0 ; ch < filter->channels ; ch++)
465
{ data->data_out_d [filter->out_gen] = (float_increment / filter->index_inc) *
466
calc_output_d (filter, increment, start_filter_index, ch) ;
470
/* Figure out the next index. */
471
input_index += 1.0 / src_ratio ;
472
rem = fmod (input_index, 1.0) ;
474
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
478
psrc->last_position = input_index ;
480
/* Save current ratio rather then target ratio. */
481
psrc->last_ratio = src_ratio ;
483
data->input_frames_used = filter->in_used / filter->channels ;
484
data->output_frames_gen = filter->out_gen / filter->channels ;
486
return SRC_ERR_NO_ERROR ;
375
sinc_vari_process_d (SRC_PRIVATE *psrc, SRC_DATA *data)
376
{ SINC_FILTER *filter ;
377
double input_index, src_ratio, count, float_increment, terminate, rem ;
378
increment_t increment, start_filter_index ;
379
int half_filter_chan_len, samples_in_hand, ch ;
381
if (psrc->private_data == NULL)
382
return SRC_ERR_NO_PRIVATE ;
384
filter = (SINC_FILTER*) psrc->private_data ;
386
/* If there is not a problem, this will be optimised out. */
387
if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
388
return SRC_ERR_SIZE_INCOMPATIBILITY ;
390
filter->in_count = data->input_frames * filter->channels ;
391
filter->out_count = data->output_frames * filter->channels ;
392
filter->in_used = filter->out_gen = 0 ;
394
src_ratio = psrc->last_ratio ;
396
/* Check the sample rate ratio wrt the buffer len. */
397
count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
398
if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
399
count /= MIN (psrc->last_ratio, data->src_ratio) ;
401
/* Maximum coefficientson either side of center point. */
402
half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
404
input_index = psrc->last_position ;
405
float_increment = filter->index_inc ;
407
rem = fmod_one (input_index) ;
408
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
411
terminate = 1.0 / src_ratio + 1e-20 ;
413
/* Main processing loop. */
414
while (filter->out_gen < filter->out_count)
416
/* Need to reload buffer? */
417
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
419
if (samples_in_hand <= half_filter_chan_len)
420
{ prepare_data_d (filter, data, half_filter_chan_len) ;
422
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
423
if (samples_in_hand <= half_filter_chan_len)
427
/* This is the termination condition. */
428
if (filter->b_real_end >= 0)
429
{ if (filter->b_current + input_index + terminate >= filter->b_real_end)
433
if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
434
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
436
float_increment = filter->index_inc * 1.0 ;
438
float_increment = filter->index_inc * src_ratio ;
440
increment = double_to_fp (float_increment) ;
442
start_filter_index = double_to_fp (input_index * float_increment) ;
444
for (ch = 0 ; ch < filter->channels ; ch++)
445
{ data->data_out_d [filter->out_gen] = (float) ((float_increment / filter->index_inc) *
446
calc_output_d (filter, increment, start_filter_index, ch)) ;
450
/* Figure out the next index. */
451
input_index += 1.0 / src_ratio ;
452
rem = fmod_one (input_index) ;
454
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
458
psrc->last_position = input_index ;
460
/* Save current ratio rather then target ratio. */
461
psrc->last_ratio = src_ratio ;
463
data->input_frames_used = filter->in_used / filter->channels ;
464
data->output_frames_gen = filter->out_gen / filter->channels ;
466
return SRC_ERR_NO_ERROR ;
467
} /* sinc_vari_process_d */
490
470
/*----------------------------------------------------------------------------------------
494
474
prepare_data_f (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len)
497
if (filter->b_real_end >= 0)
498
return ; /* This doesn't make sense, so return. */
500
if (filter->b_current == 0)
501
{ /* Initial state. Set up zeros at the start of the buffer and
502
** then load new data after that.
504
len = filter->b_len - 2 * half_filter_chan_len ;
506
filter->b_current = filter->b_end = half_filter_chan_len ;
508
else if (filter->b_end + half_filter_chan_len + filter->channels < filter->b_len)
509
{ /* Load data at current end position. */
510
len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
513
{ /* Move data at end of buffer back to the start of the buffer. */
514
len = filter->b_end - filter->b_current ;
515
memmove (filter->buffer_f, filter->buffer_f + filter->b_current - half_filter_chan_len,
516
(half_filter_chan_len + len) * sizeof (filter->buffer_f [0])) ;
518
filter->b_current = half_filter_chan_len ;
519
filter->b_end = filter->b_current + len ;
521
/* Now load data at current end of buffer. */
522
len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
525
len = MIN (filter->in_count - filter->in_used, len) ;
526
len -= (len % filter->channels) ;
528
memcpy (filter->buffer_f + filter->b_end, data->data_in_f + filter->in_used,
529
len * sizeof (filter->buffer_f [0])) ;
531
filter->b_end += len ;
532
filter->in_used += len ;
534
if (filter->in_used == filter->in_count &&
535
filter->b_end - filter->b_current < 2 * half_filter_chan_len && data->end_of_input)
536
{ /* Handle the case where all data in the current buffer has been
537
** consumed and this is the last buffer.
540
if (filter->b_len - filter->b_end < half_filter_chan_len + 5)
541
{ /* If necessary, move data down to the start of the buffer. */
542
len = filter->b_end - filter->b_current ;
543
memmove (filter->buffer_f, filter->buffer_f + filter->b_current - half_filter_chan_len,
544
(half_filter_chan_len + len) * sizeof (filter->buffer_f [0])) ;
546
filter->b_current = half_filter_chan_len ;
547
filter->b_end = filter->b_current + len ;
550
filter->b_real_end = filter->b_end ;
551
len = half_filter_chan_len + 5 ;
553
memset (filter->buffer_f + filter->b_end, 0, len * sizeof (filter->buffer_f [0])) ;
554
filter->b_end += len ;
558
} /* prepare_data_f */
477
if (filter->b_real_end >= 0)
478
return ; /* This doesn't make sense, so return. */
480
if (filter->b_current == 0)
481
{ /* Initial state. Set up zeros at the start of the buffer and
482
** then load new data after that.
484
len = filter->b_len - 2 * half_filter_chan_len ;
486
filter->b_current = filter->b_end = half_filter_chan_len ;
488
else if (filter->b_end + half_filter_chan_len + filter->channels < filter->b_len)
489
{ /* Load data at current end position. */
490
len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
493
{ /* Move data at end of buffer back to the start of the buffer. */
494
len = filter->b_end - filter->b_current ;
495
memmove (filter->buffer_f, filter->buffer_f + filter->b_current - half_filter_chan_len,
496
(half_filter_chan_len + len) * sizeof (filter->buffer_f [0])) ;
498
filter->b_current = half_filter_chan_len ;
499
filter->b_end = filter->b_current + len ;
501
/* Now load data at current end of buffer. */
502
len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
505
len = MIN (filter->in_count - filter->in_used, len) ;
506
len -= (len % filter->channels) ;
508
memcpy (filter->buffer_f + filter->b_end, data->data_in_f + filter->in_used,
509
len * sizeof (filter->buffer_f [0])) ;
511
filter->b_end += len ;
512
filter->in_used += len ;
514
if (filter->in_used == filter->in_count &&
515
filter->b_end - filter->b_current < 2 * half_filter_chan_len && data->end_of_input)
516
{ /* Handle the case where all data in the current buffer has been
517
** consumed and this is the last buffer.
520
if (filter->b_len - filter->b_end < half_filter_chan_len + 5)
521
{ /* If necessary, move data down to the start of the buffer. */
522
len = filter->b_end - filter->b_current ;
523
memmove (filter->buffer_f, filter->buffer_f + filter->b_current - half_filter_chan_len,
524
(half_filter_chan_len + len) * sizeof (filter->buffer_f [0])) ;
526
filter->b_current = half_filter_chan_len ;
527
filter->b_end = filter->b_current + len ;
530
filter->b_real_end = filter->b_end ;
531
len = half_filter_chan_len + 5 ;
533
memset (filter->buffer_f + filter->b_end, 0, len * sizeof (filter->buffer_f [0])) ;
534
filter->b_end += len ;
538
} /* prepare_data_f */
561
541
prepare_data_d (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len)
564
if (filter->b_real_end >= 0)
565
return ; /* This doesn't make sense, so return. */
567
if (filter->b_current == 0)
568
{ /* Initial state. Set up zeros at the start of the buffer and
569
** then load new data after that.
571
len = filter->b_len - 2 * half_filter_chan_len ;
573
filter->b_current = filter->b_end = half_filter_chan_len ;
575
else if (filter->b_end + half_filter_chan_len + filter->channels < filter->b_len)
576
{ /* Load data at current end position. */
577
len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
580
{ /* Move data at end of buffer back to the start of the buffer. */
581
len = filter->b_end - filter->b_current ;
582
memmove (filter->buffer_d, filter->buffer_d + filter->b_current - half_filter_chan_len,
583
(half_filter_chan_len + len) * sizeof (filter->buffer_d [0])) ;
585
filter->b_current = half_filter_chan_len ;
586
filter->b_end = filter->b_current + len ;
588
/* Now load data at current end of buffer. */
589
len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
592
len = MIN (filter->in_count - filter->in_used, len) ;
593
len -= (len % filter->channels) ;
595
memcpy (filter->buffer_d + filter->b_end, data->data_in_d + filter->in_used,
596
len * sizeof (filter->buffer_d [0])) ;
598
filter->b_end += len ;
599
filter->in_used += len ;
601
if (filter->in_used == filter->in_count &&
602
filter->b_end - filter->b_current < 2 * half_filter_chan_len && data->end_of_input)
603
{ /* Handle the case where all data in the current buffer has been
604
** consumed and this is the last buffer.
607
if (filter->b_len - filter->b_end < half_filter_chan_len + 5)
608
{ /* If necessary, move data down to the start of the buffer. */
609
len = filter->b_end - filter->b_current ;
610
memmove (filter->buffer_d, filter->buffer_d + filter->b_current - half_filter_chan_len,
611
(half_filter_chan_len + len) * sizeof (filter->buffer_d [0])) ;
613
filter->b_current = half_filter_chan_len ;
614
filter->b_end = filter->b_current + len ;
617
filter->b_real_end = filter->b_end ;
618
len = half_filter_chan_len + 5 ;
620
memset (filter->buffer_d + filter->b_end, 0, len * sizeof (filter->buffer_d [0])) ;
621
filter->b_end += len ;
625
} /* prepare_data_d */
544
if (filter->b_real_end >= 0)
545
return ; /* This doesn't make sense, so return. */
547
if (filter->b_current == 0)
548
{ /* Initial state. Set up zeros at the start of the buffer and
549
** then load new data after that.
551
len = filter->b_len - 2 * half_filter_chan_len ;
553
filter->b_current = filter->b_end = half_filter_chan_len ;
555
else if (filter->b_end + half_filter_chan_len + filter->channels < filter->b_len)
556
{ /* Load data at current end position. */
557
len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
560
{ /* Move data at end of buffer back to the start of the buffer. */
561
len = filter->b_end - filter->b_current ;
562
memmove (filter->buffer_d, filter->buffer_d + filter->b_current - half_filter_chan_len,
563
(half_filter_chan_len + len) * sizeof (filter->buffer_d [0])) ;
565
filter->b_current = half_filter_chan_len ;
566
filter->b_end = filter->b_current + len ;
568
/* Now load data at current end of buffer. */
569
len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
572
len = MIN (filter->in_count - filter->in_used, len) ;
573
len -= (len % filter->channels) ;
575
memcpy (filter->buffer_d + filter->b_end, data->data_in_d + filter->in_used,
576
len * sizeof (filter->buffer_d [0])) ;
578
filter->b_end += len ;
579
filter->in_used += len ;
581
if (filter->in_used == filter->in_count &&
582
filter->b_end - filter->b_current < 2 * half_filter_chan_len && data->end_of_input)
583
{ /* Handle the case where all data in the current buffer has been
584
** consumed and this is the last buffer.
587
if (filter->b_len - filter->b_end < half_filter_chan_len + 5)
588
{ /* If necessary, move data down to the start of the buffer. */
589
len = filter->b_end - filter->b_current ;
590
memmove (filter->buffer_d, filter->buffer_d + filter->b_current - half_filter_chan_len,
591
(half_filter_chan_len + len) * sizeof (filter->buffer_d [0])) ;
593
filter->b_current = half_filter_chan_len ;
594
filter->b_end = filter->b_current + len ;
597
filter->b_real_end = filter->b_end ;
598
len = half_filter_chan_len + 5 ;
600
memset (filter->buffer_d + filter->b_end, 0, len * sizeof (filter->buffer_d [0])) ;
601
filter->b_end += len ;
605
} /* prepare_data_d */
630
610
calc_output_f (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch)
631
{ double fraction, left, right, icoeff ;
632
increment_t filter_index, max_filter_index ;
633
int data_index, coeff_count, indx ;
635
/* Convert input parameters into fixed point. */
636
max_filter_index = INT_TO_FP (filter->coeff_half_len) ;
638
/* First apply the left half of the filter. */
639
filter_index = start_filter_index ;
640
coeff_count = (max_filter_index - filter_index) / increment ;
641
filter_index = filter_index + coeff_count * increment ;
642
data_index = filter->b_current - filter->channels * coeff_count ;
646
{ fraction = FP_TO_DOUBLE (filter_index) ;
647
indx = FP_TO_INT (filter_index) ;
649
icoeff = filter->coeffs_f [indx] + fraction * (filter->coeffs_f [indx + 1] - filter->coeffs_f [indx]) ;
651
left += icoeff * filter->buffer_f [data_index + ch] ;
653
filter_index -= increment ;
654
data_index = data_index + filter->channels ;
656
while (filter_index >= MAKE_INCREMENT_T (0)) ;
658
/* Now apply the right half of the filter. */
659
filter_index = increment - start_filter_index ;
660
coeff_count = (max_filter_index - filter_index) / increment ;
661
filter_index = filter_index + coeff_count * increment ;
662
data_index = filter->b_current + filter->channels * (1 + coeff_count) ;
666
{ fraction = FP_TO_DOUBLE (filter_index) ;
667
indx = FP_TO_INT (filter_index) ;
669
icoeff = filter->coeffs_f [indx] + fraction * (filter->coeffs_f [indx + 1] - filter->coeffs_f [indx]) ;
671
right += icoeff * filter->buffer_f [data_index + ch] ;
673
filter_index -= increment ;
674
data_index = data_index - filter->channels ;
676
while (filter_index > MAKE_INCREMENT_T (0)) ;
678
return (left + right) ;
611
{ double fraction, left, right, icoeff ;
612
increment_t filter_index, max_filter_index ;
613
int data_index, coeff_count, indx ;
615
/* Convert input parameters into fixed point. */
616
max_filter_index = int_to_fp (filter->coeff_half_len) ;
618
/* First apply the left half of the filter. */
619
filter_index = start_filter_index ;
620
coeff_count = (max_filter_index - filter_index) / increment ;
621
filter_index = filter_index + coeff_count * increment ;
622
data_index = filter->b_current - filter->channels * coeff_count + ch ;
626
{ fraction = fp_to_double (filter_index) ;
627
indx = fp_to_int (filter_index) ;
629
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
631
left += icoeff * filter->buffer_f [data_index] ;
633
filter_index -= increment ;
634
data_index = data_index + filter->channels ;
636
while (filter_index >= MAKE_INCREMENT_T (0)) ;
638
/* Now apply the right half of the filter. */
639
filter_index = increment - start_filter_index ;
640
coeff_count = (max_filter_index - filter_index) / increment ;
641
filter_index = filter_index + coeff_count * increment ;
642
data_index = filter->b_current + filter->channels * (1 + coeff_count) + ch ;
646
{ fraction = fp_to_double (filter_index) ;
647
indx = fp_to_int (filter_index) ;
649
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
651
right += icoeff * filter->buffer_f [data_index] ;
653
filter_index -= increment ;
654
data_index = data_index - filter->channels ;
656
while (filter_index > MAKE_INCREMENT_T (0)) ;
658
return (left + right) ;
659
} /* calc_output_f */
682
662
calc_output_d (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch)
683
{ double fraction, left, right, icoeff ;
684
increment_t filter_index, max_filter_index ;
685
int data_index, coeff_count, indx ;
687
/* Convert input parameters into fixed point. */
688
max_filter_index = INT_TO_FP (filter->coeff_half_len) ;
690
/* First apply the left half of the filter. */
691
filter_index = start_filter_index ;
692
coeff_count = (max_filter_index - filter_index) / increment ;
693
filter_index = filter_index + coeff_count * increment ;
694
data_index = filter->b_current - filter->channels * coeff_count ;
698
{ fraction = FP_TO_DOUBLE (filter_index) ;
699
indx = FP_TO_INT (filter_index) ;
701
icoeff = filter->coeffs_d [indx] + fraction * (filter->coeffs_d [indx + 1] - filter->coeffs_d [indx]) ;
703
left += icoeff * filter->buffer_d [data_index + ch] ;
705
filter_index -= increment ;
706
data_index = data_index + filter->channels ;
708
while (filter_index >= MAKE_INCREMENT_T (0)) ;
710
/* Now apply the right half of the filter. */
711
filter_index = increment - start_filter_index ;
712
coeff_count = (max_filter_index - filter_index) / increment ;
713
filter_index = filter_index + coeff_count * increment ;
714
data_index = filter->b_current + filter->channels * (1 + coeff_count) ;
718
{ fraction = FP_TO_DOUBLE (filter_index) ;
719
indx = FP_TO_INT (filter_index) ;
721
icoeff = filter->coeffs_d [indx] + fraction * (filter->coeffs_d [indx + 1] - filter->coeffs_d [indx]) ;
723
right += icoeff * filter->buffer_d [data_index + ch] ;
725
filter_index -= increment ;
726
data_index = data_index - filter->channels ;
728
while (filter_index > MAKE_INCREMENT_T (0)) ;
730
return (left + right) ;
735
** Do not edit or modify anything in this comment block.
736
** The arch-tag line is a file identity tag for the GNU Arch
737
** revision control system.
739
** arch-tag: db8efe06-2fbd-487e-be8f-bfc01e68c19f
663
{ double fraction, left, right, icoeff ;
664
increment_t filter_index, max_filter_index ;
665
int data_index, coeff_count, indx ;
667
/* Convert input parameters into fixed point. */
668
max_filter_index = int_to_fp (filter->coeff_half_len) ;
670
/* First apply the left half of the filter. */
671
filter_index = start_filter_index ;
672
coeff_count = (max_filter_index - filter_index) / increment ;
673
filter_index = filter_index + coeff_count * increment ;
674
data_index = filter->b_current - filter->channels * coeff_count + ch ;
678
{ fraction = fp_to_double (filter_index) ;
679
indx = fp_to_int (filter_index) ;
681
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
683
left += icoeff * filter->buffer_d [data_index] ;
685
filter_index -= increment ;
686
data_index = data_index + filter->channels ;
688
while (filter_index >= MAKE_INCREMENT_T (0)) ;
690
/* Now apply the right half of the filter. */
691
filter_index = increment - start_filter_index ;
692
coeff_count = (max_filter_index - filter_index) / increment ;
693
filter_index = filter_index + coeff_count * increment ;
694
data_index = filter->b_current + filter->channels * (1 + coeff_count) + ch ;
698
{ fraction = fp_to_double (filter_index) ;
699
indx = fp_to_int (filter_index) ;
701
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
703
right += icoeff * filter->buffer_d [data_index] ;
705
filter_index -= increment ;
706
data_index = data_index - filter->channels ;
708
while (filter_index > MAKE_INCREMENT_T (0)) ;
710
return (left + right) ;
711
} /* calc_output_d */