From: Christophe Massiot Date: Wed, 21 Nov 2007 19:04:49 +0000 (+0000) Subject: * simple.c: Extended the filter for mono output, and also converted it to the X-Git-Tag: 0.9.0-test0~4456 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=595b2a8e844f6897fa3306a2f387021ee664e46c;p=vlc * simple.c: Extended the filter for mono output, and also converted it to the audio_filter2 architecture. --- diff --git a/modules/audio_filter/channel_mixer/simple.c b/modules/audio_filter/channel_mixer/simple.c index 7c9c448782..8c36e36a3b 100644 --- a/modules/audio_filter/channel_mixer/simple.c +++ b/modules/audio_filter/channel_mixer/simple.c @@ -24,9 +24,10 @@ /***************************************************************************** * Preamble *****************************************************************************/ - #include #include +#include +#include /***************************************************************************** * Local prototypes @@ -36,6 +37,9 @@ static int Create ( vlc_object_t * ); static void DoWork ( aout_instance_t *, aout_filter_t *, aout_buffer_t *, aout_buffer_t * ); +static int OpenFilter ( vlc_object_t * ); +static block_t *Filter( filter_t *, block_t * ); + /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -45,6 +49,11 @@ vlc_module_begin(); set_category( CAT_AUDIO ); set_subcategory( SUBCAT_AUDIO_MISC ); set_callbacks( Create, NULL ); + + add_submodule(); + set_description( _("audio filter for simple channel mixing") ); + set_capability( "audio filter2", 10 ); + set_callbacks( OpenFilter, NULL ); vlc_module_end(); /***************************************************************************** @@ -65,24 +74,27 @@ static int Create( vlc_object_t *p_this ) return -1; } - /* Only conversion to Stereo and 4.0 right now */ + /* Only conversion to Mono, Stereo and 4.0 right now */ if( p_filter->output.i_physical_channels != (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) && p_filter->output.i_physical_channels != ( AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | - AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) ) - { - return -1; - } + AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) + && p_filter->output.i_physical_channels != AOUT_CHAN_CENTER ) + { + return -1; + } - /* Only from 7/7.1/5/5.1 */ + /* Only from 7/7.1/5/5.1/2.0 */ if( (p_filter->input.i_physical_channels & ~AOUT_CHAN_LFE) != (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) && (p_filter->input.i_physical_channels & ~AOUT_CHAN_LFE) != (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT | - AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) ) + AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) && + p_filter->input.i_physical_channels != + (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) ) { return -1; } @@ -136,6 +148,37 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++; } } + else if( p_filter->output.i_physical_channels == AOUT_CHAN_CENTER ) + { + if( p_filter->input.i_physical_channels & AOUT_CHAN_MIDDLELEFT ) + for( i = p_in_buf->i_nb_samples; i--; ) + { + *p_dest = p_src[6] + p_src[0] / 4 + p_src[1] / 4 + p_src[2] / 8 + p_src[3] / 8 + p_src[4] / 8 + p_src[5] / 8; + p_dest++; + + p_src += 7; + + if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++; + } + else if( p_filter->input.i_physical_channels & AOUT_CHAN_REARLEFT ) + for( i = p_in_buf->i_nb_samples; i--; ) + { + *p_dest = p_src[4] + p_src[0] / 4 + p_src[1] / 4 + p_src[2] / 6 + p_src[3] / 6; + p_dest++; + + p_src += 5; + + if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++; + } + else + for( i = p_in_buf->i_nb_samples; i--; ) + { + *p_dest = p_src[0] / 2 + p_src[1] / 2; + p_dest++; + + p_src += 2; + } + } else { if( p_filter->input.i_physical_channels & AOUT_CHAN_MIDDLELEFT ) @@ -173,3 +216,108 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, } } + +/***************************************************************************** + * OpenFilter: + *****************************************************************************/ +static int OpenFilter( vlc_object_t *p_this ) +{ + filter_t *p_filter = (filter_t *)p_this; + + if ( (p_filter->fmt_in.audio.i_physical_channels + == p_filter->fmt_out.audio.i_physical_channels + && p_filter->fmt_in.audio.i_original_channels + == p_filter->fmt_out.audio.i_original_channels) + || p_filter->fmt_in.i_codec != p_filter->fmt_out.i_codec + || p_filter->fmt_in.audio.i_rate != p_filter->fmt_out.audio.i_rate + || p_filter->fmt_in.i_codec != VLC_FOURCC('f','l','3','2') ) + { + return -1; + } + + /* Only conversion to Mono, Stereo and 4.0 right now */ + if( p_filter->fmt_out.audio.i_physical_channels != + (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) + && p_filter->fmt_out.audio.i_physical_channels != + ( AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) + && p_filter->fmt_out.audio.i_physical_channels != AOUT_CHAN_CENTER ) + { + return -1; + } + + /* Only from 7/7.1/5/5.1/2.0 */ + if( (p_filter->fmt_in.audio.i_physical_channels & ~AOUT_CHAN_LFE) != + (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | + AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) && + (p_filter->fmt_in.audio.i_physical_channels & ~AOUT_CHAN_LFE) != + (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | + AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT | + AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) && + p_filter->fmt_in.audio.i_physical_channels != + (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) ) + { + return -1; + } + + p_filter->pf_audio_filter = Filter; + + return 0; +} + +/***************************************************************************** + * Filter: + *****************************************************************************/ +static block_t *Filter( filter_t *p_filter, block_t *p_block ) +{ + aout_filter_t aout_filter; + aout_buffer_t in_buf, out_buf; + block_t *p_out; + int i_out_size; + + if( !p_block || !p_block->i_samples ) + { + if( p_block ) p_block->pf_release( p_block ); + return NULL; + } + + i_out_size = p_block->i_samples * + p_filter->fmt_out.audio.i_bitspersample * + p_filter->fmt_out.audio.i_channels / 8; + + p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size ); + if( !p_out ) + { + msg_Warn( p_filter, "can't get output buffer" ); + p_block->pf_release( p_block ); + return NULL; + } + + p_out->i_samples = p_block->i_samples; + p_out->i_dts = p_block->i_dts; + p_out->i_pts = p_block->i_pts; + p_out->i_length = p_block->i_length; + + aout_filter.p_sys = (struct aout_filter_sys_t *)p_filter->p_sys; + aout_filter.input = p_filter->fmt_in.audio; + aout_filter.input.i_format = p_filter->fmt_in.i_codec; + aout_filter.output = p_filter->fmt_out.audio; + aout_filter.output.i_format = p_filter->fmt_out.i_codec; + + in_buf.p_buffer = p_block->p_buffer; + in_buf.i_nb_bytes = p_block->i_buffer; + in_buf.i_nb_samples = p_block->i_samples; + out_buf.p_buffer = p_out->p_buffer; + out_buf.i_nb_bytes = p_out->i_buffer; + out_buf.i_nb_samples = p_out->i_samples; + + DoWork( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf ); + + p_block->pf_release( p_block ); + + p_out->i_buffer = out_buf.i_nb_bytes; + p_out->i_samples = out_buf.i_nb_samples; + + return p_out; +} +