⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mono.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
}/***************************************************************************** * OpenFilter *****************************************************************************/static int OpenFilter( vlc_object_t *p_this ){    filter_t * p_filter = (filter_t *)p_this;    filter_sys_t *p_sys = NULL;    if( aout_FormatNbChannels( &(p_filter->fmt_in.audio) ) == 1 )    {        /*msg_Dbg( p_filter, "filter discarded (incompatible format)" );*/        return VLC_EGENERIC;    }    if( (p_filter->fmt_in.i_codec != AOUT_FMT_S16_NE) ||        (p_filter->fmt_out.i_codec != AOUT_FMT_S16_NE) )    {        /*msg_Err( p_this, "filter discarded (invalid format)" );*/        return VLC_EGENERIC;    }    if( (p_filter->fmt_in.audio.i_format != p_filter->fmt_out.audio.i_format) &&        (p_filter->fmt_in.audio.i_rate != p_filter->fmt_out.audio.i_rate) &&        (p_filter->fmt_in.audio.i_format != AOUT_FMT_S16_NE) &&        (p_filter->fmt_out.audio.i_format != AOUT_FMT_S16_NE) &&        (p_filter->fmt_in.audio.i_bitspersample !=                                    p_filter->fmt_out.audio.i_bitspersample))    {        /*msg_Err( p_this, "couldn't load mono filter" );*/        return VLC_EGENERIC;    }    /* Allocate the memory needed to store the module's structure */    p_sys = p_filter->p_sys = malloc( sizeof(filter_sys_t) );    if( p_sys == NULL )        return VLC_EGENERIC;    var_Create( p_this, MONO_CFG "downmix",                VLC_VAR_BOOL | VLC_VAR_DOINHERIT );    p_sys->b_downmix = var_GetBool( p_this, MONO_CFG "downmix" );    var_Create( p_this, MONO_CFG "channel",                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    p_sys->i_channel_selected =            (unsigned int) var_GetInteger( p_this, MONO_CFG "channel" );    if( p_sys->b_downmix )    {        msg_Dbg( p_this, "using stereo to mono downmix" );        p_filter->fmt_out.audio.i_physical_channels = AOUT_CHAN_CENTER;        p_filter->fmt_out.audio.i_channels = 1;    }    else    {        msg_Dbg( p_this, "using pseudo mono" );        p_filter->fmt_out.audio.i_physical_channels =                            (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT);        p_filter->fmt_out.audio.i_channels = 2;    }    p_filter->fmt_out.audio.i_rate = p_filter->fmt_in.audio.i_rate;    p_filter->fmt_out.audio.i_format = p_filter->fmt_out.i_codec;    p_sys->i_nb_channels = aout_FormatNbChannels( &(p_filter->fmt_in.audio) );    p_sys->i_bitspersample = p_filter->fmt_out.audio.i_bitspersample;    p_sys->i_overflow_buffer_size = 0;    p_sys->p_overflow_buffer = NULL;    p_sys->i_nb_atomic_operations = 0;    p_sys->p_atomic_operations = NULL;    if( Init( VLC_OBJECT(p_filter), p_filter->p_sys,              aout_FormatNbChannels( &p_filter->fmt_in.audio ),              p_filter->fmt_in.audio.i_physical_channels,              p_filter->fmt_in.audio.i_rate ) < 0 )    {        var_Destroy( p_this, MONO_CFG "channel" );        var_Destroy( p_this, MONO_CFG "downmix" );        free( p_sys );        return VLC_EGENERIC;    }    p_filter->pf_audio_filter = Convert;    msg_Dbg( p_this, "%4.4s->%4.4s, channels %d->%d, bits per sample: %i->%i",             (char *)&p_filter->fmt_in.i_codec,             (char *)&p_filter->fmt_out.i_codec,             p_filter->fmt_in.audio.i_physical_channels,             p_filter->fmt_out.audio.i_physical_channels,             p_filter->fmt_in.audio.i_bitspersample,             p_filter->fmt_out.audio.i_bitspersample );    return VLC_SUCCESS;}/***************************************************************************** * CloseFilter *****************************************************************************/static void CloseFilter( vlc_object_t *p_this){    filter_t *p_filter = (filter_t *) p_this;    filter_sys_t *p_sys = p_filter->p_sys;    var_Destroy( p_this, MONO_CFG "channel" );    var_Destroy( p_this, MONO_CFG "downmix" );    free( p_sys->p_atomic_operations );    free( p_sys->p_overflow_buffer );    free( p_sys );}/***************************************************************************** * Convert *****************************************************************************/static block_t *Convert( filter_t *p_filter, block_t *p_block ){    aout_filter_t aout_filter;    aout_buffer_t in_buf, out_buf;    block_t *p_out = NULL;    unsigned int i_samples;    int i_out_size;    if( !p_block || !p_block->i_samples )    {        if( p_block )            block_Release( p_block );        return NULL;    }    i_out_size = p_block->i_samples * p_filter->p_sys->i_bitspersample/8 *                 aout_FormatNbChannels( &(p_filter->fmt_out.audio) );    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" );        block_Release( p_block );        return NULL;    }    p_out->i_samples = (p_block->i_samples / p_filter->p_sys->i_nb_channels) *                       aout_FormatNbChannels( &(p_filter->fmt_out.audio) );    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;#if 0    unsigned int i_in_size = in_buf.i_nb_samples  * (p_filter->p_sys->i_bitspersample/8) *                             aout_FormatNbChannels( &(p_filter->fmt_in.audio) );    if( (in_buf.i_nb_bytes != i_in_size) && ((i_in_size % 32) != 0) ) /* is it word aligned?? */    {        msg_Err( p_filter, "input buffer is not word aligned" );        /* Fix output buffer to be word aligned */    }#endif    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;    memset( p_out->p_buffer, 0, i_out_size );    if( p_filter->p_sys->b_downmix )    {        stereo2mono_downmix( &aout_filter, &in_buf, &out_buf );        i_samples = mono( &aout_filter, &out_buf, &in_buf );    }    else    {        i_samples = stereo_to_mono( &aout_filter, &out_buf, &in_buf );    }    p_out->i_buffer = out_buf.i_nb_bytes;    p_out->i_samples = out_buf.i_nb_samples;    block_Release( p_block );    return p_out;}/* stereo2mono_downmix - stereo channels into one mono channel. * Code taken from modules/audio_filter/channel_mixer/headphone.c * converted from float into int16_t based downmix * Written by Boris Dorès <babal@via.ecp.fr> */static void stereo2mono_downmix( aout_filter_t * p_filter,                            aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ){    filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;    int i_input_nb = aout_FormatNbChannels( &p_filter->input );    int i_output_nb = aout_FormatNbChannels( &p_filter->output );    int16_t * p_in = (int16_t*) p_in_buf->p_buffer;    uint8_t * p_out;    uint8_t * p_overflow;    uint8_t * p_slide;    size_t i_overflow_size;     /* in bytes */    size_t i_out_size;          /* in bytes */    unsigned int i, j;    int i_source_channel_offset;    int i_dest_channel_offset;    unsigned int i_delay;    double d_amplitude_factor;    /* out buffer characterisitcs */    p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;    p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * i_output_nb / i_input_nb;    p_out = p_out_buf->p_buffer;    i_out_size = p_out_buf->i_nb_bytes;    if( p_sys != NULL )    {        /* Slide the overflow buffer */        p_overflow = p_sys->p_overflow_buffer;        i_overflow_size = p_sys->i_overflow_buffer_size;        if ( i_out_size > i_overflow_size )            memcpy( p_out, p_overflow, i_overflow_size );        else            memcpy( p_out, p_overflow, i_out_size );        p_slide = p_sys->p_overflow_buffer;        while( p_slide < p_overflow + i_overflow_size )        {            if( p_slide + i_out_size < p_overflow + i_overflow_size )            {                memset( p_slide, 0, i_out_size );                if( p_slide + 2 * i_out_size < p_overflow + i_overflow_size )                    memcpy( p_slide, p_slide + i_out_size, i_out_size );                else                    memcpy( p_slide, p_slide + i_out_size,                            p_overflow + i_overflow_size - ( p_slide + i_out_size ) );            }            else            {                memset( p_slide, 0, p_overflow + i_overflow_size - p_slide );            }            p_slide += i_out_size;        }        /* apply the atomic operations */        for( i = 0; i < p_sys->i_nb_atomic_operations; i++ )        {            /* shorter variable names */            i_source_channel_offset                = p_sys->p_atomic_operations[i].i_source_channel_offset;            i_dest_channel_offset                = p_sys->p_atomic_operations[i].i_dest_channel_offset;            i_delay = p_sys->p_atomic_operations[i].i_delay;            d_amplitude_factor                = p_sys->p_atomic_operations[i].d_amplitude_factor;            if( p_out_buf->i_nb_samples > i_delay )            {                /* current buffer coefficients */                for( j = 0; j < p_out_buf->i_nb_samples - i_delay; j++ )                {                    ((int16_t*)p_out)[ (i_delay+j)*i_output_nb + i_dest_channel_offset ]                        += p_in[ j * i_input_nb + i_source_channel_offset ]                           * d_amplitude_factor;                }                /* overflow buffer coefficients */                for( j = 0; j < i_delay; j++ )                {                    ((int16_t*)p_overflow)[ j*i_output_nb + i_dest_channel_offset ]                        += p_in[ (p_out_buf->i_nb_samples - i_delay + j)                           * i_input_nb + i_source_channel_offset ]                           * d_amplitude_factor;                }            }            else            {                /* overflow buffer coefficients only */                for( j = 0; j < p_out_buf->i_nb_samples; j++ )                {                    ((int16_t*)p_overflow)[ (i_delay - p_out_buf->i_nb_samples + j)                        * i_output_nb + i_dest_channel_offset ]                        += p_in[ j * i_input_nb + i_source_channel_offset ]                           * d_amplitude_factor;                }            }        }    }    else    {        memset( p_out, 0, i_out_size );    }}/* Simple stereo to mono mixing. */static unsigned int mono( aout_filter_t *p_filter,                          aout_buffer_t *p_output, aout_buffer_t *p_input ){    filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;    int16_t *p_in, *p_out;    unsigned int n = 0, r = 0;    p_in = (int16_t *) p_input->p_buffer;    p_out = (int16_t *) p_output->p_buffer;    while( n < (p_input->i_nb_samples * p_sys->i_nb_channels) )    {        p_out[r] = (p_in[n] + p_in[n+1]) >> 1;        r++;        n += 2;    }    return r;}/* Simple stereo to mono mixing. */static unsigned int stereo_to_mono( aout_filter_t *p_filter,                                    aout_buffer_t *p_output, aout_buffer_t *p_input ){    filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;    int16_t *p_in, *p_out;    unsigned int n;    p_in = (int16_t *) p_input->p_buffer;    p_out = (int16_t *) p_output->p_buffer;    for( n = 0; n < (p_input->i_nb_samples * p_sys->i_nb_channels); n++ )    {        /* Fake real mono. */        if( p_sys->i_channel_selected == -1)        {            p_out[n] = p_out[n+1] = (p_in[n] + p_in[n+1]) >> 1;            n++;        }        else if( (n % p_sys->i_nb_channels) == (unsigned int) p_sys->i_channel_selected )        {            p_out[n] = p_out[n+1] = p_in[n];        }    }    return n;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -