X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_filter%2Fconverter%2Ffixed.c;h=e0144b67701eaff45aa818e6a0accc640b13c94e;hb=5bc203097536eb21a9ed026ee11c3211df1ed1cd;hp=c4634b6051ebdb5af21f73d6476039fbe03220c4;hpb=724461bdf250e856eb32f6c0b7c51b065e482982;p=vlc diff --git a/modules/audio_filter/converter/fixed.c b/modules/audio_filter/converter/fixed.c index c4634b6051..e0144b6770 100644 --- a/modules/audio_filter/converter/fixed.c +++ b/modules/audio_filter/converter/fixed.c @@ -1,7 +1,7 @@ /***************************************************************************** * fixed.c: Fixed-point audio format conversions ***************************************************************************** - * Copyright (C) 2002, 2006 the VideoLAN team + * Copyright (C) 2002, 2006-2009 the VideoLAN team * $Id$ * * Authors: Jean-Paul Saman @@ -34,61 +34,58 @@ #include #include #include +#include -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static int Create_F32ToS16 ( vlc_object_t * ); -static void Do_F32ToS16( aout_instance_t *, aout_filter_t *, aout_buffer_t *, - aout_buffer_t * ); - -static int Create_S16ToF32 ( vlc_object_t * ); -static void Do_S16ToF32( aout_instance_t *, aout_filter_t *, aout_buffer_t *, - aout_buffer_t * ); - -static int Create_U8ToF32 ( vlc_object_t * ); -static void Do_U8ToF32( aout_instance_t *, aout_filter_t *, aout_buffer_t *, - aout_buffer_t * ); +static int CreateTo( vlc_object_t * ); +static int CreateFrom( vlc_object_t * ); /***************************************************************************** * Module descriptor *****************************************************************************/ vlc_module_begin () set_description( N_("Fixed point audio format conversions") ) + set_callbacks( CreateTo, NULL ) + set_capability( "audio filter", 15 ) add_submodule () - set_callbacks( Create_F32ToS16, NULL ) + set_callbacks( CreateFrom, NULL ) set_capability( "audio filter", 10 ) - add_submodule () - set_callbacks( Create_S16ToF32, NULL ) - set_capability( "audio filter", 15 ) - add_submodule () - set_callbacks( Create_U8ToF32, NULL ) - set_capability( "audio filter", 1 ) vlc_module_end () -/***************************************************************************** - * F32 to S16 - *****************************************************************************/ -static int Create_F32ToS16( vlc_object_t *p_this ) +/*** Conversion from FI32 to audio output ***/ +static block_t *Do_F32ToS16( filter_t *, block_t * ); + +static int CreateFrom( vlc_object_t *p_this ) { - aout_filter_t * p_filter = (aout_filter_t *)p_this; + filter_t * p_filter = (filter_t *)p_this; - if ( p_filter->input.i_format != VLC_CODEC_FI32 - || p_filter->output.i_format != AOUT_FMT_S16_NE ) - { - return -1; - } + if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FI32 + || !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio, + &p_filter->fmt_out.audio ) ) + return VLC_EGENERIC; - if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) ) + /* In fixed-point builds, audio outputs pretty much all use S16N. */ + /* Feel free to add some other format if every needed. */ + switch( p_filter->fmt_out.audio.i_format ) { - return -1; + case VLC_CODEC_S16N: + p_filter->pf_audio_filter = Do_F32ToS16; + break; + default: + return VLC_EGENERIC; } + return VLC_SUCCESS; +} - p_filter->pf_do_work = Do_F32ToS16; - p_filter->b_in_place = 1; +union dw +{ + float f; + int32_t s; + uint32_t u; +}; - return VLC_SUCCESS;; -} +/***************************************************************************** + * F32 to S16 + *****************************************************************************/ /***************************************************************************** * support routines borrowed from mpg321 (file: mad.c), which is distributed @@ -131,111 +128,144 @@ static inline int16_t s24_to_s16_pcm(vlc_fixed_t sample) return (sample >> (VLC_F_FRACBITS + 1 - 16)); } -static void Do_F32ToS16( aout_instance_t * p_aout, aout_filter_t * p_filter, - aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) +static block_t *Do_F32ToS16( filter_t * p_filter, block_t * p_in_buf ) { - VLC_UNUSED(p_aout); int i; vlc_fixed_t * p_in = (vlc_fixed_t *)p_in_buf->p_buffer; - int16_t * p_out = (int16_t *)p_out_buf->p_buffer; + int16_t * p_out = (int16_t *)p_in_buf->p_buffer; for ( i = p_in_buf->i_nb_samples - * aout_FormatNbChannels( &p_filter->input ) ; i-- ; ) + * aout_FormatNbChannels( &p_filter->fmt_in.audio ) ; i-- ; ) { /* Fast Scaling */ *p_out++ = s24_to_s16_pcm(*p_in++); } - p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; - p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes / 2; + p_in_buf->i_buffer /= 2; + return p_in_buf; } +/*** Conversions from decoders to FI32 */ +static block_t *Do_FL32ToF32( filter_t *, block_t * ); +static block_t *Do_S32ToF32( filter_t *, block_t * ); +static block_t *Do_S16ToF32( filter_t *, block_t * ); +static block_t *Do_U8ToF32( filter_t *, block_t * ); -/***************************************************************************** - * S16 to F32 - *****************************************************************************/ -static int Create_S16ToF32( vlc_object_t *p_this ) +static int CreateTo( vlc_object_t *p_this ) { - aout_filter_t * p_filter = (aout_filter_t *)p_this; + filter_t * p_filter = (filter_t *)p_this; - if ( p_filter->output.i_format != VLC_CODEC_FI32 - || p_filter->input.i_format != AOUT_FMT_S16_NE ) - { - return -1; - } + if( p_filter->fmt_out.audio.i_format != VLC_CODEC_FI32 + || !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio, + &p_filter->fmt_out.audio ) ) + return VLC_EGENERIC; - if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) ) + switch( p_filter->fmt_in.audio.i_format ) { - return -1; - } + case VLC_CODEC_FL32: + p_filter->pf_audio_filter = Do_FL32ToF32; + break; + + case VLC_CODEC_S32N: + p_filter->pf_audio_filter = Do_S32ToF32; + break; + + case VLC_CODEC_S16N: + p_filter->pf_audio_filter = Do_S16ToF32; + break; - p_filter->pf_do_work = Do_S16ToF32; - p_filter->b_in_place = 1; + case VLC_CODEC_U8: + p_filter->pf_audio_filter = Do_U8ToF32; + break; - return 0; + default: + return VLC_EGENERIC; + } + + return VLC_SUCCESS; } -static void Do_S16ToF32( aout_instance_t * p_aout, aout_filter_t * p_filter, - aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) +/***************************************************************************** + * S16 to F32 + *****************************************************************************/ +static block_t *Do_S16ToF32( filter_t * p_filter, block_t * p_in_buf ) { - VLC_UNUSED(p_aout); - int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->input ); + block_t *p_out_buf; + p_out_buf = filter_NewAudioBuffer( p_filter, p_in_buf->i_buffer * 2 ); + if( !p_out_buf ) + goto out; - /* We start from the end because b_in_place is true */ - int16_t * p_in = (int16_t *)p_in_buf->p_buffer + i - 1; - vlc_fixed_t * p_out = (vlc_fixed_t *)p_out_buf->p_buffer + i - 1; + int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->fmt_in.audio ); + const int16_t * p_in = (int16_t *)p_in_buf->p_buffer; + vlc_fixed_t * p_out = (vlc_fixed_t *)p_out_buf->p_buffer; while( i-- ) { *p_out = (vlc_fixed_t)( (int32_t)(*p_in) * (FIXED32_ONE >> 16) ); - p_in--; p_out--; + p_in++; p_out++; } + p_out_buf->i_pts = p_in_buf->i_pts; + p_out_buf->i_length = p_in_buf->i_length; p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; - p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes - * sizeof(vlc_fixed_t) / sizeof(int16_t); +out: + block_Release( p_in_buf ); + return p_out_buf; } /***************************************************************************** * U8 to F32 *****************************************************************************/ -static int Create_U8ToF32( vlc_object_t *p_this ) +static block_t *Do_U8ToF32( filter_t * p_filter, block_t * p_in_buf ) { - aout_filter_t * p_filter = (aout_filter_t *)p_this; + block_t *p_out_buf; + p_out_buf = filter_NewAudioBuffer( p_filter, 4 * p_in_buf->i_buffer ); + if( !p_out_buf ) + goto out; - if ( p_filter->input.i_format != VLC_CODEC_U8 - || p_filter->output.i_format != VLC_CODEC_FI32 ) - { - return -1; - } + int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->fmt_in.audio ); + + uint8_t * p_in = (uint8_t *)p_in_buf->p_buffer; + vlc_fixed_t * p_out = (vlc_fixed_t *)p_out_buf->p_buffer; - if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) ) + while( i-- ) { - return -1; + *p_out = (vlc_fixed_t)( (int32_t)(*p_in - 128) * (FIXED32_ONE / 128) ); + p_in++; p_out++; } + p_out_buf->i_pts = p_in_buf->i_pts; + p_out_buf->i_length = p_in_buf->i_length; + p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; +out: + block_Release( p_in_buf ); + return p_out_buf; +} - p_filter->pf_do_work = Do_U8ToF32; - p_filter->b_in_place = true; +static block_t *Do_FL32ToF32( filter_t * p_filter, block_t * p_in_buf ) +{ + unsigned count = p_in_buf->i_nb_samples + * aout_FormatNbChannels( &p_filter->fmt_in.audio ); + union dw *restrict p = (union dw *)p_in_buf->p_buffer, *end = p + count; + const float one = FIXED32_ONE; - return 0; + while (p < end) + { + p->s = (one * p->f); + p++; + } + return p_in_buf; } -static void Do_U8ToF32( aout_instance_t * p_aout, aout_filter_t * p_filter, - aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) +static block_t *Do_S32ToF32( filter_t * p_filter, block_t * p_in_buf ) { - VLC_UNUSED(p_aout); - int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->input ); + unsigned count = p_in_buf->i_nb_samples + * aout_FormatNbChannels( &p_filter->fmt_in.audio ); + int32_t *restrict p = (int32_t *)p_in_buf->p_buffer, *end = p + count; - /* We start from the end because b_in_place is true */ - uint8_t * p_in = (uint8_t *)p_in_buf->p_buffer + i - 1; - vlc_fixed_t * p_out = (vlc_fixed_t *)p_out_buf->p_buffer + i - 1; - - while( i-- ) + while (p < end) { - *p_out = (vlc_fixed_t)( (int32_t)(*p_in - 128) * (FIXED32_ONE / 128) ); - p_in--; p_out--; + *p = *p >> 3; + p++; } - - p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; - p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * sizeof(vlc_fixed_t); + return p_in_buf; }