Changeset 10e3212ea54875dd09bc3ac36bd31b7f795a1cb8

Show
Ignore:
Timestamp:
22/08/06 16:31:40 (2 years ago)
Author:
Jean-Paul Saman <jpsaman@videolan.org>
git-committer:
Jean-Paul Saman <jpsaman@videolan.org> 1156257100 +0000
git-parent:

[63fa138598d47f1e75e7065a03952e00be6d4780]

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

Downmix stereo to mono channel and choose with --sout-mono-channel <n> the destination channel.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/audio_filter/converter/mono.c

    r5f1df8a r10e3212  
    5252 
    5353static block_t *Convert( filter_t *p_filter, block_t *p_block ); 
    54 static void stereo_mono_downmix( aout_instance_t *, aout_filter_t *, 
    55                                  aout_buffer_t *, aout_buffer_t * ); 
    56 static unsigned int stereo_to_mono( int16_t *, int16_t *, unsigned int ); 
    57  
    58 static void silence_channel( aout_instance_t *, aout_filter_t *, 
    59                              aout_buffer_t *, aout_buffer_t * ); 
     54 
     55static unsigned int stereo_to_mono( aout_instance_t *, aout_filter_t *, 
     56                                    aout_buffer_t *, aout_buffer_t * ); 
    6057 
    6158/***************************************************************************** 
     
    6461struct filter_sys_t 
    6562{ 
    66     vlc_bool_t b_block_channel; 
    6763    int i_nb_channels; /* number of float32 per sample */ 
    6864    unsigned int i_channel_selected; 
     
    119115        (p_filter->fmt_out.i_codec != AOUT_FMT_S16_NE) ) 
    120116    { 
    121         msg_Err( p_this, "invalid format" ); 
     117        msg_Err( p_this, "filter discarded (invalid format)" ); 
    122118        return -1; 
    123119    } 
     
    145141            (unsigned int) var_GetInteger( p_this, MONO_CFG "mono-channel" ); 
    146142 
    147     /* temporarily force channel silence */ 
    148     p_sys->b_block_channel = VLC_TRUE; 
    149     if( p_sys->b_block_channel ) 
    150     { 
    151         p_filter->fmt_out.audio.i_physical_channels = 
     143#if 0 
     144    p_filter->fmt_out.audio.i_physical_channels = AOUT_CHAN_CENTER; 
     145#endif 
     146    p_filter->fmt_out.audio.i_physical_channels = 
    152147                            (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT); 
    153     } 
    154     else 
    155         p_filter->fmt_out.audio.i_physical_channels = AOUT_CHAN_CENTER; 
    156  
    157     p_filter->pf_audio_filter = Convert; 
     148 
    158149    p_filter->fmt_out.audio.i_rate = p_filter->fmt_in.audio.i_rate; 
    159150    p_filter->fmt_out.audio.i_format = p_filter->fmt_out.i_codec; 
    160151 
    161     p_sys->i_nb_channels = aout_FormatNbChannels( &(p_filter->fmt_out.audio) ); 
     152    p_sys->i_nb_channels = aout_FormatNbChannels( &(p_filter->fmt_in.audio) ); 
    162153    p_sys->i_bitspersample = p_filter->fmt_out.audio.i_bitspersample; 
     154 
     155    p_filter->pf_audio_filter = Convert; 
    163156 
    164157    msg_Dbg( p_this, "%4.4s->%4.4s, channels %d->%d, bits per sample: %i->%i", 
     
    194187    block_t *p_out = NULL; 
    195188    int i_out_size; 
     189    unsigned int i_samples; 
    196190 
    197191    if( !p_block || !p_block->i_samples ) 
     
    203197 
    204198    i_out_size = p_block->i_samples * p_filter->p_sys->i_bitspersample/8 * 
    205                  p_filter->p_sys->i_nb_channels
     199                 aout_FormatNbChannels( &(p_filter->fmt_out.audio) )
    206200 
    207201    p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size ); 
     
    213207    } 
    214208 
    215     p_out->i_samples = p_block->i_samples; 
     209    p_out->i_samples = (p_block->i_samples / p_filter->p_sys->i_nb_channels) * 
     210                            aout_FormatNbChannels( &(p_filter->fmt_out.audio) ); 
    216211    p_out->i_dts = p_block->i_dts; 
    217212    p_out->i_pts = p_block->i_pts; 
     
    229224 
    230225#if 0 
    231     if( in_buf.i_nb_bytes != (p_filter->p_sys->i_bitspersample/8) * in_buf.i_nb_samples ) 
    232     { 
    233         msg_Err( p_filter, "input buffer is not alligned" ); 
    234 /*        if( in_buf.i_nb_bytes > (p_filter->p_sys->i_bitspersample/8) * in_buf.i_nb_samples) 
    235             in_buf.i_nb_bytes = (p_filter->p_sys->i_bitspersample/8) * in_buf.i_nb_samples; 
    236         else 
    237             //in_buf*/ 
     226    unsigned int i_in_size = in_buf.i_nb_samples  * (p_filter->p_sys->i_bitspersample/8) * 
     227                             aout_FormatNbChannels( &(p_filter->fmt_in.audio) ); 
     228    if( (in_buf.i_nb_bytes != i_in_size) && ((i_in_size % 32) != 0) ) /* is it word aligned?? */ 
     229    { 
     230        msg_Err( p_filter, "input buffer is not word aligned" ); 
     231        /* Fix output buffer to be word aligned */ 
    238232    } 
    239233#endif 
     
    243237    out_buf.i_nb_samples = p_out->i_samples; 
    244238 
    245     stereo_mono_downmix( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf ); 
     239    i_samples = stereo_to_mono( (aout_instance_t *)p_filter, &aout_filter, 
     240                                &out_buf, &in_buf ); 
    246241 
    247242    p_out->i_buffer = out_buf.i_nb_bytes; 
     
    252247} 
    253248 
    254 static void stereo_mono_downmix( aout_instance_t * p_aout, aout_filter_t * p_filter, 
    255                                  aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) 
     249/* stereo_to_mono - mix 2 channels (left,right) into one and play silence on 
     250 * all other channels. 
     251 */ 
     252static unsigned int stereo_to_mono( aout_instance_t * p_aout, aout_filter_t *p_filter, 
     253                                    aout_buffer_t *p_output, aout_buffer_t *p_input ) 
    256254{ 
    257255    filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys; 
    258  
    259     if( p_sys->b_block_channel ) 
    260     { 
    261         silence_channel( p_aout, p_filter, p_out_buf, p_in_buf ); 
    262     } 
    263     else 
    264     { 
    265         unsigned int i_samples; 
    266  
    267         i_samples = stereo_to_mono( (int16_t *)p_out_buf->p_buffer, (int16_t *)p_in_buf->p_buffer, 
    268                                     p_out_buf->i_nb_samples ); 
    269     } 
    270  
    271     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; 
    272 } 
    273  
    274 /* silence_channel - play silence on all channels except the selected one. 
    275  */ 
    276 static void silence_channel( aout_instance_t * p_aout, aout_filter_t * p_filter, 
    277                              aout_buffer_t *p_out_buf, aout_buffer_t *p_in_buf ) 
    278 { 
    279     filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys; 
    280     unsigned int n = 0; 
    281256    int16_t *p_in, *p_out; 
    282  
    283     p_in = (int16_t *)p_in_buf->p_buffer; 
    284     p_out = (int16_t *)p_out_buf->p_buffer; 
    285  
    286     for( n = 0; n < p_in_buf->i_nb_samples * p_sys->i_nb_channels; n++ ) 
     257    unsigned int n; 
     258 
     259    p_in = (int16_t *) p_input->p_buffer; 
     260    p_out = (int16_t *) p_output->p_buffer; 
     261 
     262    for( n = 0; n < (p_input->i_nb_samples * p_sys->i_nb_channels); n++ ) 
    287263    { 
    288264        if( (n%p_sys->i_nb_channels) == p_sys->i_channel_selected ) 
    289265        { 
    290             p_out[n] = p_in[n]
     266            p_out[n] = (p_in[n] + p_in[n+1]) >> 1
    291267        } 
    292268        else 
     
    295271        } 
    296272    } 
    297 } 
    298  
    299 /* stereo_to_mono() function is from ffmpeg file libavcodec/resample.c  
    300  * Copyright (c) 2000 Fabrice Bellard. 
    301  */ 
    302 static unsigned int stereo_to_mono( int16_t *p_output, int16_t *p_input, 
    303                                     unsigned int i_samples ) 
    304 { 
    305     int16_t *p, *q; 
    306     unsigned int n = i_samples; 
    307  
    308     p = p_input; 
    309     q = p_output; 
    310  
    311     while (n >= 4) { 
    312         q[0] = (p[0] + p[1]) >> 1; 
    313         q[1] = (p[2] + p[3]) >> 1; 
    314         q[2] = (p[4] + p[5]) >> 1; 
    315         q[3] = (p[6] + p[7]) >> 1; 
    316         q += 4; 
    317         p += 8; 
    318         n -= 4; 
    319     } 
    320     while (n > 0) { 
    321         q[0] = (p[0] + p[1]) >> 1; 
    322         q++; 
    323         p += 2; 
    324         n--; 
    325     } 
    326273    return n; 
    327274}