~ubuntu-branches/ubuntu/trusty/gavl/trusty

« back to all changes in this revision

Viewing changes to gavl/libsamplerate/src_sinc.c

  • Committer: Bazaar Package Importer
  • Author(s): Romain Beauxis
  • Date: 2009-01-17 20:38:33 UTC
  • mfrom: (1.1.3 upstream) (4.1.1 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090117203833-t8fq1e1jdquyelmy
Tags: 1.1.0-2
Fixed debian/copyright 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
 
2
** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
3
3
**
4
4
** This program is free software; you can redistribute it and/or modify
5
5
** it under the terms of the GNU General Public License as published by
16
16
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17
17
*/
18
18
 
 
19
/*
 
20
** This code is part of Secret Rabibt Code aka libsamplerate. A commercial
 
21
** use license for this code is available, please see:
 
22
**              http://www.mega-nerd.com/SRC/procedure.html
 
23
*/
 
24
 
19
25
#include <stdio.h>
20
26
#include <stdlib.h>
21
27
#include <string.h>
22
28
 
23
29
#include "config.h"
24
 
#include "float_cast.h"
25
30
#include "common.h"
26
31
 
27
32
#define SINC_MAGIC_MARKER       MAKE_MAGIC (' ', 's', 'i', 'n', 'c', ' ')
28
33
 
29
 
#define ARRAY_LEN(x)            ((int) (sizeof (x) / sizeof ((x) [0])))
30
 
 
31
34
/*========================================================================================
32
 
**      Macros for handling the index into the array for the filter.
33
 
**      Double precision floating point is not accurate enough so use a 64 bit
34
 
**      fixed point value instead. SHIFT_BITS (current value of 48) is the number
35
 
**      of bits to the right of the decimal point.
36
 
**      The rest of the macros are for retrieving the fractional and integer parts
37
 
**      and for converting floats and ints to the fixed point format or from the
38
 
**      fixed point type back to integers and floats.
39
35
*/
40
36
 
41
37
#define MAKE_INCREMENT_T(x)     ((increment_t) (x))
42
38
 
43
 
#define SHIFT_BITS                              16
 
39
#define SHIFT_BITS                              12
44
40
#define FP_ONE                                  ((double) (((increment_t) 1) << SHIFT_BITS))
45
 
 
46
 
#define DOUBLE_TO_FP(x)                 (lrint ((x) * FP_ONE))
47
 
#define INT_TO_FP(x)                    (((increment_t) (x)) << SHIFT_BITS)
48
 
 
49
 
#define FP_FRACTION_PART(x)             ((x) & ((((increment_t) 1) << SHIFT_BITS) - 1))
50
 
#define FP_INTEGER_PART(x)              ((x) & (((increment_t) -1) << SHIFT_BITS))
51
 
 
52
 
#define FP_TO_INT(x)                    (((x) >> SHIFT_BITS))
53
 
#define FP_TO_DOUBLE(x)                 (FP_FRACTION_PART (x) / FP_ONE)
 
41
#define INV_FP_ONE                              (1.0 / FP_ONE)
54
42
 
55
43
/*========================================================================================
56
 
 */
 
44
*/
57
45
 
58
46
typedef int32_t increment_t ;
59
 
typedef float   coeff_f_t ;
60
 
typedef double  coeff_d_t ;
 
47
typedef double  coeff_t ;
61
48
 
62
 
enum
63
 
  {
64
 
    STATE_BUFFER_START  = 101,
65
 
    STATE_DATA_CONTINUE = 102,
66
 
    STATE_BUFFER_END    = 103,
67
 
    STATE_FINISHED
68
 
  } ;
 
49
#include "fastest_coeffs.h"
 
50
#include "mid_qual_coeffs.h"
 
51
#include "high_qual_coeffs.h"
69
52
 
70
53
typedef struct
71
 
  {     int             sinc_magic_marker ;
72
 
 
73
 
  int           channels ;
74
 
  long  in_count, in_used ;
75
 
  long  out_count, out_gen ;
76
 
 
77
 
  int           coeff_half_len, index_inc ;
78
 
  int           has_diffs ;
79
 
 
80
 
  double        src_ratio, input_index ;
81
 
 
82
 
  int           coeff_len ;
83
 
  coeff_f_t const *coeffs_f ;
84
 
  coeff_d_t const *coeffs_d ;
85
 
 
86
 
  int           b_current, b_end, b_real_end, b_len ;
87
 
  int d;
88
 
  float  buffer_f [1] ;
89
 
  double buffer_d [1] ;
90
 
 
91
 
  } SINC_FILTER ;
92
 
 
93
 
static int sinc_process_f (SRC_PRIVATE *psrc, SRC_DATA *data) ;
94
 
static int sinc_process_d (SRC_PRIVATE *psrc, SRC_DATA *data) ;
 
54
{       int             sinc_magic_marker ;
 
55
 
 
56
        int             channels ;
 
57
        long    in_count, in_used ;
 
58
        long    out_count, out_gen ;
 
59
 
 
60
        int             coeff_half_len, index_inc ;
 
61
 
 
62
        double  src_ratio, input_index ;
 
63
 
 
64
        coeff_t const   *coeffs ;
 
65
 
 
66
        int             b_current, b_end, b_real_end, b_len ;
 
67
        int d;
 
68
        float   buffer_f [1] ;
 
69
        double  buffer_d [1] ;
 
70
} SINC_FILTER ;
 
71
 
 
72
static int sinc_vari_process_d (SRC_PRIVATE *psrc, SRC_DATA *data) ;
 
73
static int sinc_vari_process_f (SRC_PRIVATE *psrc, SRC_DATA *data) ;
95
74
 
96
75
static double calc_output_f (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) ;
97
76
static double calc_output_d (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) ;
101
80
 
102
81
static void sinc_reset (SRC_PRIVATE *psrc) ;
103
82
 
104
 
static coeff_f_t const high_qual_coeffs_f [] =
105
 
  {
106
 
#include "high_qual_coeffs.h"
107
 
  } ; /* high_qual_coeffs */
108
 
 
109
 
static coeff_f_t const mid_qual_coeffs_f [] =
110
 
  {
111
 
#include "mid_qual_coeffs.h"
112
 
  } ; /* mid_qual_coeffs */
113
 
 
114
 
static coeff_f_t const fastest_coeffs_f [] =
115
 
  {
116
 
#include "fastest_coeffs.h"
117
 
  } ; /* fastest_coeffs */
118
 
 
119
 
static coeff_d_t const high_qual_coeffs_d [] =
120
 
  {
121
 
#include "high_qual_coeffs.h"
122
 
  } ; /* high_qual_coeffs */
123
 
 
124
 
static coeff_d_t const mid_qual_coeffs_d [] =
125
 
  {
126
 
#include "mid_qual_coeffs.h"
127
 
  } ; /* mid_qual_coeffs */
128
 
 
129
 
static coeff_d_t const fastest_coeffs_d [] =
130
 
  {
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)) ;
 
88
} /* double_to_fp */
 
89
 
 
90
static inline increment_t
 
91
int_to_fp (int x)
 
92
{       return (((increment_t) (x)) << SHIFT_BITS) ;
 
93
} /* int_to_fp */
 
94
 
 
95
static inline int
 
96
fp_to_int (increment_t x)
 
97
{       return (((x) >> SHIFT_BITS)) ;
 
98
} /* fp_to_int */
 
99
 
 
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 */
 
104
 
 
105
static inline double
 
106
fp_to_double (increment_t x)
 
107
{       return fp_fraction_part (x) * INV_FP_ONE ;
 
108
} /* fp_to_double */
133
109
 
134
110
 
135
111
/*----------------------------------------------------------------------------------------
136
 
 */
137
 
 
138
 
const char*
139
 
gavl_sinc_get_name (int src_enum)
140
 
  {
141
 
  switch (src_enum)
142
 
    {   case SRC_SINC_BEST_QUALITY :
143
 
          return "Best Sinc Interpolator" ;
144
 
 
145
 
    case SRC_SINC_MEDIUM_QUALITY :
146
 
      return "Medium Sinc Interpolator" ;
147
 
 
148
 
    case SRC_SINC_FASTEST :
149
 
      return "Fastest Sinc Interpolator" ;
150
 
    } ;
151
 
 
152
 
  return NULL ;
153
 
  } /* sinc_get_descrition */
154
 
 
155
 
const char*
156
 
gavl_sinc_get_description (int src_enum)
157
 
  {
158
 
  switch (src_enum)
159
 
    {   case SRC_SINC_BEST_QUALITY :
160
 
          return "Band limited sinc interpolation, best quality, 97dB SNR, 96% BW." ;
161
 
 
162
 
    case SRC_SINC_MEDIUM_QUALITY :
163
 
      return "Band limited sinc interpolation, medium quality, 97dB SNR, 90% BW." ;
164
 
 
165
 
    case SRC_SINC_FASTEST :
166
 
      return "Band limited sinc interpolation, fastest, 97dB SNR, 80% BW." ;
167
 
    } ;
168
 
 
169
 
  return NULL ;
170
 
  } /* sinc_get_descrition */
 
112
*/
 
113
 
 
114
const char*
 
115
sinc_get_name (int src_enum)
 
116
{
 
117
        switch (src_enum)
 
118
        {       case SRC_SINC_BEST_QUALITY :
 
119
                        return "Best Sinc Interpolator" ;
 
120
 
 
121
                case SRC_SINC_MEDIUM_QUALITY :
 
122
                        return "Medium Sinc Interpolator" ;
 
123
 
 
124
                case SRC_SINC_FASTEST :
 
125
                        return "Fastest Sinc Interpolator" ;
 
126
 
 
127
                default: break ;
 
128
                } ;
 
129
 
 
130
        return NULL ;
 
131
} /* sinc_get_descrition */
 
132
 
 
133
const char*
 
134
sinc_get_description (int src_enum)
 
135
{
 
136
        switch (src_enum)
 
137
        {       case SRC_SINC_FASTEST :
 
138
                        return "Band limited sinc interpolation, fastest, 97dB SNR, 80% BW." ;
 
139
 
 
140
                case SRC_SINC_MEDIUM_QUALITY :
 
141
                        return "Band limited sinc interpolation, medium quality, 121dB SNR, 90% BW." ;
 
142
 
 
143
                case SRC_SINC_BEST_QUALITY :
 
144
                        return "Band limited sinc interpolation, best quality, 145dB SNR, 96% BW." ;
 
145
 
 
146
                default :
 
147
                        break ;
 
148
                } ;
 
149
 
 
150
        return NULL ;
 
151
} /* sinc_get_descrition */
171
152
 
172
153
int
173
154
gavl_sinc_set_converter (SRC_PRIVATE *psrc, int src_enum, int d)
174
 
  {     SINC_FILTER *filter, temp_filter ;
175
 
  int count, bits ;
176
 
 
177
 
  /* Quick sanity check. */
178
 
  if (SHIFT_BITS >= sizeof (increment_t) * 8 - 1)
179
 
    return SRC_ERR_SHIFT_BITS ;
180
 
 
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 ;
186
 
      } ;
187
 
    } ;
188
 
 
189
 
  memset (&temp_filter, 0, sizeof (temp_filter)) ;
190
 
 
191
 
  temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ;
192
 
  temp_filter.channels = psrc->channels ;
193
 
 
194
 
  if(d)
195
 
    psrc->process = sinc_process_d ;
196
 
  else
197
 
    psrc->process = sinc_process_f ;
198
 
  psrc->reset = sinc_reset ;
199
 
 
200
 
  switch (src_enum)
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) ;
208
 
          break ;
209
 
 
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) ;
217
 
      break ;
218
 
 
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) ;
226
 
      break ;
227
 
 
228
 
    default :
229
 
      return SRC_ERR_BAD_CONVERTER ;
230
 
    } ;
231
 
 
232
 
  /*
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.
235
 
  */
236
 
 
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 ;
239
 
 
240
 
  if(d)
241
 
    {
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 ;
244
 
    }
245
 
  else
246
 
    {
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 ;
249
 
    }
250
 
 
251
 
  temp_filter.d = d;
252
 
 
253
 
  *filter = temp_filter ;
254
 
  memset (&temp_filter, 0xEE, sizeof (temp_filter)) ;
255
 
 
256
 
  psrc->private_data = filter ;
257
 
 
258
 
  sinc_reset (psrc) ;
259
 
 
260
 
  count = filter->coeff_half_len ;
261
 
  for (bits = 0 ; (1 << bits) < count ; bits++)
262
 
    count |= (1 << bits) ;
263
 
 
264
 
  if (bits + SHIFT_BITS - 1 >= (int) (sizeof (increment_t) * 8))
265
 
    return SRC_ERR_FILTER_LEN ;
266
 
 
267
 
  return SRC_ERR_NO_ERROR ;
268
 
  } /* sinc_set_converter */
 
155
{       SINC_FILTER *filter, temp_filter ;
 
156
        increment_t count ;
 
157
        int bits ;
 
158
 
 
159
        /* Quick sanity check. */
 
160
        if (SHIFT_BITS >= sizeof (increment_t) * 8 - 1)
 
161
                return SRC_ERR_SHIFT_BITS ;
 
162
 
 
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 ;
 
168
                        } ;
 
169
                } ;
 
170
 
 
171
        memset (&temp_filter, 0, sizeof (temp_filter)) ;
 
172
 
 
173
        temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ;
 
174
        temp_filter.channels = psrc->channels ;
 
175
        if(d)
 
176
          {
 
177
          psrc->const_process = sinc_vari_process_d ;
 
178
          psrc->vari_process = sinc_vari_process_d ;
 
179
          }
 
180
        else
 
181
          {
 
182
          psrc->const_process = sinc_vari_process_f ;
 
183
          psrc->vari_process = sinc_vari_process_f ;
 
184
          }
 
185
        psrc->reset = sinc_reset ;
 
186
 
 
187
        switch (src_enum)
 
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 ;
 
192
                                break ;
 
193
 
 
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 ;
 
198
                                break ;
 
199
 
 
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 ;
 
204
                                break ;
 
205
 
 
206
                default :
 
207
                                return SRC_ERR_BAD_CONVERTER ;
 
208
                } ;
 
209
 
 
210
        /*
 
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.
 
213
        */
 
214
 
 
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 ;
 
218
        temp_filter.d = d; 
 
219
        if(d)
 
220
          {
 
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 ;
 
223
 
 
224
          }
 
225
        else
 
226
          {
 
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 ;
 
229
          }
 
230
 
 
231
        *filter = temp_filter ;
 
232
        memset (&temp_filter, 0xEE, sizeof (temp_filter)) ;
 
233
 
 
234
        psrc->private_data = filter ;
 
235
 
 
236
        sinc_reset (psrc) ;
 
237
 
 
238
        count = filter->coeff_half_len ;
 
239
        for (bits = 0 ; (MAKE_INCREMENT_T (1) << bits) < count ; bits++)
 
240
                count |= (MAKE_INCREMENT_T (1) << bits) ;
 
241
 
 
242
        if (bits + SHIFT_BITS - 1 >= (int) (sizeof (increment_t) * 8))
 
243
                return SRC_ERR_FILTER_LEN ;
 
244
 
 
245
        return SRC_ERR_NO_ERROR ;
 
246
} /* sinc_set_converter */
269
247
 
270
248
static void
271
249
sinc_reset (SRC_PRIVATE *psrc)
272
 
  {     SINC_FILTER *filter ;
273
 
 
274
 
  filter = (SINC_FILTER*) psrc->private_data ;
275
 
  if (filter == NULL)
276
 
    return ;
277
 
 
278
 
  filter->b_current = filter->b_end = 0 ;
279
 
  filter->b_real_end = -1 ;
280
 
 
281
 
  filter->src_ratio = filter->input_index = 0.0 ;
282
 
 
283
 
  if(!filter->d)
284
 
    memset (filter->buffer_f, 0, filter->b_len * sizeof (filter->buffer_f [0])) ;
285
 
  else
286
 
    memset (filter->buffer_d, 0, filter->b_len * sizeof (filter->buffer_d [0])) ;
287
 
 
288
 
  /* Set this for a sanity check */
289
 
  if(!filter->d)
290
 
    memset (filter->buffer_f + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer_f [0])) ;
291
 
  else
292
 
    memset (filter->buffer_d + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer_d [0])) ;
293
 
  } /* sinc_reset */
 
250
{       SINC_FILTER *filter ;
 
251
 
 
252
        filter = (SINC_FILTER*) psrc->private_data ;
 
253
        if (filter == NULL)
 
254
                return ;
 
255
 
 
256
        filter->b_current = filter->b_end = 0 ;
 
257
        filter->b_real_end = -1 ;
 
258
 
 
259
        filter->src_ratio = filter->input_index = 0.0 ;
 
260
        if(filter->d)
 
261
          {
 
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])) ;
 
265
          }
 
266
        else
 
267
          {
 
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])) ;
 
271
          }
 
272
          
 
273
} /* sinc_reset */
294
274
 
295
275
/*========================================================================================
296
276
**      Beware all ye who dare pass this point. There be dragons here.
297
277
*/
298
278
 
299
279
static int
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 ;
305
 
 
306
 
  if (psrc->private_data == NULL)
307
 
    return SRC_ERR_NO_PRIVATE ;
308
 
 
309
 
  filter = (SINC_FILTER*) psrc->private_data ;
310
 
 
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 ;
314
 
 
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 ;
318
 
 
319
 
  src_ratio = psrc->last_ratio ;
320
 
 
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) ;
325
 
 
326
 
  /* Maximum coefficientson either side of center point. */
327
 
  half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
328
 
 
329
 
  input_index = psrc->last_position ;
330
 
  float_increment = filter->index_inc ;
331
 
 
332
 
  rem = fmod (input_index, 1.0) ;
333
 
  filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
334
 
  input_index = rem ;
335
 
 
336
 
  terminate = 1.0 / src_ratio + 1e-20 ;
337
 
 
338
 
  /* Main processing loop. */
339
 
  while (filter->out_gen < filter->out_count)
340
 
    {
341
 
    /* Need to reload buffer? */
342
 
    samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
343
 
 
344
 
    if (samples_in_hand <= half_filter_chan_len)
345
 
      { prepare_data_f (filter, data, half_filter_chan_len) ;
346
 
 
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)
349
 
        break ;
350
 
      } ;
351
 
 
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)
355
 
        break ;
356
 
      } ;
357
 
 
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) ;
360
 
 
361
 
    float_increment = filter->index_inc * 1.0 ;
362
 
    if (src_ratio < 1.0)
363
 
      float_increment = filter->index_inc * src_ratio ;
364
 
 
365
 
    increment = DOUBLE_TO_FP (float_increment) ;
366
 
 
367
 
    start_filter_index = DOUBLE_TO_FP (input_index * float_increment) ;
368
 
 
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) ;
372
 
      filter->out_gen ++ ;
373
 
      } ;
374
 
 
375
 
    /* Figure out the next index. */
376
 
    input_index += 1.0 / src_ratio ;
377
 
    rem = fmod (input_index, 1.0) ;
378
 
 
379
 
    filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
380
 
    input_index = rem ;
381
 
    } ;
382
 
 
383
 
  psrc->last_position = input_index ;
384
 
 
385
 
  /* Save current ratio rather then target ratio. */
386
 
  psrc->last_ratio = src_ratio ;
387
 
 
388
 
  data->input_frames_used = filter->in_used / filter->channels ;
389
 
  data->output_frames_gen = filter->out_gen / filter->channels ;
390
 
 
391
 
  return SRC_ERR_NO_ERROR ;
392
 
  } /* sinc_process */
 
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 ;
 
285
 
 
286
        if (psrc->private_data == NULL)
 
287
                return SRC_ERR_NO_PRIVATE ;
 
288
 
 
289
        filter = (SINC_FILTER*) psrc->private_data ;
 
290
#if 0
 
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 ;
 
294
#endif
 
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 ;
 
298
 
 
299
        src_ratio = psrc->last_ratio ;
 
300
 
 
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) ;
 
305
 
 
306
        /* Maximum coefficientson either side of center point. */
 
307
        half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
 
308
 
 
309
        input_index = psrc->last_position ;
 
310
        float_increment = filter->index_inc ;
 
311
 
 
312
        rem = fmod_one (input_index) ;
 
313
        filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
 
314
        input_index = rem ;
 
315
 
 
316
        terminate = 1.0 / src_ratio + 1e-20 ;
 
317
 
 
318
        /* Main processing loop. */
 
319
        while (filter->out_gen < filter->out_count)
 
320
        {
 
321
                /* Need to reload buffer? */
 
322
                samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
 
323
 
 
324
                if (samples_in_hand <= half_filter_chan_len)
 
325
                {       prepare_data_f (filter, data, half_filter_chan_len) ;
 
326
 
 
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)
 
329
                                break ;
 
330
                        } ;
 
331
 
 
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)
 
335
                                break ;
 
336
                        } ;
 
337
 
 
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 ;
 
340
 
 
341
                float_increment = filter->index_inc * 1.0 ;
 
342
                if (src_ratio < 1.0)
 
343
                        float_increment = filter->index_inc * src_ratio ;
 
344
 
 
345
                increment = double_to_fp (float_increment) ;
 
346
 
 
347
                start_filter_index = double_to_fp (input_index * float_increment) ;
 
348
 
 
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)) ;
 
352
                        filter->out_gen ++ ;
 
353
                        } ;
 
354
 
 
355
                /* Figure out the next index. */
 
356
                input_index += 1.0 / src_ratio ;
 
357
                rem = fmod_one (input_index) ;
 
358
 
 
359
                filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
 
360
                input_index = rem ;
 
361
                } ;
 
362
 
 
363
        psrc->last_position = input_index ;
 
364
 
 
365
        /* Save current ratio rather then target ratio. */
 
366
        psrc->last_ratio = src_ratio ;
 
367
 
 
368
        data->input_frames_used = filter->in_used / filter->channels ;
 
369
        data->output_frames_gen = filter->out_gen / filter->channels ;
 
370
 
 
371
        return SRC_ERR_NO_ERROR ;
 
372
} /* sinc_vari_process_f */
393
373
 
394
374
static int
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 ;
400
 
 
401
 
  if (psrc->private_data == NULL)
402
 
    return SRC_ERR_NO_PRIVATE ;
403
 
 
404
 
  filter = (SINC_FILTER*) psrc->private_data ;
405
 
 
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 ;
409
 
 
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 ;
413
 
 
414
 
  src_ratio = psrc->last_ratio ;
415
 
 
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) ;
420
 
 
421
 
  /* Maximum coefficientson either side of center point. */
422
 
  half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
423
 
 
424
 
  input_index = psrc->last_position ;
425
 
  float_increment = filter->index_inc ;
426
 
 
427
 
  rem = fmod (input_index, 1.0) ;
428
 
  filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
429
 
  input_index = rem ;
430
 
 
431
 
  terminate = 1.0 / src_ratio + 1e-20 ;
432
 
 
433
 
  /* Main processing loop. */
434
 
  while (filter->out_gen < filter->out_count)
435
 
    {
436
 
    /* Need to reload buffer? */
437
 
    samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
438
 
 
439
 
    if (samples_in_hand <= half_filter_chan_len)
440
 
      { prepare_data_d (filter, data, half_filter_chan_len) ;
441
 
 
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)
444
 
        break ;
445
 
      } ;
446
 
 
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)
450
 
        break ;
451
 
      } ;
452
 
 
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) ;
455
 
 
456
 
    float_increment = filter->index_inc * 1.0 ;
457
 
    if (src_ratio < 1.0)
458
 
      float_increment = filter->index_inc * src_ratio ;
459
 
 
460
 
    increment = DOUBLE_TO_FP (float_increment) ;
461
 
 
462
 
    start_filter_index = DOUBLE_TO_FP (input_index * float_increment) ;
463
 
 
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) ;
467
 
      filter->out_gen ++ ;
468
 
      } ;
469
 
 
470
 
    /* Figure out the next index. */
471
 
    input_index += 1.0 / src_ratio ;
472
 
    rem = fmod (input_index, 1.0) ;
473
 
 
474
 
    filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
475
 
    input_index = rem ;
476
 
    } ;
477
 
 
478
 
  psrc->last_position = input_index ;
479
 
 
480
 
  /* Save current ratio rather then target ratio. */
481
 
  psrc->last_ratio = src_ratio ;
482
 
 
483
 
  data->input_frames_used = filter->in_used / filter->channels ;
484
 
  data->output_frames_gen = filter->out_gen / filter->channels ;
485
 
 
486
 
  return SRC_ERR_NO_ERROR ;
487
 
  } /* sinc_process */
 
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 ;
 
380
 
 
381
        if (psrc->private_data == NULL)
 
382
                return SRC_ERR_NO_PRIVATE ;
 
383
 
 
384
        filter = (SINC_FILTER*) psrc->private_data ;
 
385
#if 0
 
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 ;
 
389
#endif
 
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 ;
 
393
 
 
394
        src_ratio = psrc->last_ratio ;
 
395
 
 
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) ;
 
400
 
 
401
        /* Maximum coefficientson either side of center point. */
 
402
        half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
 
403
 
 
404
        input_index = psrc->last_position ;
 
405
        float_increment = filter->index_inc ;
 
406
 
 
407
        rem = fmod_one (input_index) ;
 
408
        filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
 
409
        input_index = rem ;
 
410
 
 
411
        terminate = 1.0 / src_ratio + 1e-20 ;
 
412
 
 
413
        /* Main processing loop. */
 
414
        while (filter->out_gen < filter->out_count)
 
415
        {
 
416
                /* Need to reload buffer? */
 
417
                samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
 
418
 
 
419
                if (samples_in_hand <= half_filter_chan_len)
 
420
                {       prepare_data_d (filter, data, half_filter_chan_len) ;
 
421
 
 
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)
 
424
                                break ;
 
425
                        } ;
 
426
 
 
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)
 
430
                                break ;
 
431
                        } ;
 
432
 
 
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 ;
 
435
 
 
436
                float_increment = filter->index_inc * 1.0 ;
 
437
                if (src_ratio < 1.0)
 
438
                        float_increment = filter->index_inc * src_ratio ;
 
439
 
 
440
                increment = double_to_fp (float_increment) ;
 
441
 
 
442
                start_filter_index = double_to_fp (input_index * float_increment) ;
 
443
 
 
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)) ;
 
447
                        filter->out_gen ++ ;
 
448
                        } ;
 
449
 
 
450
                /* Figure out the next index. */
 
451
                input_index += 1.0 / src_ratio ;
 
452
                rem = fmod_one (input_index) ;
 
453
 
 
454
                filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
 
455
                input_index = rem ;
 
456
                } ;
 
457
 
 
458
        psrc->last_position = input_index ;
 
459
 
 
460
        /* Save current ratio rather then target ratio. */
 
461
        psrc->last_ratio = src_ratio ;
 
462
 
 
463
        data->input_frames_used = filter->in_used / filter->channels ;
 
464
        data->output_frames_gen = filter->out_gen / filter->channels ;
 
465
 
 
466
        return SRC_ERR_NO_ERROR ;
 
467
} /* sinc_vari_process_d */
488
468
 
489
469
 
490
470
/*----------------------------------------------------------------------------------------
491
 
 */
 
471
*/
492
472
 
493
473
static void
494
474
prepare_data_f (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len)
495
 
  {     int len = 0 ;
496
 
 
497
 
  if (filter->b_real_end >= 0)
498
 
    return ;    /* This doesn't make sense, so return. */
499
 
 
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.
503
 
        */
504
 
    len = filter->b_len - 2 * half_filter_chan_len ;
505
 
 
506
 
    filter->b_current = filter->b_end = half_filter_chan_len ;
507
 
    }
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) ;
511
 
    }
512
 
  else
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])) ;
517
 
 
518
 
    filter->b_current = half_filter_chan_len ;
519
 
    filter->b_end = filter->b_current + len ;
520
 
 
521
 
    /* Now load data at current end of buffer. */
522
 
    len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
523
 
    } ;
524
 
 
525
 
  len = MIN (filter->in_count - filter->in_used, len) ;
526
 
  len -= (len % filter->channels) ;
527
 
 
528
 
  memcpy (filter->buffer_f + filter->b_end, data->data_in_f + filter->in_used,
529
 
          len * sizeof (filter->buffer_f [0])) ;
530
 
 
531
 
  filter->b_end += len ;
532
 
  filter->in_used += len ;
533
 
 
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.
538
 
        */
539
 
 
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])) ;
545
 
 
546
 
      filter->b_current = half_filter_chan_len ;
547
 
      filter->b_end = filter->b_current + len ;
548
 
      } ;
549
 
 
550
 
    filter->b_real_end = filter->b_end ;
551
 
    len = half_filter_chan_len + 5 ;
552
 
 
553
 
    memset (filter->buffer_f + filter->b_end, 0, len * sizeof (filter->buffer_f [0])) ;
554
 
    filter->b_end += len ;
555
 
    } ;
556
 
 
557
 
  return ;
558
 
  } /* prepare_data_f */
 
475
{       int len = 0 ;
 
476
 
 
477
        if (filter->b_real_end >= 0)
 
478
                return ;        /* This doesn't make sense, so return. */
 
479
 
 
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.
 
483
                */
 
484
                len = filter->b_len - 2 * half_filter_chan_len ;
 
485
 
 
486
                filter->b_current = filter->b_end = half_filter_chan_len ;
 
487
                }
 
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) ;
 
491
                }
 
492
        else
 
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])) ;
 
497
 
 
498
                filter->b_current = half_filter_chan_len ;
 
499
                filter->b_end = filter->b_current + len ;
 
500
 
 
501
                /* Now load data at current end of buffer. */
 
502
                len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
 
503
                } ;
 
504
 
 
505
        len = MIN (filter->in_count - filter->in_used, len) ;
 
506
        len -= (len % filter->channels) ;
 
507
 
 
508
        memcpy (filter->buffer_f + filter->b_end, data->data_in_f + filter->in_used,
 
509
                                                len * sizeof (filter->buffer_f [0])) ;
 
510
 
 
511
        filter->b_end += len ;
 
512
        filter->in_used += len ;
 
513
 
 
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.
 
518
                */
 
519
 
 
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])) ;
 
525
 
 
526
                        filter->b_current = half_filter_chan_len ;
 
527
                        filter->b_end = filter->b_current + len ;
 
528
                        } ;
 
529
 
 
530
                filter->b_real_end = filter->b_end ;
 
531
                len = half_filter_chan_len + 5 ;
 
532
 
 
533
                memset (filter->buffer_f + filter->b_end, 0, len * sizeof (filter->buffer_f [0])) ;
 
534
                filter->b_end += len ;
 
535
                } ;
 
536
 
 
537
        return ;
 
538
} /* prepare_data_f */
559
539
 
560
540
static void
561
541
prepare_data_d (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len)
562
 
  {     int len = 0 ;
563
 
 
564
 
  if (filter->b_real_end >= 0)
565
 
    return ;    /* This doesn't make sense, so return. */
566
 
 
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.
570
 
        */
571
 
    len = filter->b_len - 2 * half_filter_chan_len ;
572
 
 
573
 
    filter->b_current = filter->b_end = half_filter_chan_len ;
574
 
    }
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) ;
578
 
    }
579
 
  else
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])) ;
584
 
 
585
 
    filter->b_current = half_filter_chan_len ;
586
 
    filter->b_end = filter->b_current + len ;
587
 
 
588
 
    /* Now load data at current end of buffer. */
589
 
    len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
590
 
    } ;
591
 
 
592
 
  len = MIN (filter->in_count - filter->in_used, len) ;
593
 
  len -= (len % filter->channels) ;
594
 
 
595
 
  memcpy (filter->buffer_d + filter->b_end, data->data_in_d + filter->in_used,
596
 
          len * sizeof (filter->buffer_d [0])) ;
597
 
 
598
 
  filter->b_end += len ;
599
 
  filter->in_used += len ;
600
 
 
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.
605
 
        */
606
 
 
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])) ;
612
 
 
613
 
      filter->b_current = half_filter_chan_len ;
614
 
      filter->b_end = filter->b_current + len ;
615
 
      } ;
616
 
 
617
 
    filter->b_real_end = filter->b_end ;
618
 
    len = half_filter_chan_len + 5 ;
619
 
 
620
 
    memset (filter->buffer_d + filter->b_end, 0, len * sizeof (filter->buffer_d [0])) ;
621
 
    filter->b_end += len ;
622
 
    } ;
623
 
 
624
 
  return ;
625
 
  } /* prepare_data_d */
 
542
{       int len = 0 ;
 
543
 
 
544
        if (filter->b_real_end >= 0)
 
545
                return ;        /* This doesn't make sense, so return. */
 
546
 
 
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.
 
550
                */
 
551
                len = filter->b_len - 2 * half_filter_chan_len ;
 
552
 
 
553
                filter->b_current = filter->b_end = half_filter_chan_len ;
 
554
                }
 
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) ;
 
558
                }
 
559
        else
 
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])) ;
 
564
 
 
565
                filter->b_current = half_filter_chan_len ;
 
566
                filter->b_end = filter->b_current + len ;
 
567
 
 
568
                /* Now load data at current end of buffer. */
 
569
                len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
 
570
                } ;
 
571
 
 
572
        len = MIN (filter->in_count - filter->in_used, len) ;
 
573
        len -= (len % filter->channels) ;
 
574
 
 
575
        memcpy (filter->buffer_d + filter->b_end, data->data_in_d + filter->in_used,
 
576
                                                len * sizeof (filter->buffer_d [0])) ;
 
577
 
 
578
        filter->b_end += len ;
 
579
        filter->in_used += len ;
 
580
 
 
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.
 
585
                */
 
586
 
 
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])) ;
 
592
 
 
593
                        filter->b_current = half_filter_chan_len ;
 
594
                        filter->b_end = filter->b_current + len ;
 
595
                        } ;
 
596
 
 
597
                filter->b_real_end = filter->b_end ;
 
598
                len = half_filter_chan_len + 5 ;
 
599
 
 
600
                memset (filter->buffer_d + filter->b_end, 0, len * sizeof (filter->buffer_d [0])) ;
 
601
                filter->b_end += len ;
 
602
                } ;
 
603
 
 
604
        return ;
 
605
} /* prepare_data_d */
626
606
 
627
607
 
628
608
 
629
609
static double
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 ;
634
 
 
635
 
  /* Convert input parameters into fixed point. */
636
 
  max_filter_index = INT_TO_FP (filter->coeff_half_len) ;
637
 
 
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 ;
643
 
 
644
 
  left = 0.0 ;
645
 
  do
646
 
    {   fraction = FP_TO_DOUBLE (filter_index) ;
647
 
    indx = FP_TO_INT (filter_index) ;
648
 
 
649
 
    icoeff = filter->coeffs_f [indx] + fraction * (filter->coeffs_f [indx + 1] - filter->coeffs_f [indx]) ;
650
 
 
651
 
    left += icoeff * filter->buffer_f [data_index + ch] ;
652
 
 
653
 
    filter_index -= increment ;
654
 
    data_index = data_index + filter->channels ;
655
 
    }
656
 
  while (filter_index >= MAKE_INCREMENT_T (0)) ;
657
 
 
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) ;
663
 
 
664
 
  right = 0.0 ;
665
 
  do
666
 
    {   fraction = FP_TO_DOUBLE (filter_index) ;
667
 
    indx = FP_TO_INT (filter_index) ;
668
 
 
669
 
    icoeff = filter->coeffs_f [indx] + fraction * (filter->coeffs_f [indx + 1] - filter->coeffs_f [indx]) ;
670
 
 
671
 
    right += icoeff * filter->buffer_f [data_index + ch] ;
672
 
 
673
 
    filter_index -= increment ;
674
 
    data_index = data_index - filter->channels ;
675
 
    }
676
 
  while (filter_index > MAKE_INCREMENT_T (0)) ;
677
 
 
678
 
  return (left + right) ;
679
 
  } /* calc_output */
 
611
{       double          fraction, left, right, icoeff ;
 
612
        increment_t     filter_index, max_filter_index ;
 
613
        int                     data_index, coeff_count, indx ;
 
614
 
 
615
        /* Convert input parameters into fixed point. */
 
616
        max_filter_index = int_to_fp (filter->coeff_half_len) ;
 
617
 
 
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 ;
 
623
 
 
624
        left = 0.0 ;
 
625
        do
 
626
        {       fraction = fp_to_double (filter_index) ;
 
627
                indx = fp_to_int (filter_index) ;
 
628
 
 
629
                icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
 
630
 
 
631
                left += icoeff * filter->buffer_f [data_index] ;
 
632
 
 
633
                filter_index -= increment ;
 
634
                data_index = data_index + filter->channels ;
 
635
                }
 
636
        while (filter_index >= MAKE_INCREMENT_T (0)) ;
 
637
 
 
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 ;
 
643
 
 
644
        right = 0.0 ;
 
645
        do
 
646
        {       fraction = fp_to_double (filter_index) ;
 
647
                indx = fp_to_int (filter_index) ;
 
648
 
 
649
                icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
 
650
 
 
651
                right += icoeff * filter->buffer_f [data_index] ;
 
652
 
 
653
                filter_index -= increment ;
 
654
                data_index = data_index - filter->channels ;
 
655
                }
 
656
        while (filter_index > MAKE_INCREMENT_T (0)) ;
 
657
 
 
658
        return (left + right) ;
 
659
} /* calc_output_f */
680
660
 
681
661
static double
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 ;
686
 
 
687
 
  /* Convert input parameters into fixed point. */
688
 
  max_filter_index = INT_TO_FP (filter->coeff_half_len) ;
689
 
 
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 ;
695
 
 
696
 
  left = 0.0 ;
697
 
  do
698
 
    {   fraction = FP_TO_DOUBLE (filter_index) ;
699
 
    indx = FP_TO_INT (filter_index) ;
700
 
 
701
 
    icoeff = filter->coeffs_d [indx] + fraction * (filter->coeffs_d [indx + 1] - filter->coeffs_d [indx]) ;
702
 
 
703
 
    left += icoeff * filter->buffer_d [data_index + ch] ;
704
 
 
705
 
    filter_index -= increment ;
706
 
    data_index = data_index + filter->channels ;
707
 
    }
708
 
  while (filter_index >= MAKE_INCREMENT_T (0)) ;
709
 
 
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) ;
715
 
 
716
 
  right = 0.0 ;
717
 
  do
718
 
    {   fraction = FP_TO_DOUBLE (filter_index) ;
719
 
    indx = FP_TO_INT (filter_index) ;
720
 
 
721
 
    icoeff = filter->coeffs_d [indx] + fraction * (filter->coeffs_d [indx + 1] - filter->coeffs_d [indx]) ;
722
 
 
723
 
    right += icoeff * filter->buffer_d [data_index + ch] ;
724
 
 
725
 
    filter_index -= increment ;
726
 
    data_index = data_index - filter->channels ;
727
 
    }
728
 
  while (filter_index > MAKE_INCREMENT_T (0)) ;
729
 
 
730
 
  return (left + right) ;
731
 
  } /* calc_output */
732
 
 
733
 
 
734
 
/*
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.
738
 
**
739
 
** arch-tag: db8efe06-2fbd-487e-be8f-bfc01e68c19f
740
 
*/
 
663
{       double          fraction, left, right, icoeff ;
 
664
        increment_t     filter_index, max_filter_index ;
 
665
        int                     data_index, coeff_count, indx ;
 
666
 
 
667
        /* Convert input parameters into fixed point. */
 
668
        max_filter_index = int_to_fp (filter->coeff_half_len) ;
 
669
 
 
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 ;
 
675
 
 
676
        left = 0.0 ;
 
677
        do
 
678
        {       fraction = fp_to_double (filter_index) ;
 
679
                indx = fp_to_int (filter_index) ;
 
680
 
 
681
                icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
 
682
 
 
683
                left += icoeff * filter->buffer_d [data_index] ;
 
684
 
 
685
                filter_index -= increment ;
 
686
                data_index = data_index + filter->channels ;
 
687
                }
 
688
        while (filter_index >= MAKE_INCREMENT_T (0)) ;
 
689
 
 
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 ;
 
695
 
 
696
        right = 0.0 ;
 
697
        do
 
698
        {       fraction = fp_to_double (filter_index) ;
 
699
                indx = fp_to_int (filter_index) ;
 
700
 
 
701
                icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
 
702
 
 
703
                right += icoeff * filter->buffer_d [data_index] ;
 
704
 
 
705
                filter_index -= increment ;
 
706
                data_index = data_index - filter->channels ;
 
707
                }
 
708
        while (filter_index > MAKE_INCREMENT_T (0)) ;
 
709
 
 
710
        return (left + right) ;
 
711
} /* calc_output_d */
741
712