Changeset 352b5f932f4c6b66a2c0a0b57e749cd6be7f44ee

Show
Ignore:
Timestamp:
08/20/06 23:00:34 (2 years ago)
Author:
Jean-Paul Saman <jpsaman@videolan.org>
git-committer:
Jean-Paul Saman <jpsaman@videolan.org> 1156107634 +0000
git-parent:

[663716c008efd7b0a6ce435d89f66b12b33caa81]

git-author:
Jean-Paul Saman <jpsaman@videolan.org> 1156107634 +0000
Message:

Make headphone also an audio_filter2

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/audio_filter/channel_mixer/headphone.c

    r5ca8805 r352b5f9  
    3131 
    3232#include <vlc/vlc.h> 
    33 #include "audio_output.h" 
    34 #include "aout_internal.h" 
     33#include <audio_output.h> 
     34#include <aout_internal.h> 
     35#include <vlc_filter.h> 
     36#include <vlc_block.h> 
    3537 
    3638/***************************************************************************** 
     
    4244static void DoWork    ( aout_instance_t *, aout_filter_t *, aout_buffer_t *, 
    4345                        aout_buffer_t * ); 
     46 
     47/* Audio filter2 */ 
     48static int  OpenFilter ( vlc_object_t * ); 
     49static void CloseFilter( vlc_object_t * ); 
     50static block_t *Convert( filter_t *, block_t * ); 
    4451 
    4552/***************************************************************************** 
     
    8693    set_callbacks( Create, Destroy ); 
    8794    add_shortcut( "headphone" ); 
     95 
     96    /* Audio filter 2 */ 
     97    add_submodule(); 
     98    set_description( _("Headphone virtual spatialization effect") ); 
     99    set_capability( "audio filter2", 100 ); 
     100    set_callbacks( OpenFilter, CloseFilter ); 
    88101vlc_module_end(); 
    89102 
     
    101114 
    102115struct aout_filter_sys_t 
     116{ 
     117    size_t i_overflow_buffer_size;/* in bytes */ 
     118    byte_t * p_overflow_buffer; 
     119    unsigned int i_nb_atomic_operations; 
     120    struct atomic_operation_t * p_atomic_operations; 
     121}; 
     122 
     123struct filter_sys_t 
    103124{ 
    104125    size_t i_overflow_buffer_size;/* in bytes */ 
     
    126147 *          x-axis 
    127148 *  */ 
    128 static void ComputeChannelOperations ( struct aout_filter_sys_t * p_data 
    129         , unsigned int i_rate , unsigned int i_next_atomic_operation 
    130         , int i_source_channel_offset , double d_x , double d_z 
    131         , double d_compensation_length , double d_channel_amplitude_factor ) 
     149static void ComputeChannelOperations( struct aout_filter_sys_t * p_data 
     150        , unsigned int i_rate, unsigned int i_next_atomic_operation 
     151        , int i_source_channel_offset, double d_x, double d_z 
     152        , double d_compensation_length, double d_channel_amplitude_factor ) 
    132153{ 
    133154    double d_c = 340; /*sound celerity (unit: m/s)*/ 
     
    142163        .i_delay = (int)( sqrt( (-0.1-d_x)*(-0.1-d_x) + (0-d_z)*(0-d_z) ) 
    143164                          / d_c * i_rate - d_compensation_delay ); 
    144     if ( d_x < 0 ) 
     165    if( d_x < 0 ) 
    145166    { 
    146167        p_data->p_atomic_operations[i_next_atomic_operation] 
    147168            .d_amplitude_factor = d_channel_amplitude_factor * 1.1 / 2; 
    148169    } 
    149     else if ( d_x > 0 ) 
     170    else if( d_x > 0 ) 
    150171    { 
    151172        p_data->p_atomic_operations[i_next_atomic_operation] 
     
    166187        .i_delay = (int)( sqrt( (0.1-d_x)*(0.1-d_x) + (0-d_z)*(0-d_z) ) 
    167188                          / d_c * i_rate - d_compensation_delay ); 
    168     if ( d_x < 0 ) 
     189    if( d_x < 0 ) 
    169190    { 
    170191        p_data->p_atomic_operations[i_next_atomic_operation + 1] 
    171192            .d_amplitude_factor = d_channel_amplitude_factor * 0.9 / 2; 
    172193    } 
    173     else if ( d_x > 0 ) 
     194    else if( d_x > 0 ) 
    174195    { 
    175196        p_data->p_atomic_operations[i_next_atomic_operation + 1] 
     
    183204} 
    184205 
    185 static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data 
    186         , unsigned int i_nb_channels , uint32_t i_physical_channels 
     206static int Init( vlc_object_t *p_this, struct aout_filter_sys_t * p_data 
     207        , unsigned int i_nb_channels, uint32_t i_physical_channels 
    187208        , unsigned int i_rate ) 
    188209{ 
    189     double d_x = config_GetInt ( p_filter , "headphone-dim" ); 
     210    double d_x = config_GetInt( p_this, "headphone-dim" ); 
    190211    double d_z = d_x; 
    191212    double d_z_rear = -d_x/3; 
     
    195216    unsigned int i; 
    196217 
    197     if ( p_data == NULL ) 
    198     { 
    199         msg_Dbg ( p_filter, "passing a null pointer as argument" ); 
     218    if( p_data == NULL ) 
     219    { 
     220        msg_Dbg( p_this, "passing a null pointer as argument" ); 
    200221        return 0; 
    201222    } 
    202223 
    203     if ( config_GetInt ( p_filter , "headphone-compensate" ) ) 
     224    if( config_GetInt( p_this, "headphone-compensate" ) ) 
    204225    { 
    205226        /* minimal distance to any speaker */ 
    206         if ( i_physical_channels & AOUT_CHAN_REARCENTER ) 
     227        if( i_physical_channels & AOUT_CHAN_REARCENTER ) 
    207228        { 
    208229            d_min = d_z_rear; 
     
    216237    /* Number of elementary operations */ 
    217238    p_data->i_nb_atomic_operations = i_nb_channels * 2; 
    218     if ( i_physical_channels & AOUT_CHAN_CENTER ) 
     239    if( i_physical_channels & AOUT_CHAN_CENTER ) 
    219240    { 
    220241        p_data->i_nb_atomic_operations += 2; 
    221242    } 
    222     p_data->p_atomic_operations = malloc ( sizeof(struct atomic_operation_t) 
     243    p_data->p_atomic_operations = malloc( sizeof(struct atomic_operation_t) 
    223244            * p_data->i_nb_atomic_operations ); 
    224     if ( p_data->p_atomic_operations == NULL ) 
    225     { 
    226         msg_Err( p_filter, "out of memory" ); 
     245    if( p_data->p_atomic_operations == NULL ) 
     246    { 
     247        msg_Err( p_this, "out of memory" ); 
    227248        return -1; 
    228249    } 
     
    232253    i_next_atomic_operation = 0; 
    233254    i_source_channel_offset = 0; 
    234     if ( i_physical_channels & AOUT_CHAN_LEFT ) 
    235     { 
    236         ComputeChannelOperations ( p_data , i_rate 
     255    if( i_physical_channels & AOUT_CHAN_LEFT ) 
     256    { 
     257        ComputeChannelOperations( p_data , i_rate 
    237258                , i_next_atomic_operation , i_source_channel_offset 
    238259                , -d_x , d_z , d_min , 2.0 / i_nb_channels ); 
     
    240261        i_source_channel_offset++; 
    241262    } 
    242     if ( i_physical_channels & AOUT_CHAN_RIGHT ) 
    243     { 
    244         ComputeChannelOperations ( p_data , i_rate 
     263    if( i_physical_channels & AOUT_CHAN_RIGHT ) 
     264    { 
     265        ComputeChannelOperations( p_data , i_rate 
    245266                , i_next_atomic_operation , i_source_channel_offset 
    246267                , d_x , d_z , d_min , 2.0 / i_nb_channels ); 
     
    248269        i_source_channel_offset++; 
    249270    } 
    250     if ( i_physical_channels & AOUT_CHAN_MIDDLELEFT ) 
    251     { 
    252         ComputeChannelOperations ( p_data , i_rate 
     271    if( i_physical_channels & AOUT_CHAN_MIDDLELEFT ) 
     272    { 
     273        ComputeChannelOperations( p_data , i_rate 
    253274                , i_next_atomic_operation , i_source_channel_offset 
    254275                , -d_x , 0 , d_min , 1.5 / i_nb_channels ); 
     
    256277        i_source_channel_offset++; 
    257278    } 
    258     if ( i_physical_channels & AOUT_CHAN_MIDDLERIGHT ) 
    259     { 
    260         ComputeChannelOperations ( p_data , i_rate 
     279    if( i_physical_channels & AOUT_CHAN_MIDDLERIGHT ) 
     280    { 
     281        ComputeChannelOperations( p_data , i_rate 
    261282                , i_next_atomic_operation , i_source_channel_offset 
    262283                , d_x , 0 , d_min , 1.5 / i_nb_channels ); 
     
    264285        i_source_channel_offset++; 
    265286    } 
    266     if ( i_physical_channels & AOUT_CHAN_REARLEFT ) 
    267     { 
    268         ComputeChannelOperations ( p_data , i_rate 
     287    if( i_physical_channels & AOUT_CHAN_REARLEFT ) 
     288    { 
     289        ComputeChannelOperations( p_data , i_rate 
    269290                , i_next_atomic_operation , i_source_channel_offset 
    270291                , -d_x , d_z_rear , d_min , 1.5 / i_nb_channels ); 
     
    272293        i_source_channel_offset++; 
    273294    } 
    274     if ( i_physical_channels & AOUT_CHAN_REARRIGHT ) 
    275     { 
    276         ComputeChannelOperations ( p_data , i_rate 
     295    if( i_physical_channels & AOUT_CHAN_REARRIGHT ) 
     296    { 
     297        ComputeChannelOperations( p_data , i_rate 
    277298                , i_next_atomic_operation , i_source_channel_offset 
    278299                , d_x , d_z_rear , d_min , 1.5 / i_nb_channels ); 
     
    280301        i_source_channel_offset++; 
    281302    } 
    282     if ( i_physical_channels & AOUT_CHAN_REARCENTER ) 
    283     { 
    284         ComputeChannelOperations ( p_data , i_rate 
     303    if( i_physical_channels & AOUT_CHAN_REARCENTER ) 
     304    { 
     305        ComputeChannelOperations( p_data , i_rate 
    285306                , i_next_atomic_operation , i_source_channel_offset 
    286307                , 0 , -d_z , d_min , 1.5 / i_nb_channels ); 
     
    288309        i_source_channel_offset++; 
    289310    } 
    290     if ( i_physical_channels & AOUT_CHAN_CENTER ) 
     311    if( i_physical_channels & AOUT_CHAN_CENTER ) 
    291312    { 
    292313        /* having two center channels increases the spatialization effect */ 
    293         ComputeChannelOperations ( p_data , i_rate 
     314        ComputeChannelOperations( p_data , i_rate 
    294315                , i_next_atomic_operation , i_source_channel_offset 
    295316                , d_x / 5.0 , d_z , d_min , 0.75 / i_nb_channels ); 
    296317        i_next_atomic_operation += 2; 
    297         ComputeChannelOperations ( p_data , i_rate 
     318        ComputeChannelOperations( p_data , i_rate 
    298319                , i_next_atomic_operation , i_source_channel_offset 
    299320                , -d_x / 5.0 , d_z , d_min , 0.75 / i_nb_channels ); 
     
    301322        i_source_channel_offset++; 
    302323    } 
    303     if ( i_physical_channels & AOUT_CHAN_LFE ) 
    304     { 
    305         ComputeChannelOperations ( p_data , i_rate 
     324    if( i_physical_channels & AOUT_CHAN_LFE ) 
     325    { 
     326        ComputeChannelOperations( p_data , i_rate 
    306327                , i_next_atomic_operation , i_source_channel_offset 
    307328                , 0 , d_z_rear , d_min , 5.0 / i_nb_channels ); 
     
    313334     * we need it because the process induce a delay in the samples */ 
    314335    p_data->i_overflow_buffer_size = 0; 
    315     for ( i = 0 ; i < p_data->i_nb_atomic_operations ; i++ ) 
    316     { 
    317         if ( p_data->i_overflow_buffer_size 
     336    for( i = 0 ; i < p_data->i_nb_atomic_operations ; i++ ) 
     337    { 
     338        if( p_data->i_overflow_buffer_size 
    318339                < p_data->p_atomic_operations[i].i_delay * 2 * sizeof (float) ) 
    319340        { 
     
    322343        } 
    323344    } 
    324     p_data->p_overflow_buffer = malloc ( p_data->i_overflow_buffer_size ); 
    325     if ( p_data->p_atomic_operations == NULL ) 
    326     { 
    327         msg_Err( p_filter, "out of memory" ); 
     345    p_data->p_overflow_buffer = malloc( p_data->i_overflow_buffer_size ); 
     346    if( p_data->p_atomic_operations == NULL ) 
     347    { 
     348        msg_Err( p_this, "out of memory" ); 
    328349        return -1; 
    329350    } 
    330     memset ( p_data->p_overflow_buffer , 0 , p_data->i_overflow_buffer_size ); 
     351    memset( p_data->p_overflow_buffer, 0 , p_data->i_overflow_buffer_size ); 
    331352 
    332353    /* end */ 
     
    343364 
    344365    /* Activate this filter only with stereo devices */ 
    345     if ( p_filter->output.i_physical_channels 
     366    if( p_filter->output.i_physical_channels 
    346367            != (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) ) 
    347368    { 
     
    351372 
    352373    /* Request a specific format if not already compatible */ 
    353     if ( p_filter->input.i_original_channels 
     374    if( p_filter->input.i_original_channels 
    354375            != p_filter->output.i_original_channels ) 
    355376    { 
     
    358379                                        p_filter->output.i_original_channels; 
    359380    } 
    360     if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2') 
     381    if( p_filter->input.i_format != VLC_FOURCC('f','l','3','2') 
    361382          || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') ) 
    362383    { 
     
    365386        p_filter->output.i_format = VLC_FOURCC('f','l','3','2'); 
    366387    } 
    367     if ( p_filter->input.i_rate != p_filter->output.i_rate ) 
     388    if( p_filter->input.i_rate != p_filter->output.i_rate ) 
    368389    { 
    369390        b_fit = VLC_FALSE; 
    370391        p_filter->input.i_rate = p_filter->output.i_rate; 
    371392    } 
    372     if ( p_filter->input.i_physical_channels == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) 
     393    if( p_filter->input.i_physical_channels == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) 
    373394          && ( p_filter->input.i_original_channels & AOUT_CHAN_DOLBYSTEREO ) 
    374395          && ! config_GetInt ( p_filter , "headphone-dolby" ) ) 
     
    380401                                              AOUT_CHAN_REARRIGHT; 
    381402    } 
    382     if ( ! b_fit ) 
     403    if( ! b_fit ) 
    383404    { 
    384405        msg_Dbg( p_filter, "requesting specific format" ); 
     
    388409    /* Allocate the memory needed to store the module's structure */ 
    389410    p_filter->p_sys = malloc( sizeof(struct aout_filter_sys_t) ); 
    390     if ( p_filter->p_sys == NULL ) 
     411    if( p_filter->p_sys == NULL ) 
    391412    { 
    392413        msg_Err( p_filter, "out of memory" ); 
     
    398419    p_filter->p_sys->p_atomic_operations = NULL; 
    399420 
    400     if ( Init( p_filter , p_filter->p_sys 
     421    if( Init( VLC_OBJECT(p_filter), p_filter->p_sys 
    401422                , aout_FormatNbChannels ( &p_filter->input ) 
    402423                , p_filter->input.i_physical_channels 
     
    419440    aout_filter_t * p_filter = (aout_filter_t *)p_this; 
    420441 
    421     if ( p_filter->p_sys != NULL ) 
    422     { 
    423         if ( p_filter->p_sys->p_overflow_buffer != NULL ) 
    424         { 
    425             free ( p_filter->p_sys->p_overflow_buffer ); 
    426         } 
    427         if ( p_filter->p_sys->p_atomic_operations != NULL ) 
    428         { 
    429             free ( p_filter->p_sys->p_atomic_operations ); 
    430         } 
    431         free ( p_filter->p_sys ); 
     442    if( p_filter->p_sys != NULL ) 
     443    { 
     444        if( p_filter->p_sys->p_overflow_buffer != NULL ) 
     445        { 
     446            free( p_filter->p_sys->p_overflow_buffer ); 
     447        } 
     448        if( p_filter->p_sys->p_atomic_operations != NULL ) 
     449        { 
     450            free( p_filter->p_sys->p_atomic_operations ); 
     451        } 
     452        free( p_filter->p_sys ); 
    432453        p_filter->p_sys = NULL; 
    433454    } 
     
    457478    unsigned int i_delay; 
    458479    double d_amplitude_factor; 
    459  
    460480 
    461481    /* out buffer characterisitcs */ 
     
    465485    i_out_size = p_out_buf->i_nb_bytes; 
    466486 
    467     if ( p_filter->p_sys != NULL ) 
     487    if( p_filter->p_sys != NULL ) 
    468488    { 
    469489        /* Slide the overflow buffer */ 
     
    471491        i_overflow_size = p_filter->p_sys->i_overflow_buffer_size; 
    472492 
    473         memset ( p_out , 0 , i_out_size ); 
     493        memset( p_out, 0, i_out_size ); 
    474494        if ( i_out_size > i_overflow_size ) 
    475             memcpy ( p_out , p_overflow , i_overflow_size ); 
     495            memcpy( p_out, p_overflow, i_overflow_size ); 
    476496        else 
    477             memcpy ( p_out , p_overflow , i_out_size ); 
     497            memcpy( p_out, p_overflow, i_out_size ); 
    478498 
    479499        p_slide = p_filter->p_sys->p_overflow_buffer; 
    480         while ( p_slide < p_overflow + i_overflow_size ) 
    481         { 
    482             if ( p_slide + i_out_size < p_overflow + i_overflow_size ) 
     500        while( p_slide < p_overflow + i_overflow_size ) 
     501        { 
     502            if( p_slide + i_out_size < p_overflow + i_overflow_size ) 
    483503            { 
    484                 memset ( p_slide , 0 , i_out_size ); 
    485                 if ( p_slide + 2 * i_out_size < p_overflow + i_overflow_size ) 
    486                     memcpy ( p_slide , p_slide + i_out_size , i_out_size ); 
     504                memset( p_slide, 0, i_out_size ); 
     505                if( p_slide + 2 * i_out_size < p_overflow + i_overflow_size ) 
     506                    memcpy( p_slide, p_slide + i_out_size, i_out_size ); 
    487507                else 
    488                     memcpy ( p_slide , p_slide + i_out_size 
    489                       , p_overflow + i_overflow_size - ( p_slide + i_out_size ) ); 
     508                    memcpy( p_slide, p_slide + i_out_size, 
     509                            p_overflow + i_overflow_size - ( p_slide + i_out_size ) ); 
    490510            } 
    491511            else 
    492512            { 
    493                 memset ( p_slide , 0 , p_overflow + i_overflow_size - p_slide ); 
     513                memset( p_slide, 0, p_overflow + i_overflow_size - p_slide ); 
    494514            } 
    495515            p_slide += i_out_size; 
     
    497517 
    498518        /* apply the atomic operations */ 
    499         for ( i = 0 ; i < p_filter->p_sys->i_nb_atomic_operations ; i++ ) 
     519        for( i = 0; i < p_filter->p_sys->i_nb_atomic_operations; i++ ) 
    500520        { 
    501521            /* shorter variable names */ 
     
    508528                = p_filter->p_sys->p_atomic_operations[i].d_amplitude_factor; 
    509529 
    510             if ( p_out_buf->i_nb_samples > i_delay ) 
     530            if( p_out_buf->i_nb_samples > i_delay ) 
    511531            { 
    512532                /* current buffer coefficients */ 
    513                 for ( j = 0 ; j < p_out_buf->i_nb_samples - i_delay ; j++ ) 
     533                for( j = 0; j < p_out_buf->i_nb_samples - i_delay; j++ ) 
    514534                { 
    515535                    ((float*)p_out)[ (i_delay+j)*i_output_nb + i_dest_channel_offset ] 
     
    519539 
    520540                /* overflow buffer coefficients */ 
    521                 for ( j = 0 ; j < i_delay ; j++ ) 
     541                for( j = 0; j < i_delay; j++ ) 
    522542                { 
    523543                    ((float*)p_overflow)[ j*i_output_nb + i_dest_channel_offset ] 
     
    530550            { 
    531551                /* overflow buffer coefficients only */ 
    532                 for ( j = 0 ; j < p_out_buf->i_nb_samples ; j++ ) 
     552                for( j = 0; j < p_out_buf->i_nb_samples; j++ ) 
    533553                { 
    534554                    ((float*)p_overflow)[ (i_delay - p_out_buf->i_nb_samples + j) 
     
    542562    else 
    543563    { 
    544         memset ( p_out , 0 , i_out_size ); 
     564        memset( p_out, 0, i_out_size ); 
    545565    } 
    546566} 
     567 
     568/* 
     569 * Audio filter 2 
     570 */ 
     571/***************************************************************************** 
     572 * OpenFilter: 
     573 *****************************************************************************/ 
     574static int OpenFilter( vlc_object_t *p_this ) 
     575{ 
     576    filter_t *p_filter = (filter_t *)p_this; 
     577    vlc_bool_t b_fit = VLC_TRUE; 
     578 
     579    /* Activate this filter only with stereo devices */ 
     580    if( p_filter->fmt_out.audio.i_physical_channels 
     581            != (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) ) 
     582    { 
     583        msg_Dbg( p_filter, "filter discarded (incompatible format)" ); 
     584        return VLC_EGENERIC; 
     585    } 
     586 
     587    /* Request a specific format if not already compatible */ 
     588    if( p_filter->fmt_in.audio.i_original_channels 
     589            != p_filter->fmt_out.audio.i_original_channels ) 
     590    { 
     591        b_fit = VLC_FALSE; 
     592        p_filter->fmt_in.audio.i_original_channels = 
     593                                        p_filter->fmt_out.audio.i_original_channels; 
     594    } 
     595    if( p_filter->fmt_in.audio.i_format != VLC_FOURCC('f','l','3','2') 
     596          || p_filter->fmt_out.audio.i_format != VLC_FOURCC('f','l','3','2') ) 
     597    { 
     598        b_fit = VLC_FALSE; 
     599        p_filter->fmt_in.audio.i_format = VLC_FOURCC('f','l','3','2'); 
     600        p_filter->fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2'); 
     601    } 
     602    if( p_filter->fmt_in.audio.i_rate != p_filter->fmt_out.audio.i_rate ) 
     603    { 
     604        b_fit = VLC_FALSE; 
     605        p_filter->fmt_in.audio.i_rate = p_filter->fmt_out.audio.i_rate; 
     606    } 
     607    if( p_filter->fmt_in.audio.i_physical_channels == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) 
     608          && ( p_filter->fmt_in.audio.i_original_channels & AOUT_CHAN_DOLBYSTEREO ) 
     609          && !config_GetInt( p_filter, "headphone-dolby" ) ) 
     610    { 
     611        b_fit = VLC_FALSE; 
     612        p_filter->fmt_in.audio.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | 
     613                                              AOUT_CHAN_CENTER | 
     614                                              AOUT_CHAN_REARLEFT | 
     615                                              AOUT_CHAN_REARRIGHT; 
     616    } 
     617    if( !b_fit ) 
     618    { 
     619        msg_Dbg( p_filter, "requesting specific format" ); 
     620        return VLC_EGENERIC; 
     621    } 
     622 
     623    /* Allocate the memory needed to store the module's structure */ 
     624    p_filter->p_sys = malloc( sizeof(struct filter_sys_t) ); 
     625    if( p_filter->p_sys == NULL ) 
     626    { 
     627        msg_Err( p_filter, "out of memory" ); 
     628        return VLC_EGENERIC; 
     629    } 
     630    p_filter->p_sys->i_overflow_buffer_size = 0; 
     631    p_filter->p_sys->p_overflow_buffer = NULL; 
     632    p_filter->p_sys->i_nb_atomic_operations = 0; 
     633    p_filter->p_sys->p_atomic_operations = NULL; 
     634 
     635    if( Init( VLC_OBJECT(p_filter), (struct aout_filter_sys_t *)p_filter->p_sys 
     636                , aout_FormatNbChannels ( &(p_filter->fmt_in.audio) ) 
     637                , p_filter->fmt_in.audio.i_physical_channels 
     638                , p_filter->fmt_in.audio.i_rate ) < 0 ) 
     639    { 
     640        return VLC_EGENERIC; 
     641    } 
     642 
     643    p_filter->pf_audio_filter = Convert; 
     644    p_filter->fmt_out.audio.i_rate = p_filter->fmt_in.audio.i_rate; 
     645msg_Dbg( p_this, ">> HEADPHONE filter loaded" ); 
     646    return VLC_SUCCESS; 
     647} 
     648 
     649/***************************************************************************** 
     650 * CloseFilter : deallocate data structures 
     651 *****************************************************************************/ 
     652static void CloseFilter( vlc_object_t *p_this ) 
     653{ 
     654    filter_t *p_filter = (filter_t *)p_this; 
     655    filter_sys_t *p_sys = p_filter->p_sys; 
     656 
     657    if( p_filter->p_sys != NULL ) 
     658    { 
     659        if( p_filter->p_sys->p_overflow_buffer != NULL ) 
     660        { 
     661            free ( p_filter->p_sys->p_overflow_buffer ); 
     662        } 
     663        if( p_filter->p_sys->p_atomic_operations != NULL ) 
     664        { 
     665            free ( p_filter->p_sys->p_atomic_operations ); 
     666        } 
     667        free( p_filter->p_sys ); 
     668        p_filter->p_sys = NULL; 
     669    } 
     670 
     671    if( p_sys) free( p_sys ); 
     672} 
     673 
     674static block_t *Convert( filter_t *p_filter, block_t *p_block ) 
     675{ 
     676    aout_filter_t aout_filter; 
     677    aout_buffer_t in_buf, out_buf; 
     678    block_t *p_out; 
     679    int i_out_size; 
     680 
     681    if( !p_block || !p_block->i_samples ) 
     682    { 
     683        if( p_block ) p_block->pf_release( p_block ); 
     684        return NULL; 
     685    } 
     686 
     687    i_out_size = p_block->i_samples * 
     688      p_filter->fmt_out.audio.i_bitspersample * 
     689        p_filter->fmt_out.audio.i_channels / 8; 
     690 
     691    p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size ); 
     692    if( !p_out ) 
     693    { 
     694        msg_Warn( p_filter, "can't get output buffer" ); 
     695        if( p_block ) p_block->pf_release( p_block ); 
     696        return NULL; 
     697    } 
     698 
     699    p_out->i_samples = p_block->i_samples; 
     700    p_out->i_dts = p_block->i_dts; 
     701    p_out->i_pts = p_block->i_pts; 
     702    p_out->i_length = p_block->i_length; 
     703 
     704    aout_filter.p_sys = (struct aout_filter_sys_t *)p_filter->p_sys; 
     705    aout_filter.input = p_filter->fmt_in.audio; 
     706    aout_filter.input.i_format = p_filter->fmt_in.i_codec; 
     707    aout_filter.output = p_filter->fmt_out.audio; 
     708    aout_filter.output.i_format = p_filter->fmt_out.i_codec; 
     709    aout_filter.b_in_place = 0; 
     710 
     711    in_buf.p_buffer = p_block->p_buffer; 
     712    in_buf.i_nb_bytes = p_block->i_buffer; 
     713    in_buf.i_nb_samples = p_block->i_samples; 
     714    out_buf.p_buffer = p_out->p_buffer; 
     715    out_buf.i_nb_bytes = p_out->i_buffer; 
     716    out_buf.i_nb_samples = p_out->i_samples; 
     717 
     718    DoWork( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf ); 
     719 
     720    p_out->i_buffer = out_buf.i_nb_bytes; 
     721    p_out->i_samples = out_buf.i_nb_samples; 
     722 
     723    if( p_block ) p_block->pf_release( p_block ); 
     724    return p_out; 
     725}