Hi,<br><br><div class="gmail_quote">On Thu, Jul 1, 2010 at 1:10 PM, Laurent Aimar <span dir="ltr"><<a href="mailto:fenrir@elivagar.org">fenrir@elivagar.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Hi,<br>
<div class="im"><br>
On Thu, Jul 01, 2010 at 03:33:00AM -0500, Ronald Wright wrote:<br>
> +vlc_module_begin()<br>
> +    set_shortname( _("Compressor") )<br>
> +    set_description( _("Dynamic range compressor") )<br>
> +    set_capability( "audio filter", 1 )<br>
</div> It must be 0 as explained in reply to another of your patches.<br></blockquote><div><br>See below for the explanation of the issue.<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im">> +    add_float( "compressor-lo-pregain", 0.0, NULL, LO_TEXT,<br>
> +               LO_LONGTEXT, false )<br>
> +    add_float( "compressor-mid-pregain", 0.0, NULL, MID_TEXT,<br>
> +               MID_LONGTEXT, false )<br>
> +    add_float( "compressor-hi-pregain", 0.0, NULL, HI_TEXT,<br>
> +               HI_LONGTEXT, false )<br>
<br>
</div> I don't see why you have to do the equalizer part inside your module.<br>
I think that normalizing the audio and applying equalization are two<br>
completly independant tasks, and as such should be done by two<br>
independant plugin. Furthermore, we already have 2 equalizers in VLC.<br></blockquote><div><br>But then, how can you 
tell if the equalizer will go before or after the compressor on 
instantiation?  Priority is important when it comes to dynamic range 
compressors, as there is a significant difference between equalization 
before compression and compression before equalization.  Read the blue 
box at <a href="http://www.soundonsound.com/sos/jan01/articles/advanced.asp">http://www.soundonsound.com/sos/jan01/articles/advanced.asp</a>.<br><br>It's
 almost like asking yourself, given two distinct functions f(x) and 
g(x), is f(g(x)) really equal to g(f(x))?  The answer is obvious:  not 
always, since the composition of functions is not commutative.  This 
means that the audio controls in a certain order will exhibit behavior 
that changes when the order is swapped.<br><br>
Here is an example.  Assume the older patches are used to compile VLC.  Also assume that the parametric equalizer, main equalizer, 
and compressor are enabled.  Because the equalizers and compressor have score 0, there are six different ways for the audio to 
be processed, and four of these ways will have a major impact as to how 
the audio is output.  If 
the ordering is not explicit, then the compressor is not suitable for 
use with either equalizer.<br><br>Considering the information that I 
have just mentioned, if you can help me find a better way to implement 
the equalization part (without changing the scores in the other 
modules), let me know.  My most reasonable guess is that my module 
belongs in a category other than audio filters.  (Is it possible that I 
need to add a new module category known as "audio_processors"?)<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div><div class="h5">

> +static int Open( vlc_object_t *p_this )<br>
> +{<br>
> +    filter_t *p_filter = (filter_t*)p_this;<br>
> +    vlc_object_t *p_aout = p_filter->p_parent;<br>
> +    float f_sample_rate = p_filter->fmt_in.audio.i_rate;<br>
> +    struct filter_sys_t *p_sys;<br>
> +    float f_num;<br>
> +<br>
> +    if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 ||<br>
> +        p_filter->fmt_out.audio.i_format != VLC_CODEC_FL32 )<br>
> +    {<br>
> +        p_filter->fmt_in.audio.i_format = VLC_CODEC_FL32;<br>
> +        p_filter->fmt_out.audio.i_format = VLC_CODEC_FL32;<br>
> +        msg_Warn( p_filter, "bad input or output format" );<br>
> +        return VLC_EGENERIC;<br>
> +    }<br>
> +    if( !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio,<br>
> +                            &p_filter->fmt_out.audio ) )<br>
> +    {<br>
> +        p_filter->fmt_out.audio = p_filter->fmt_in.audio;<br>
> +        msg_Warn( p_filter, "input and output formats are not similar" );<br>
> +        return VLC_EGENERIC;<br>
> +    }<br>
> +<br>
> +    /* Initialize the filter parameter structure */<br>
> +    p_sys = p_filter->p_sys = calloc( 1, sizeof(*p_sys) );<br>
> +    if( !p_sys )<br>
> +    {<br>
> +        return VLC_ENOMEM;<br>
> +    }<br>
> +<br>
> +    /* Initialize the attack lookup table */<br>
> +    p_sys->pf_as[0] = 1.0f;<br>
> +    for( int i = 1; i < A_TBL; i++ )<br>
> +    {<br>
> +        p_sys->pf_as[i] = expf( -1.0f / ( f_sample_rate * i / A_TBL ) );<br>
> +    }<br>
> +<br>
> +    /* Calculate the RMS and lookahead sizes from the sample rate */<br>
> +    f_num = 0.01f * f_sample_rate;<br>
> +    p_sys->rms.i_count = Round( Clamp( 0.5f * f_num, 1.0f, RMS_BUF_SIZE ) );<br>
> +    p_sys->la.i_count = Round( Clamp( f_num, 1.0f, LOOKAHEAD_SIZE ) );<br>
> +<br>
> +    /* Initialize decibel lookup tables */<br>
> +    DbInit( p_sys );<br>
> +<br>
> +    /* Restore the last saved settings */<br>
> +    p_sys->f_lo_pregain  =<br>
> +           var_CreateGetFloat( p_aout, "compressor-lo-pregain" );<br>
> +    p_sys->f_mid_pregain =<br>
> +           var_CreateGetFloat( p_aout, "compressor-mid-pregain" );<br>
> +    p_sys->f_hi_pregain  =<br>
> +           var_CreateGetFloat( p_aout, "compressor-hi-pregain" );<br>
> +    p_sys->f_rms_peak    = var_CreateGetFloat( p_aout, "compressor-rms-peak" );<br>
> +    p_sys->f_attack      = var_CreateGetFloat( p_aout, "compressor-attack" );<br>
> +    p_sys->f_release     = var_CreateGetFloat( p_aout, "compressor-release" );<br>
> +    p_sys->f_threshold   = var_CreateGetFloat( p_aout, "compressor-threshold" );<br>
> +    p_sys->f_ratio       = var_CreateGetFloat( p_aout, "compressor-ratio" );<br>
> +    p_sys->f_knee        = var_CreateGetFloat( p_aout, "compressor-knee" );<br>
> +    p_sys->f_makeup_gain =<br>
> +           var_CreateGetFloat( p_aout, "compressor-makeup-gain" );<br>
> +<br>
> +    /* Initialize the mutex */<br>
> +    vlc_mutex_init( &p_sys->lock );<br>
> +<br>
> +    /* Add our own callbacks */<br>
> +    var_AddCallback( p_aout, "compressor-lo-pregain", LoPregainCallback,<br>
> +                     p_sys );<br>
> +    var_AddCallback( p_aout, "compressor-mid-pregain", MidPregainCallback,<br>
> +                     p_sys );<br>
> +    var_AddCallback( p_aout, "compressor-hi-pregain", HiPregainCallback,<br>
> +                     p_sys );<br>
> +    var_AddCallback( p_aout, "compressor-rms-peak", RMSPeakCallback, p_sys );<br>
> +    var_AddCallback( p_aout, "compressor-attack", AttackCallback, p_sys );<br>
> +    var_AddCallback( p_aout, "compressor-release", ReleaseCallback, p_sys );<br>
> +    var_AddCallback( p_aout, "compressor-threshold", ThresholdCallback, p_sys );<br>
> +    var_AddCallback( p_aout, "compressor-ratio", RatioCallback, p_sys );<br>
> +    var_AddCallback( p_aout, "compressor-knee", KneeCallback, p_sys );<br>
> +    var_AddCallback( p_aout, "compressor-makeup-gain", MakeupGainCallback,<br>
> +                     p_sys );<br>
> +<br>
> +    /* Set the filter function */<br>
> +    p_filter->pf_audio_filter = DoWork;<br>
> +<br>
> +    /* At this stage, we are ready! */<br>
> +    msg_Dbg( p_filter, "compressor successfully initialized" );<br>
> +    return VLC_SUCCESS;<br>
> +}<br>
> +<br>
> +/*****************************************************************************<br>
> + * Close: destroy interface<br>
> + *****************************************************************************/<br>
> +<br>
> +static void Close( vlc_object_t *p_this )<br>
> +{<br>
> +    filter_t *p_filter = (filter_t*)p_this;<br>
> +    vlc_object_t *p_aout = p_filter->p_parent;<br>
> +    struct filter_sys_t *p_sys = p_filter->p_sys;<br>
> +<br>
> +    /* Remove our callbacks */<br>
> +    var_DelCallback( p_aout, "compressor-rms-peak", RMSPeakCallback, p_sys );<br>
> +    var_DelCallback( p_aout, "compressor-attack", AttackCallback, p_sys );<br>
> +    var_DelCallback( p_aout, "compressor-release", ReleaseCallback, p_sys );<br>
> +    var_DelCallback( p_aout, "compressor-threshold", ThresholdCallback, p_sys );<br>
> +    var_DelCallback( p_aout, "compressor-ratio", RatioCallback, p_sys );<br>
> +    var_DelCallback( p_aout, "compressor-knee", KneeCallback, p_sys );<br>
> +    var_DelCallback( p_aout, "compressor-makeup-gain", MakeupGainCallback,<br>
> +                     p_sys );<br>
</div></div> I think you forgot some deletes.<br>
Maybe creating a table with the variables names and the associated callbacks<br>
would  simplify it ? Otherwise, adding the missing one is enough.<br></blockquote><div><br><div>Oops, I forgot to add 
those in.  I have been too busy fixing other things in the code, and 
when I make many changes, it is hard to keep track of the remaining 
changes that I still have to take care of.<br></div> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div><div class="h5">
Regards,<br>
<br>
--<br>
fenrir<br>
<br>
_______________________________________________<br>
vlc-devel mailing list<br>
To unsubscribe or modify your subscription options:<br>
<a href="http://mailman.videolan.org/listinfo/vlc-devel" target="_blank">http://mailman.videolan.org/listinfo/vlc-devel</a><br>
</div></div></blockquote></div><br>Regards,<br><br>Ronald Wright<br>