~ubuntu-branches/ubuntu/precise/libsamplerate/precise

« back to all changes in this revision

Viewing changes to src/src_sinc.c

  • Committer: Bazaar Package Importer
  • Author(s): Anand Kumria
  • Date: 2004-08-23 09:27:09 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040823092709-0ky0g42832g3f7vv
Tags: 0.1.1-2
Install documentation (Closes: #262921)

Show diffs side-by-side

added added

removed removed

Lines of Context:
82
82
        coeff_t const   *coeffs ;
83
83
 
84
84
        int             b_current, b_end, b_real_end, b_len ;
85
 
        float   *pdata ;
86
85
        float   buffer [1] ;
87
86
} SINC_FILTER ;
88
87
 
 
88
static int sinc_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
 
89
 
89
90
static double calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) ;
90
91
 
91
92
static void prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) ;
147
148
int
148
149
sinc_set_converter (SRC_PRIVATE *psrc, int src_enum)
149
150
{       SINC_FILTER *filter, temp_filter ;
150
 
        int count ;
 
151
        int count, bits ;
151
152
 
152
153
        /* Quick sanity check. */
153
154
        if (SHIFT_BITS >= sizeof (increment_t) * 8 - 1)
172
173
        switch (src_enum)
173
174
        {       case SRC_SINC_BEST_QUALITY :
174
175
                                temp_filter.coeffs = high_qual_coeffs ;
175
 
                                temp_filter.coeff_half_len = (sizeof (high_qual_coeffs) / sizeof (coeff_t)) - 1 ;
 
176
                                temp_filter.coeff_half_len = ARRAY_LEN (high_qual_coeffs) - 1 ;
176
177
                                temp_filter.index_inc = 128 ;
177
178
                                temp_filter.has_diffs = SRC_FALSE ;
178
 
                                temp_filter.coeff_len = sizeof (high_qual_coeffs) / sizeof (coeff_t) ;
 
179
                                temp_filter.coeff_len = ARRAY_LEN (high_qual_coeffs) ;
179
180
                                break ;
180
181
 
181
182
                case SRC_SINC_MEDIUM_QUALITY :
182
183
                                temp_filter.coeffs = mid_qual_coeffs ;
183
 
                                temp_filter.coeff_half_len = (sizeof (mid_qual_coeffs) / sizeof (coeff_t)) - 1 ;
 
184
                                temp_filter.coeff_half_len = ARRAY_LEN (mid_qual_coeffs) - 1 ;
184
185
                                temp_filter.index_inc = 128 ;
185
186
                                temp_filter.has_diffs = SRC_FALSE ;
186
 
                                temp_filter.coeff_len = sizeof (mid_qual_coeffs) / sizeof (coeff_t) ;
 
187
                                temp_filter.coeff_len = ARRAY_LEN (mid_qual_coeffs) ;
187
188
                                break ;
188
189
 
189
190
                case SRC_SINC_FASTEST :
190
191
                                temp_filter.coeffs = fastest_coeffs ;
191
 
                                temp_filter.coeff_half_len = (sizeof (fastest_coeffs) / sizeof (coeff_t)) - 1 ;
 
192
                                temp_filter.coeff_half_len = ARRAY_LEN (fastest_coeffs) - 1 ;
192
193
                                temp_filter.index_inc = 128 ;
193
194
                                temp_filter.has_diffs = SRC_FALSE ;
194
 
                                temp_filter.coeff_len = sizeof (fastest_coeffs) / sizeof (coeff_t) ;
 
195
                                temp_filter.coeff_len = ARRAY_LEN (fastest_coeffs) ;
195
196
                                break ;
196
197
 
197
198
                default :
203
204
        ** a better way. Need to look at prepare_data () at the same time.
204
205
        */
205
206
 
206
 
        temp_filter.b_len = 1000 + 2 * lrint (ceil (temp_filter.coeff_len / (temp_filter.index_inc * 1.0) * SRC_MAX_RATIO)) ;
 
207
        temp_filter.b_len = 1000 + 2 * lrint (0.5 + temp_filter.coeff_len / (temp_filter.index_inc * 1.0) * SRC_MAX_RATIO) ;
207
208
        temp_filter.b_len *= temp_filter.channels ;
208
209
 
209
210
        if ((filter = calloc (1, sizeof (SINC_FILTER) + sizeof (filter->buffer [0]) * (temp_filter.b_len + temp_filter.channels))) == NULL)
216
217
 
217
218
        sinc_reset (psrc) ;
218
219
 
219
 
        count = (filter->coeff_half_len * INT_TO_FP (1)) / FP_ONE ;
 
220
        count = filter->coeff_half_len ;
 
221
        for (bits = 0 ; (1 << bits) < count ; bits++)
 
222
                count |= (1 << bits) ;
220
223
 
221
 
        if (abs (count - filter->coeff_half_len) >= 1)
 
224
        if (bits + SHIFT_BITS - 1 >= (int) (sizeof (increment_t) * 8))
222
225
                return SRC_ERR_FILTER_LEN ;
223
226
 
224
227
        return SRC_ERR_NO_ERROR ;
247
250
**      Beware all ye who dare pass this point. There be dragons here.
248
251
*/
249
252
 
250
 
int
 
253
static int
251
254
sinc_process (SRC_PRIVATE *psrc, SRC_DATA *data)
252
255
{       SINC_FILTER *filter ;
253
 
        double          input_index, src_ratio, count, float_increment, terminate ;
 
256
        double          input_index, src_ratio, count, float_increment, terminate, rem ;
254
257
        increment_t     increment, start_filter_index ;
255
258
        int                     half_filter_chan_len, samples_in_hand, ch ;
256
259
 
273
276
        count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
274
277
        if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
275
278
                count /= MIN (psrc->last_ratio, data->src_ratio) ;
276
 
        count = lrint (ceil (count)) ;
277
279
 
278
280
        /* Maximum coefficientson either side of center point. */
279
281
        half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
280
282
 
281
283
        input_index = psrc->last_position ;
282
 
        if (input_index >= 1.0)
283
 
        {       filter->b_current = (filter->b_current + filter->channels * lrint (floor (input_index))) % filter->b_len ;
284
 
                input_index -= floor (input_index) ;
285
 
                } ;
286
 
 
287
284
        float_increment = filter->index_inc ;
288
285
 
289
 
        filter->b_current = (filter->b_current + filter->channels * lrint (floor (input_index))) % filter->b_len ;
290
 
        input_index -= floor (input_index) ;
 
286
        rem = fmod (input_index, 1.0) ;
 
287
        filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
 
288
        input_index = rem ;
291
289
 
292
290
        terminate = 1.0 / src_ratio + 1e-20 ;
293
291
 
330
328
 
331
329
                /* Figure out the next index. */
332
330
                input_index += 1.0 / src_ratio ;
 
331
                rem = fmod (input_index, 1.0) ;
333
332
 
334
 
                filter->b_current = (filter->b_current + filter->channels * lrint (floor (input_index))) % filter->b_len ;
335
 
                input_index -= floor (input_index) ;
 
333
                filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
 
334
                input_index = rem ;
336
335
                } ;
337
336
 
338
337
        psrc->last_position = input_index ;