Changeset 2c93e8563e99c72f3dae36226a6e8f46441cd93e

Show
Ignore:
Timestamp:
18/03/05 00:34:04 (4 years ago)
Author:
Gildas Bazin <gbazin@videolan.org>
git-committer:
Gildas Bazin <gbazin@videolan.org> 1111102444 +0000
git-parent:

[d680724364fbd1222282d1e9c5d8d0c16f171cf1]

git-author:
Gildas Bazin <gbazin@videolan.org> 1111102444 +0000
Message:

* modules/audio_filter/resampler/linear.c: ported linear resampler to audio filter 2 architecture. Patch courtesy of Matthew Hodgson (matthew at mxtelecom dot com) + cleanup and fixes by me.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/audio_filter/resampler/linear.c

    ra90a19a r2c93e85  
    3232#include "audio_output.h" 
    3333#include "aout_internal.h" 
     34#include "vlc_filter.h" 
     35#include "vlc_block.h" 
    3436 
    3537/***************************************************************************** 
     
    4143                        aout_buffer_t * ); 
    4244 
     45static int  OpenFilter ( vlc_object_t * ); 
     46static void CloseFilter( vlc_object_t * ); 
     47static block_t *Resample( filter_t *, block_t * ); 
     48 
    4349/***************************************************************************** 
    4450 * Local structures 
    4551 *****************************************************************************/ 
    46 struct aout_filter_sys_t 
     52struct filter_sys_t 
    4753{ 
    4854    int32_t *p_prev_sample;       /* this filter introduces a 1 sample delay */ 
     
    6268    set_capability( "audio filter", 5 ); 
    6369    set_callbacks( Create, Close ); 
     70 
     71    add_submodule(); 
     72    set_description( _("audio filter for linear interpolation resampling") ); 
     73    set_capability( "audio filter2", 5 ); 
     74    set_callbacks( OpenFilter, CloseFilter ); 
    6475vlc_module_end(); 
    6576 
     
    7081{ 
    7182    aout_filter_t * p_filter = (aout_filter_t *)p_this; 
     83    struct filter_sys_t * p_sys; 
     84     
    7285    if ( p_filter->input.i_rate == p_filter->output.i_rate 
    7386          || p_filter->input.i_format != p_filter->output.i_format 
     
    8295 
    8396    /* Allocate the memory needed to store the module's structure */ 
    84     p_filter->p_sys = malloc( sizeof(struct aout_filter_sys_t) ); 
    85     if( p_filter->p_sys == NULL ) 
     97    p_sys = malloc( sizeof(filter_sys_t) ); 
     98    p_filter->p_sys = (struct aout_filter_sys_t *)p_sys; 
     99    if( p_sys == NULL ) 
    86100    { 
    87101        msg_Err( p_filter, "out of memory" ); 
    88102        return VLC_ENOMEM; 
    89103    } 
    90     p_filter->p_sys->p_prev_sample = malloc( 
     104    p_sys->p_prev_sample = malloc( 
    91105        aout_FormatNbChannels( &p_filter->input ) * sizeof(int32_t) ); 
    92     if( p_filter->p_sys->p_prev_sample == NULL ) 
     106    if( p_sys->p_prev_sample == NULL ) 
    93107    { 
    94108        msg_Err( p_filter, "out of memory" ); 
     
    111125{ 
    112126    aout_filter_t * p_filter = (aout_filter_t *)p_this; 
    113     free( p_filter->p_sys->p_prev_sample ); 
    114     free( p_filter->p_sys ); 
     127    filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys; 
     128     
     129    free( p_sys->p_prev_sample ); 
     130    free( p_sys ); 
    115131} 
    116132 
     
    121137                    aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) 
    122138{ 
     139    filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys; 
    123140    float *p_in_orig, *p_in, *p_out = (float *)p_out_buf->p_buffer; 
    124     float *p_prev_sample = (float *)p_filter->p_sys->p_prev_sample; 
     141    float *p_prev_sample = (float *)p_sys->p_prev_sample; 
    125142 
    126143    int i_nb_channels = aout_FormatNbChannels( &p_filter->input ); 
     
    161178    { 
    162179        p_filter->b_continuity = VLC_TRUE; 
    163         p_filter->p_sys->i_remainder = 0; 
    164         aout_DateInit( &p_filter->p_sys->end_date, p_filter->output.i_rate ); 
     180        p_sys->i_remainder = 0; 
     181        aout_DateInit( &p_sys->end_date, p_filter->output.i_rate ); 
    165182    } 
    166183    else 
    167184    { 
    168         while( p_filter->p_sys->i_remainder < p_filter->output.i_rate ) 
     185        while( p_sys->i_remainder < p_filter->output.i_rate ) 
    169186        { 
    170187            for( i_chan = i_nb_channels ; i_chan ; ) 
     
    173190                p_out[i_chan] = p_prev_sample[i_chan]; 
    174191                p_out[i_chan] += ( (p_prev_sample[i_chan] - p_in[i_chan]) 
    175                                    * p_filter->p_sys->i_remainder 
     192                                   * p_sys->i_remainder 
    176193                                   / p_filter->output.i_rate ); 
    177194            } 
     
    179196              i_out++; 
    180197 
    181             p_filter->p_sys->i_remainder += p_filter->input.i_rate; 
     198            p_sys->i_remainder += p_filter->input.i_rate; 
    182199        } 
    183         p_filter->p_sys->i_remainder -= p_filter->output.i_rate; 
     200        p_sys->i_remainder -= p_filter->output.i_rate; 
    184201    } 
    185202 
     
    187204    for( i_in = 0; i_in < i_in_nb - 1; i_in++ ) 
    188205    { 
    189         while( p_filter->p_sys->i_remainder < p_filter->output.i_rate ) 
     206        while( p_sys->i_remainder < p_filter->output.i_rate ) 
    190207        { 
    191208            for( i_chan = i_nb_channels ; i_chan ; ) 
     
    195212                p_out[i_chan] += ( (p_in[i_chan] - 
    196213                    p_in[i_chan + i_nb_channels]) 
    197                     * p_filter->p_sys->i_remainder / p_filter->output.i_rate ); 
     214                    * p_sys->i_remainder / p_filter->output.i_rate ); 
    198215            } 
    199216            p_out += i_nb_channels; 
    200217              i_out++; 
    201218 
    202             p_filter->p_sys->i_remainder += p_filter->input.i_rate; 
     219            p_sys->i_remainder += p_filter->input.i_rate; 
    203220        } 
    204221 
    205222        p_in += i_nb_channels; 
    206         p_filter->p_sys->i_remainder -= p_filter->output.i_rate; 
     223        p_sys->i_remainder -= p_filter->output.i_rate; 
    207224    } 
    208225 
     
    218235 
    219236    if( p_in_buf->start_date != 
    220         aout_DateGet( &p_filter->p_sys->end_date ) ) 
    221     { 
    222         aout_DateSet( &p_filter->p_sys->end_date, p_in_buf->start_date ); 
    223     } 
    224  
    225     p_out_buf->end_date = aout_DateIncrement( &p_filter->p_sys->end_date, 
     237        aout_DateGet( &p_sys->end_date ) ) 
     238    { 
     239        aout_DateSet( &p_sys->end_date, p_in_buf->start_date ); 
     240    } 
     241 
     242    p_out_buf->end_date = aout_DateIncrement( &p_sys->end_date, 
    226243                                              p_out_buf->i_nb_samples ); 
    227244 
     
    234251 
    235252} 
     253 
     254/***************************************************************************** 
     255 * OpenFilter: 
     256 *****************************************************************************/ 
     257static int OpenFilter( vlc_object_t *p_this ) 
     258{ 
     259    filter_t *p_filter = (filter_t *)p_this; 
     260    filter_sys_t *p_sys; 
     261    int i_out_rate  = p_filter->fmt_out.audio.i_rate; 
     262 
     263    if( p_filter->fmt_in.audio.i_rate == p_filter->fmt_out.audio.i_rate || 
     264        p_filter->fmt_in.i_codec != VLC_FOURCC('f','l','3','2') ) 
     265    { 
     266        return VLC_EGENERIC; 
     267    } 
     268     
     269    /* Allocate the memory needed to store the module's structure */ 
     270    p_filter->p_sys = p_sys = malloc( sizeof(struct filter_sys_t) ); 
     271    if( p_sys == NULL ) 
     272    { 
     273        msg_Err( p_filter, "out of memory" ); 
     274        return VLC_ENOMEM; 
     275    } 
     276 
     277    p_sys->p_prev_sample = malloc( 
     278        p_filter->fmt_in.audio.i_channels * sizeof(int32_t) ); 
     279    if( p_sys->p_prev_sample == NULL ) 
     280    { 
     281        msg_Err( p_filter, "out of memory" ); 
     282        free( p_sys ); 
     283        return VLC_ENOMEM; 
     284    } 
     285 
     286    p_filter->pf_audio_filter = Resample; 
     287 
     288    msg_Dbg( p_this, "%4.4s/%iKHz/%i->%4.4s/%iKHz/%i", 
     289             (char *)&p_filter->fmt_in.i_codec, 
     290             p_filter->fmt_in.audio.i_rate, 
     291             p_filter->fmt_in.audio.i_channels, 
     292             (char *)&p_filter->fmt_out.i_codec, 
     293             p_filter->fmt_out.audio.i_rate, 
     294             p_filter->fmt_out.audio.i_channels); 
     295 
     296    p_filter->fmt_out = p_filter->fmt_in; 
     297    p_filter->fmt_out.audio.i_rate = i_out_rate; 
     298 
     299    return 0; 
     300} 
     301 
     302/***************************************************************************** 
     303 * CloseFilter : deallocate data structures 
     304 *****************************************************************************/ 
     305static void CloseFilter( vlc_object_t *p_this ) 
     306{ 
     307    filter_t *p_filter = (filter_t *)p_this; 
     308    free( p_filter->p_sys->p_prev_sample ); 
     309    free( p_filter->p_sys ); 
     310} 
     311 
     312/***************************************************************************** 
     313 * Resample 
     314 *****************************************************************************/ 
     315static block_t *Resample( filter_t *p_filter, block_t *p_block ) 
     316{ 
     317    aout_filter_t aout_filter; 
     318    aout_buffer_t in_buf, out_buf; 
     319    block_t *p_out; 
     320    int i_out_size; 
     321    int i_bytes_per_frame; 
     322 
     323    if( !p_block || !p_block->i_samples ) 
     324    { 
     325        if( p_block ) p_block->pf_release( p_block ); 
     326        return NULL; 
     327    } 
     328     
     329    i_bytes_per_frame = p_filter->fmt_out.audio.i_channels * 
     330                  p_filter->fmt_out.audio.i_bitspersample / 8; 
     331     
     332    i_out_size = i_bytes_per_frame * ( 1 + (p_block->i_samples *  
     333        p_filter->fmt_out.audio.i_rate / p_filter->fmt_in.audio.i_rate)); 
     334 
     335    p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size ); 
     336    if( !p_out ) 
     337    { 
     338        msg_Warn( p_filter, "can't get output buffer" ); 
     339        p_block->pf_release( p_block ); 
     340        return NULL; 
     341    } 
     342 
     343    p_out->i_samples = i_out_size / i_bytes_per_frame; 
     344    p_out->i_dts = p_block->i_dts; 
     345    p_out->i_pts = p_block->i_pts; 
     346    p_out->i_length = p_block->i_length; 
     347 
     348    aout_filter.p_sys = (struct aout_filter_sys_t *)p_filter->p_sys; 
     349    aout_filter.input = p_filter->fmt_in.audio; 
     350    aout_filter.output = p_filter->fmt_out.audio; 
     351    aout_filter.b_continuity = VLC_FALSE; 
     352 
     353    in_buf.p_buffer = p_block->p_buffer; 
     354    in_buf.i_nb_bytes = p_block->i_buffer; 
     355    in_buf.i_nb_samples = p_block->i_samples; 
     356    out_buf.p_buffer = p_out->p_buffer; 
     357    out_buf.i_nb_bytes = p_out->i_buffer; 
     358    out_buf.i_nb_samples = p_out->i_samples; 
     359 
     360    DoWork( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf ); 
     361 
     362    p_block->pf_release( p_block ); 
     363     
     364    p_out->i_buffer = out_buf.i_nb_bytes; 
     365    p_out->i_samples = out_buf.i_nb_samples; 
     366 
     367    return p_out; 
     368}