~ubuntu-branches/ubuntu/maverick/vlc/maverick

« back to all changes in this revision

Viewing changes to modules/audio_filter/resampler/bandlimited.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-09-17 21:56:14 UTC
  • mfrom: (1.1.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20080917215614-tj0vx8xzd57e52t8
Tags: 0.9.2-1ubuntu1
* New Upstream Release, exception granted by
    - dktrkranz, norsetto, Hobbsee (via irc). LP: #270404

Changes done in ubuntu:

* add libxul-dev to build-depends
* make sure that vlc is build against libxul in configure. This doesn't
  change anything in the package, but makes it more robust if building
  in an 'unclean' chroot or when modifying the package.
* debian/control: make Vcs-* fields point to the motumedia branch
* add libx264-dev and libass-dev to build-depends
  LP: #210354, #199870
* actually enable libass support by passing --enable-libass to configure
* enable libdca: add libdca-dev to build depends and --enable-libdca
* install the x264 plugin.

Changes already in the pkg-multimedia branch in debian:

* don't install usr/share/vlc/mozilla in debian/mozilla-plugin-vlc.install  
* new upstream .desktop file now registers flash video mimetype LP: #261567
* add Xb-Npp-Applications to mozilla-plugin-vlc
* remove duplicate entries in debian/vlc-nox.install

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * bandlimited.c : band-limited interpolation resampler
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2002, 2006 the VideoLAN team
5
 
 * $Id: d092f6b06402d943262837aff76bcbddb38ca97d $
 
5
 * $Id$
6
6
 *
7
7
 * Authors: Gildas Bazin <gbazin@netcourrier.com>
8
8
 *
10
10
 * it under the terms of the GNU General Public License as published by
11
11
 * the Free Software Foundation; either version 2 of the License, or
12
12
 * (at your option) any later version.
13
 
 * 
 
13
 *
14
14
 * This program is distributed in the hope that it will be useful,
15
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
32
 * filter is 13 samples.
33
33
 *
34
34
 *****************************************************************************/
35
 
#include <stdlib.h>                                      /* malloc(), free() */
36
 
#include <string.h>
37
 
 
38
 
#include <vlc/vlc.h>
39
 
#include "audio_output.h"
40
 
#include "aout_internal.h"
 
35
 
 
36
#ifdef HAVE_CONFIG_H
 
37
# include "config.h"
 
38
#endif
 
39
 
 
40
#include <vlc_common.h>
 
41
#include <vlc_plugin.h>
 
42
#include <vlc_aout.h>
 
43
#include <vlc_filter.h>
 
44
#include <vlc_block.h>
 
45
 
41
46
#include "bandlimited.h"
42
47
 
43
48
/*****************************************************************************
48
53
static void DoWork    ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
49
54
                        aout_buffer_t * );
50
55
 
51
 
static void FilterFloatUP( float Imp[], float ImpD[], uint16_t Nwing,
 
56
/* audio filter2 */
 
57
static int  OpenFilter ( vlc_object_t * );
 
58
static void CloseFilter( vlc_object_t * );
 
59
static block_t *Resample( filter_t *, block_t * );
 
60
 
 
61
 
 
62
static void FilterFloatUP( const float Imp[], const float ImpD[], uint16_t Nwing,
52
63
                           float *f_in, float *f_out, uint32_t ui_remainder,
53
64
                           uint32_t ui_output_rate, int16_t Inc,
54
65
                           int i_nb_channels );
55
66
 
56
 
static void FilterFloatUD( float Imp[], float ImpD[], uint16_t Nwing,
 
67
static void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing,
57
68
                           float *f_in, float *f_out, uint32_t ui_remainder,
58
69
                           uint32_t ui_output_rate, uint32_t ui_input_rate,
59
70
                           int16_t Inc, int i_nb_channels );
61
72
/*****************************************************************************
62
73
 * Local structures
63
74
 *****************************************************************************/
64
 
struct aout_filter_sys_t
 
75
struct filter_sys_t
65
76
{
66
77
    int32_t *p_buf;                        /* this filter introduces a delay */
67
78
    int i_buf_size;
73
84
    unsigned int i_remainder;                /* remainder of previous sample */
74
85
 
75
86
    audio_date_t end_date;
 
87
 
 
88
    bool b_first;
 
89
    bool b_filter2;
76
90
};
77
91
 
78
92
/*****************************************************************************
81
95
vlc_module_begin();
82
96
    set_category( CAT_AUDIO );
83
97
    set_subcategory( SUBCAT_AUDIO_MISC );
84
 
    set_description( _("Audio filter for band-limited interpolation resampling") );
 
98
    set_description( N_("Audio filter for band-limited interpolation resampling") );
85
99
    set_capability( "audio filter", 20 );
86
100
    set_callbacks( Create, Close );
 
101
 
 
102
    add_submodule();
 
103
    set_description( _("Audio filter for band-limited interpolation resampling") );
 
104
    set_capability( "audio filter2", 20 );
 
105
    set_callbacks( OpenFilter, CloseFilter );
87
106
vlc_module_end();
88
107
 
89
108
/*****************************************************************************
92
111
static int Create( vlc_object_t *p_this )
93
112
{
94
113
    aout_filter_t * p_filter = (aout_filter_t *)p_this;
 
114
    struct filter_sys_t * p_sys;
95
115
    double d_factor;
96
116
    int i_filter_wing;
97
117
 
114
134
#endif
115
135
 
116
136
    /* Allocate the memory needed to store the module's structure */
117
 
    p_filter->p_sys = malloc( sizeof(struct aout_filter_sys_t) );
118
 
    if( p_filter->p_sys == NULL )
119
 
    {
120
 
        msg_Err( p_filter, "out of memory" );
 
137
    p_sys = malloc( sizeof(filter_sys_t) );
 
138
    if( p_sys == NULL )
121
139
        return VLC_ENOMEM;
122
 
    }
 
140
    p_filter->p_sys = (struct aout_filter_sys_t *)p_sys;
123
141
 
124
142
    /* Calculate worst case for the length of the filter wing */
125
143
    d_factor = (double)p_filter->output.i_rate
126
 
                        / p_filter->input.i_rate;
 
144
                        / p_filter->input.i_rate / AOUT_MAX_INPUT_RATE;
127
145
    i_filter_wing = ((SMALL_FILTER_NMULT + 1)/2.0)
128
146
                      * __MAX(1.0, 1.0/d_factor) + 10;
129
 
    p_filter->p_sys->i_buf_size = aout_FormatNbChannels( &p_filter->input ) *
 
147
    p_sys->i_buf_size = aout_FormatNbChannels( &p_filter->input ) *
130
148
        sizeof(int32_t) * 2 * i_filter_wing;
131
149
 
132
150
    /* Allocate enough memory to buffer previous samples */
133
 
    p_filter->p_sys->p_buf = malloc( p_filter->p_sys->i_buf_size );
134
 
    if( p_filter->p_sys->p_buf == NULL )
 
151
    p_sys->p_buf = malloc( p_sys->i_buf_size );
 
152
    if( p_sys->p_buf == NULL )
135
153
    {
136
 
        msg_Err( p_filter, "out of memory" );
 
154
        free( p_sys );
137
155
        return VLC_ENOMEM;
138
156
    }
139
157
 
140
 
    p_filter->p_sys->i_old_wing = 0;
 
158
    p_sys->i_old_wing = 0;
 
159
    p_sys->b_filter2 = false;           /* It seams to be a good valuefor this module */
141
160
    p_filter->pf_do_work = DoWork;
142
161
 
143
162
    /* We don't want a new buffer to be created because we're not sure we'll
144
163
     * actually need to resample anything. */
145
 
    p_filter->b_in_place = VLC_TRUE;
 
164
    p_filter->b_in_place = true;
146
165
 
147
166
    return VLC_SUCCESS;
148
167
}
153
172
static void Close( vlc_object_t * p_this )
154
173
{
155
174
    aout_filter_t * p_filter = (aout_filter_t *)p_this;
156
 
    free( p_filter->p_sys->p_buf );
157
 
    free( p_filter->p_sys );
 
175
    filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
 
176
    free( p_sys->p_buf );
 
177
    free( p_sys );
158
178
}
159
179
 
160
180
/*****************************************************************************
163
183
static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
164
184
                    aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
165
185
{
 
186
    filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
166
187
    float *p_in, *p_in_orig, *p_out = (float *)p_out_buf->p_buffer;
167
188
 
168
189
    int i_nb_channels = aout_FormatNbChannels( &p_filter->input );
169
190
    int i_in_nb = p_in_buf->i_nb_samples;
170
191
    int i_in, i_out = 0;
 
192
    unsigned int i_out_rate;
171
193
    double d_factor, d_scale_factor, d_old_scale_factor;
172
194
    int i_filter_wing;
173
 
#if 0
174
 
    int i;
175
 
#endif
 
195
 
 
196
    if( p_sys->b_filter2 )
 
197
        i_out_rate = p_filter->output.i_rate;
 
198
    else
 
199
        i_out_rate = p_aout->mixer.mixer.i_rate;
176
200
 
177
201
    /* Check if we really need to run the resampler */
178
 
    if( p_aout->mixer.mixer.i_rate == p_filter->input.i_rate )
 
202
    if( i_out_rate == p_filter->input.i_rate )
179
203
    {
180
 
        if( //p_filter->b_continuity && /* What difference does it make ? :) */
181
 
            p_filter->p_sys->i_old_wing &&
 
204
        if( /*p_filter->b_continuity && /--* What difference does it make ? :) */
 
205
            p_sys->i_old_wing &&
182
206
            p_in_buf->i_size >=
183
 
              p_in_buf->i_nb_bytes + p_filter->p_sys->i_old_wing *
 
207
              p_in_buf->i_nb_bytes + p_sys->i_old_wing *
184
208
              p_filter->input.i_bytes_per_frame )
185
209
        {
186
210
            /* output the whole thing with the samples from last time */
187
211
            memmove( ((float *)(p_in_buf->p_buffer)) +
188
 
                     i_nb_channels * p_filter->p_sys->i_old_wing,
 
212
                     i_nb_channels * p_sys->i_old_wing,
189
213
                     p_in_buf->p_buffer, p_in_buf->i_nb_bytes );
190
 
            memcpy( p_in_buf->p_buffer, p_filter->p_sys->p_buf +
191
 
                    i_nb_channels * p_filter->p_sys->i_old_wing,
192
 
                    p_filter->p_sys->i_old_wing *
 
214
            memcpy( p_in_buf->p_buffer, p_sys->p_buf +
 
215
                    i_nb_channels * p_sys->i_old_wing,
 
216
                    p_sys->i_old_wing *
193
217
                    p_filter->input.i_bytes_per_frame );
194
218
 
195
219
            p_out_buf->i_nb_samples = p_in_buf->i_nb_samples +
196
 
                p_filter->p_sys->i_old_wing;
 
220
                p_sys->i_old_wing;
197
221
 
198
 
            p_out_buf->start_date = aout_DateGet( &p_filter->p_sys->end_date );
 
222
            p_out_buf->start_date = aout_DateGet( &p_sys->end_date );
199
223
            p_out_buf->end_date =
200
 
                aout_DateIncrement( &p_filter->p_sys->end_date,
 
224
                aout_DateIncrement( &p_sys->end_date,
201
225
                                    p_out_buf->i_nb_samples );
202
226
 
203
227
            p_out_buf->i_nb_bytes = p_out_buf->i_nb_samples *
204
228
                p_filter->input.i_bytes_per_frame;
205
229
        }
206
 
        p_filter->b_continuity = VLC_FALSE;
207
 
        p_filter->p_sys->i_old_wing = 0;
 
230
        p_filter->b_continuity = false;
 
231
        p_sys->i_old_wing = 0;
208
232
        return;
209
233
    }
210
234
 
212
236
    {
213
237
        /* Continuity in sound samples has been broken, we'd better reset
214
238
         * everything. */
215
 
        p_filter->b_continuity = VLC_TRUE;
216
 
        p_filter->p_sys->i_remainder = 0;
217
 
        aout_DateInit( &p_filter->p_sys->end_date, p_filter->output.i_rate );
218
 
        aout_DateSet( &p_filter->p_sys->end_date, p_in_buf->start_date );
219
 
        p_filter->p_sys->i_old_rate   = p_filter->input.i_rate;
220
 
        p_filter->p_sys->d_old_factor = 1;
221
 
        p_filter->p_sys->i_old_wing   = 0;
 
239
        p_filter->b_continuity = true;
 
240
        p_sys->i_remainder = 0;
 
241
        aout_DateInit( &p_sys->end_date, i_out_rate );
 
242
        aout_DateSet( &p_sys->end_date, p_in_buf->start_date );
 
243
        p_sys->i_old_rate   = p_filter->input.i_rate;
 
244
        p_sys->d_old_factor = 1;
 
245
        p_sys->i_old_wing   = 0;
222
246
    }
223
247
 
224
248
#if 0
225
249
    msg_Err( p_filter, "old rate: %i, old factor: %f, old wing: %i, i_in: %i",
226
 
             p_filter->p_sys->i_old_rate, p_filter->p_sys->d_old_factor,
227
 
             p_filter->p_sys->i_old_wing, i_in_nb );
 
250
             p_sys->i_old_rate, p_sys->d_old_factor,
 
251
             p_sys->i_old_wing, i_in_nb );
228
252
#endif
229
253
 
230
254
    /* Prepare the source buffer */
231
 
    i_in_nb += (p_filter->p_sys->i_old_wing * 2);
 
255
    i_in_nb += (p_sys->i_old_wing * 2);
232
256
#ifdef HAVE_ALLOCA
233
257
    p_in = p_in_orig = (float *)alloca( i_in_nb *
234
258
                                        p_filter->input.i_bytes_per_frame );
242
266
    }
243
267
 
244
268
    /* Copy all our samples in p_in */
245
 
    if( p_filter->p_sys->i_old_wing )
 
269
    if( p_sys->i_old_wing )
246
270
    {
247
 
        p_aout->p_vlc->pf_memcpy( p_in, p_filter->p_sys->p_buf,
248
 
                                  p_filter->p_sys->i_old_wing * 2 *
249
 
                                  p_filter->input.i_bytes_per_frame );
 
271
        vlc_memcpy( p_in, p_sys->p_buf,
 
272
                    p_sys->i_old_wing * 2 *
 
273
                      p_filter->input.i_bytes_per_frame );
250
274
    }
251
 
    p_aout->p_vlc->pf_memcpy( p_in + p_filter->p_sys->i_old_wing * 2 *
252
 
                              i_nb_channels, p_in_buf->p_buffer,
253
 
                              p_in_buf->i_nb_samples *
254
 
                              p_filter->input.i_bytes_per_frame );
 
275
    vlc_memcpy( p_in + p_sys->i_old_wing * 2 * i_nb_channels,
 
276
                p_in_buf->p_buffer,
 
277
                p_in_buf->i_nb_samples * p_filter->input.i_bytes_per_frame );
255
278
 
256
279
    /* Make sure the output buffer is reset */
257
280
    memset( p_out, 0, p_out_buf->i_size );
258
281
 
259
282
    /* Calculate the new length of the filter wing */
260
 
    d_factor = (double)p_aout->mixer.mixer.i_rate / p_filter->input.i_rate;
 
283
    d_factor = (double)i_out_rate / p_filter->input.i_rate;
261
284
    i_filter_wing = ((SMALL_FILTER_NMULT+1)/2.0) * __MAX(1.0,1.0/d_factor) + 1;
262
285
 
263
286
    /* Account for increased filter gain when using factors less than 1 */
264
287
    d_old_scale_factor = SMALL_FILTER_SCALE *
265
 
        p_filter->p_sys->d_old_factor + 0.5;
 
288
        p_sys->d_old_factor + 0.5;
266
289
    d_scale_factor = SMALL_FILTER_SCALE * d_factor + 0.5;
267
290
 
268
291
    /* Apply the old rate until we have enough samples for the new one */
269
 
    i_in = p_filter->p_sys->i_old_wing;
270
 
    p_in += p_filter->p_sys->i_old_wing * i_nb_channels;
 
292
    i_in = p_sys->i_old_wing;
 
293
    p_in += p_sys->i_old_wing * i_nb_channels;
271
294
    for( ; i_in < i_filter_wing &&
272
 
           (i_in + p_filter->p_sys->i_old_wing) < i_in_nb; i_in++ )
 
295
           (i_in + p_sys->i_old_wing) < i_in_nb; i_in++ )
273
296
    {
274
 
        if( p_filter->p_sys->d_old_factor == 1 )
 
297
        if( p_sys->d_old_factor == 1 )
275
298
        {
276
299
            /* Just copy the samples */
277
 
            memcpy( p_out, p_in, 
278
 
                    p_filter->input.i_bytes_per_frame );          
 
300
            memcpy( p_out, p_in,
 
301
                    p_filter->input.i_bytes_per_frame );
279
302
            p_in += i_nb_channels;
280
303
            p_out += i_nb_channels;
281
304
            i_out++;
282
305
            continue;
283
306
        }
284
307
 
285
 
        while( p_filter->p_sys->i_remainder < p_filter->output.i_rate )
 
308
        while( p_sys->i_remainder < p_filter->output.i_rate )
286
309
        {
287
310
 
288
 
            if( p_filter->p_sys->d_old_factor >= 1 )
 
311
            if( p_sys->d_old_factor >= 1 )
289
312
            {
290
313
                /* FilterFloatUP() is faster if we can use it */
291
314
 
292
315
                /* Perform left-wing inner product */
293
316
                FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
294
317
                               SMALL_FILTER_NWING, p_in, p_out,
295
 
                               p_filter->p_sys->i_remainder,
 
318
                               p_sys->i_remainder,
296
319
                               p_filter->output.i_rate,
297
320
                               -1, i_nb_channels );
298
321
                /* Perform right-wing inner product */
299
322
                FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
300
323
                               SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
301
324
                               p_filter->output.i_rate -
302
 
                               p_filter->p_sys->i_remainder,
 
325
                               p_sys->i_remainder,
303
326
                               p_filter->output.i_rate,
304
327
                               1, i_nb_channels );
305
328
 
317
340
                {
318
341
                    p_out += i_nb_channels;
319
342
                    i_out++;
320
 
                    p_filter->p_sys->i_remainder += p_filter->input.i_rate;
 
343
                    p_sys->i_remainder += p_filter->input.i_rate;
321
344
                    break;
322
345
                }
323
346
            }
326
349
                /* Perform left-wing inner product */
327
350
                FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
328
351
                               SMALL_FILTER_NWING, p_in, p_out,
329
 
                               p_filter->p_sys->i_remainder,
 
352
                               p_sys->i_remainder,
330
353
                               p_filter->output.i_rate, p_filter->input.i_rate,
331
354
                               -1, i_nb_channels );
332
355
                /* Perform right-wing inner product */
333
356
                FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
334
357
                               SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
335
358
                               p_filter->output.i_rate -
336
 
                               p_filter->p_sys->i_remainder,
 
359
                               p_sys->i_remainder,
337
360
                               p_filter->output.i_rate, p_filter->input.i_rate,
338
361
                               1, i_nb_channels );
339
362
            }
341
364
            p_out += i_nb_channels;
342
365
            i_out++;
343
366
 
344
 
            p_filter->p_sys->i_remainder += p_filter->input.i_rate;
 
367
            p_sys->i_remainder += p_filter->input.i_rate;
345
368
        }
346
369
 
347
370
        p_in += i_nb_channels;
348
 
        p_filter->p_sys->i_remainder -= p_filter->output.i_rate;
 
371
        p_sys->i_remainder -= p_filter->output.i_rate;
349
372
    }
350
373
 
351
374
    /* Apply the new rate for the rest of the samples */
352
375
    if( i_in < i_in_nb - i_filter_wing )
353
376
    {
354
 
        p_filter->p_sys->i_old_rate   = p_filter->input.i_rate;
355
 
        p_filter->p_sys->d_old_factor = d_factor;
356
 
        p_filter->p_sys->i_old_wing   = i_filter_wing;
 
377
        p_sys->i_old_rate   = p_filter->input.i_rate;
 
378
        p_sys->d_old_factor = d_factor;
 
379
        p_sys->i_old_wing   = i_filter_wing;
357
380
    }
358
381
    for( ; i_in < i_in_nb - i_filter_wing; i_in++ )
359
382
    {
360
 
        while( p_filter->p_sys->i_remainder < p_filter->output.i_rate )
 
383
        while( p_sys->i_remainder < p_filter->output.i_rate )
361
384
        {
362
385
 
363
386
            if( d_factor >= 1 )
367
390
                /* Perform left-wing inner product */
368
391
                FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
369
392
                               SMALL_FILTER_NWING, p_in, p_out,
370
 
                               p_filter->p_sys->i_remainder,
 
393
                               p_sys->i_remainder,
371
394
                               p_filter->output.i_rate,
372
395
                               -1, i_nb_channels );
373
396
 
375
398
                FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
376
399
                               SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
377
400
                               p_filter->output.i_rate -
378
 
                               p_filter->p_sys->i_remainder,
 
401
                               p_sys->i_remainder,
379
402
                               p_filter->output.i_rate,
380
403
                               1, i_nb_channels );
381
404
 
382
405
#if 0
383
406
                /* Normalize for unity filter gain */
384
 
                for( i = 0; i < i_nb_channels; i++ )
 
407
                for( int i = 0; i < i_nb_channels; i++ )
385
408
                {
386
409
                    *(p_out+i) *= d_old_scale_factor;
387
410
                }
392
415
                {
393
416
                    p_out += i_nb_channels;
394
417
                    i_out++;
395
 
                    p_filter->p_sys->i_remainder += p_filter->input.i_rate;
 
418
                    p_sys->i_remainder += p_filter->input.i_rate;
396
419
                    break;
397
420
                }
398
421
            }
401
424
                /* Perform left-wing inner product */
402
425
                FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
403
426
                               SMALL_FILTER_NWING, p_in, p_out,
404
 
                               p_filter->p_sys->i_remainder,
 
427
                               p_sys->i_remainder,
405
428
                               p_filter->output.i_rate, p_filter->input.i_rate,
406
429
                               -1, i_nb_channels );
407
430
                /* Perform right-wing inner product */
408
431
                FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
409
432
                               SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
410
433
                               p_filter->output.i_rate -
411
 
                               p_filter->p_sys->i_remainder,
 
434
                               p_sys->i_remainder,
412
435
                               p_filter->output.i_rate, p_filter->input.i_rate,
413
436
                               1, i_nb_channels );
414
437
            }
416
439
            p_out += i_nb_channels;
417
440
            i_out++;
418
441
 
419
 
            p_filter->p_sys->i_remainder += p_filter->input.i_rate;
 
442
            p_sys->i_remainder += p_filter->input.i_rate;
420
443
        }
421
444
 
422
445
        p_in += i_nb_channels;
423
 
        p_filter->p_sys->i_remainder -= p_filter->output.i_rate;
 
446
        p_sys->i_remainder -= p_filter->output.i_rate;
424
447
    }
425
448
 
426
449
    /* Buffer i_filter_wing * 2 samples for next time */
427
 
    if( p_filter->p_sys->i_old_wing )
 
450
    if( p_sys->i_old_wing )
428
451
    {
429
 
        memcpy( p_filter->p_sys->p_buf,
430
 
                p_in_orig + (i_in_nb - 2 * p_filter->p_sys->i_old_wing) *
431
 
                i_nb_channels, (2 * p_filter->p_sys->i_old_wing) *
 
452
        memcpy( p_sys->p_buf,
 
453
                p_in_orig + (i_in_nb - 2 * p_sys->i_old_wing) *
 
454
                i_nb_channels, (2 * p_sys->i_old_wing) *
432
455
                p_filter->input.i_bytes_per_frame );
433
456
    }
434
457
 
444
467
 
445
468
    /* Finalize aout buffer */
446
469
    p_out_buf->i_nb_samples = i_out;
447
 
    p_out_buf->start_date = aout_DateGet( &p_filter->p_sys->end_date );
448
 
    p_out_buf->end_date = aout_DateIncrement( &p_filter->p_sys->end_date,
 
470
    p_out_buf->start_date = aout_DateGet( &p_sys->end_date );
 
471
    p_out_buf->end_date = aout_DateIncrement( &p_sys->end_date,
449
472
                                              p_out_buf->i_nb_samples );
450
473
 
451
474
    p_out_buf->i_nb_bytes = p_out_buf->i_nb_samples *
453
476
 
454
477
}
455
478
 
456
 
void FilterFloatUP( float Imp[], float ImpD[], uint16_t Nwing, float *p_in,
 
479
/*****************************************************************************
 
480
 * OpenFilter:
 
481
 *****************************************************************************/
 
482
static int OpenFilter( vlc_object_t *p_this )
 
483
{
 
484
    filter_t *p_filter = (filter_t *)p_this;
 
485
    filter_sys_t *p_sys;
 
486
    unsigned int i_out_rate  = p_filter->fmt_out.audio.i_rate;
 
487
    double d_factor;
 
488
    int i_filter_wing;
 
489
 
 
490
    if( p_filter->fmt_in.audio.i_rate == p_filter->fmt_out.audio.i_rate ||
 
491
        p_filter->fmt_in.i_codec != VLC_FOURCC('f','l','3','2') )
 
492
    {
 
493
        return VLC_EGENERIC;
 
494
    }
 
495
 
 
496
#if !defined( SYS_DARWIN )
 
497
    if( !config_GetInt( p_this, "hq-resampling" ) )
 
498
    {
 
499
        return VLC_EGENERIC;
 
500
    }
 
501
#endif
 
502
 
 
503
    /* Allocate the memory needed to store the module's structure */
 
504
    p_filter->p_sys = p_sys = malloc( sizeof(struct filter_sys_t) );
 
505
    if( p_sys == NULL )
 
506
        return VLC_ENOMEM;
 
507
 
 
508
    /* Calculate worst case for the length of the filter wing */
 
509
    d_factor = (double)i_out_rate / p_filter->fmt_in.audio.i_rate;
 
510
    i_filter_wing = ((SMALL_FILTER_NMULT + 1)/2.0)
 
511
                      * __MAX(1.0, 1.0/d_factor) + 10;
 
512
    p_filter->p_sys->i_buf_size = p_filter->fmt_in.audio.i_channels *
 
513
        sizeof(int32_t) * 2 * i_filter_wing;
 
514
 
 
515
    /* Allocate enough memory to buffer previous samples */
 
516
    p_filter->p_sys->p_buf = malloc( p_filter->p_sys->i_buf_size );
 
517
    if( p_filter->p_sys->p_buf == NULL )
 
518
    {
 
519
        free( p_sys );
 
520
        return VLC_ENOMEM;
 
521
    }
 
522
 
 
523
    p_filter->p_sys->i_old_wing = 0;
 
524
    p_sys->b_first = true;
 
525
    p_sys->b_filter2 = true;
 
526
    p_filter->pf_audio_filter = Resample;
 
527
 
 
528
    msg_Dbg( p_this, "%4.4s/%iKHz/%i->%4.4s/%iKHz/%i",
 
529
             (char *)&p_filter->fmt_in.i_codec,
 
530
             p_filter->fmt_in.audio.i_rate,
 
531
             p_filter->fmt_in.audio.i_channels,
 
532
             (char *)&p_filter->fmt_out.i_codec,
 
533
             p_filter->fmt_out.audio.i_rate,
 
534
             p_filter->fmt_out.audio.i_channels);
 
535
 
 
536
    p_filter->fmt_out = p_filter->fmt_in;
 
537
    p_filter->fmt_out.audio.i_rate = i_out_rate;
 
538
 
 
539
    return 0;
 
540
}
 
541
 
 
542
/*****************************************************************************
 
543
 * CloseFilter : deallocate data structures
 
544
 *****************************************************************************/
 
545
static void CloseFilter( vlc_object_t *p_this )
 
546
{
 
547
    filter_t *p_filter = (filter_t *)p_this;
 
548
    free( p_filter->p_sys->p_buf );
 
549
    free( p_filter->p_sys );
 
550
}
 
551
 
 
552
/*****************************************************************************
 
553
 * Resample
 
554
 *****************************************************************************/
 
555
static block_t *Resample( filter_t *p_filter, block_t *p_block )
 
556
{
 
557
    aout_filter_t aout_filter;
 
558
    aout_buffer_t in_buf, out_buf;
 
559
    block_t *p_out;
 
560
    int i_out_size;
 
561
    int i_bytes_per_frame;
 
562
 
 
563
    if( !p_block || !p_block->i_samples )
 
564
    {
 
565
        if( p_block ) p_block->pf_release( p_block );
 
566
        return NULL;
 
567
    }
 
568
 
 
569
    i_bytes_per_frame = p_filter->fmt_out.audio.i_channels *
 
570
                  p_filter->fmt_out.audio.i_bitspersample / 8;
 
571
 
 
572
    i_out_size = i_bytes_per_frame * ( 1 + (p_block->i_samples *
 
573
        p_filter->fmt_out.audio.i_rate / p_filter->fmt_in.audio.i_rate));
 
574
 
 
575
    p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size );
 
576
    if( !p_out )
 
577
    {
 
578
        msg_Warn( p_filter, "can't get output buffer" );
 
579
        p_block->pf_release( p_block );
 
580
        return NULL;
 
581
    }
 
582
 
 
583
    p_out->i_samples = i_out_size / i_bytes_per_frame;
 
584
    p_out->i_dts = p_block->i_dts;
 
585
    p_out->i_pts = p_block->i_pts;
 
586
    p_out->i_length = p_block->i_length;
 
587
 
 
588
    aout_filter.p_sys = (struct aout_filter_sys_t *)p_filter->p_sys;
 
589
    aout_filter.input = p_filter->fmt_in.audio;
 
590
    aout_filter.input.i_bytes_per_frame = p_filter->fmt_in.audio.i_channels *
 
591
                  p_filter->fmt_in.audio.i_bitspersample / 8;
 
592
    aout_filter.output = p_filter->fmt_out.audio;
 
593
    aout_filter.output.i_bytes_per_frame = p_filter->fmt_out.audio.i_channels *
 
594
                  p_filter->fmt_out.audio.i_bitspersample / 8;
 
595
    aout_filter.b_continuity = !p_filter->p_sys->b_first;
 
596
    p_filter->p_sys->b_first = false;
 
597
 
 
598
    in_buf.p_buffer = p_block->p_buffer;
 
599
    in_buf.i_nb_bytes = in_buf.i_size = p_block->i_buffer;
 
600
    in_buf.i_nb_samples = p_block->i_samples;
 
601
    out_buf.p_buffer = p_out->p_buffer;
 
602
    out_buf.i_nb_bytes = out_buf.i_size = p_out->i_buffer;
 
603
    out_buf.i_nb_samples = p_out->i_samples;
 
604
 
 
605
    DoWork( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf );
 
606
 
 
607
    p_block->pf_release( p_block );
 
608
 
 
609
    p_out->i_buffer = out_buf.i_nb_bytes;
 
610
    p_out->i_samples = out_buf.i_nb_samples;
 
611
 
 
612
    return p_out;
 
613
}
 
614
 
 
615
void FilterFloatUP( const float Imp[], const float ImpD[], uint16_t Nwing, float *p_in,
457
616
                    float *p_out, uint32_t ui_remainder,
458
617
                    uint32_t ui_output_rate, int16_t Inc, int i_nb_channels )
459
618
{
460
 
    float *Hp, *Hdp, *End;
 
619
    const float *Hp, *Hdp, *End;
461
620
    float t, temp;
462
621
    uint32_t ui_linear_remainder;
463
622
    int i;
496
655
    }
497
656
}
498
657
 
499
 
void FilterFloatUD( float Imp[], float ImpD[], uint16_t Nwing, float *p_in,
 
658
void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing, float *p_in,
500
659
                    float *p_out, uint32_t ui_remainder,
501
660
                    uint32_t ui_output_rate, uint32_t ui_input_rate,
502
661
                    int16_t Inc, int i_nb_channels )
503
662
{
504
 
    float *Hp, *Hdp, *End;
 
663
    const float *Hp, *Hdp, *End;
505
664
    float t, temp;
506
665
    uint32_t ui_linear_remainder;
507
666
    int i, ui_counter = 0;