[vlc-devel] stereo enhancer audio effect

Rémi Denis-Courmont remi at remlab.net
Fri Mar 9 09:23:54 CET 2012


On Thu, 8 Mar 2012 20:31:02 -0800, Sukrit Sangwan
<sukritsangwan at gmail.com>
wrote:
> I have written a simple stereo enhancer. I have used the following way.
>      left_output = A * left_input - B * right_input + C * delayed
> right_input
> i have set A = 0.8, B = 0.3, C = 0.3  ..  subtracted right_input to
> suppress mono a bit and enhanced stereo by a little delaying effect(20
ms)
> It has a little widening effect. I have attached the file.
> Please tell me how can i improve it.

Inline...


/*****************************************************************************
 * stereo_widen.c : simple stereo widening effect

*****************************************************************************
 * 

-> Missing copyright.

 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.

*****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <assert.h>

-> No need to include that.

#include <vlc_common.h>
#include <vlc_aout.h>
#include <vlc_filter.h>
#include <vlc_plugin.h>

#define DELAY       20
#define DRY_MIX     0.8
#define WET_MIX     0.3
#define FEEDBACK    0.3

/*****************************************************************************
 * Local prototypes

*****************************************************************************/
static int  Open ( vlc_object_t * );
static void Close( vlc_object_t * );
 
static block_t *Filter ( filter_t *, block_t * );

struct filter_sys_t
{
    float *pf_begin;    /* circular buffer to store samples */
    float *pf_write;    /* where to write current sample    */
    int   i_len;        /* delay in number of samples       */
};

/*****************************************************************************
 * Module descriptor

*****************************************************************************/
vlc_module_begin ()
    set_shortname (N_("stereo_widen"))
    set_description (N_("Simple Stereo enhancer"))
    set_category (CAT_AUDIO)
    set_subcategory (SUBCAT_AUDIO_AFILTER)
    set_capability ("audio filter", 0)
    set_callbacks (Open, Close)
vlc_module_end ()

/*****************************************************************************
 * Open: Allocate buffer

*****************************************************************************/
static int Open( vlc_object_t *obj )
{
    filter_t *p_filter  = (filter_t *)obj;
    filter_sys_t *p_sys;

    if ( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 ||
     !AOUT_FMTS_IDENTICAL( &p_filter->fmt_in.audio,
&p_filter->fmt_out.audio ))
        return VLC_EGENERIC;

    if ( p_filter->fmt_in.audio.i_channels != 2 )
    {
        msg_Err ( p_filter, "stereo enhance requires stereo" );
        return VLC_EGENERIC;
    }

    p_sys = p_filter->p_sys = malloc( sizeof(filter_sys_t) );
    if( !p_sys )
        return VLC_ENOMEM;

-> Could use the unlikely() macro.

    /* Compute buffer length and allocate space */
    p_sys->i_len = 2 * DELAY * p_filter->fmt_in.audio.i_rate / 1000;
    p_sys->pf_begin = calloc( p_sys->i_len + 2, sizeof(float) );

-> Missing error check.

    p_sys->pf_write = p_sys->pf_begin;
    p_filter->pf_audio_filter = Filter;
    return VLC_SUCCESS;
}


/*****************************************************************************
 * Filter: process each sample

*****************************************************************************/
static block_t *Filter( filter_t *p_filter, block_t *p_block )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    float *p_out = (float *)p_block->p_buffer;
    float *pf_read;
    
    for (unsigned i = p_block->i_nb_samples; i > 0; i--)
    {
        pf_read = p_sys->pf_write + 2;
        /* if at end of buffer put read ptr at begin */
        if( pf_read > p_sys->pf_begin + p_sys->i_len )
            pf_read = p_sys->pf_begin;

        float left  = p_out[0];
        float right = p_out[1];

        *(p_out++) = DRY_MIX * left  - WET_MIX * right - FEEDBACK *
pf_read[1];
        *(p_out++) = DRY_MIX * right - WET_MIX * left  - FEEDBACK *
pf_read[0];
        p_sys->pf_write[0] = left ;
        p_sys->pf_write[1] = right;

        /* if at end of buffer place pf_write at begin */
        if( p_sys->pf_write  == p_sys->pf_begin + p_sys->i_len )
            p_sys->pf_write  =  p_sys->pf_begin;
        else
            p_sys->pf_write += 2;
    }

    (void) p_filter;

-> Not needed. You do use p_filter in this function.

    return p_block;
}

/*****************************************************************************
 * Close: close the plugin

*****************************************************************************/
static void Close( vlc_object_t *obj )
{
    filter_t *p_filter  = (filter_t *)obj;
    filter_sys_t *p_sys = p_filter->p_sys;
    free( p_sys->pf_begin );
    free( p_sys );
}


Also you should format this as a patch (git format-patch) and include the
Modules.am modifications.

-- 
Rémi Denis-Courmont
Sent from my collocated server




More information about the vlc-devel mailing list