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>