When the input lufs meter goes to '-infinity', the audio mutes and some GUI
parts disappear.
On July 20, 2021 11:59:57 AM GMT+02:00, "Stéphane Letz" <l...@grame.fr> wrote:
> « crash at silence » ? what does that mean exactly?
>
>Thanks.
>
>Stéphane
>
>> Le 20 juil. 2021 à 11:55, Klaus Scheuermann <kla...@posteo.de> a
>écrit :
>>
>> Good day to all!
>>
>> All my TO-DOs are DONE - woohoo :) Here is the code:
>>
>https://faustide.grame.fr/?code=https://raw.githubusercontent.com/trummerschlunk/master_me/master/master_me_gui.dsp
>>
>> The only thing that still behaves weird is the envelope in the LUFS
>measurement section as it will crash at silence.
>> Would anyone have some time to look into it?
>>
>> Thanks for all your help!
>> Klaus
>>
>> On 17.07.21 18:03, Klaus Scheuermann wrote:
>>> Or maybe the 'gating' is better done in my 'leveler' section to keep
>the continuous lufs metering specs-compliant?
>>>
>>> I guess that is a good idea ;)
>>> This way I can specify the gating characteristics.
>>> (I will probably need some help with this...)
>>>
>>> my TO-DOs:
>>> - slider for target loudness in lufs
>>> - new leveler section slowly adapting loudness to target loudness
>>> - gating: freeze leveler when silence is detected on input
>>>
>>> Almost there ;)
>>>
>>> By the way, does an.ms_envelope_rect() work correctly now?
>>>
>>> Cheers, Klaus
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On 17.07.21 15:30, Klaus Scheuermann wrote:
>>>> Dear Juan Carlos,
>>>>
>>>> thanks so much for looking into the gating. I agree, we have
>'momentary' (Tg=0.4) and 'short-term' (Tg=3).
>>>>
>>>> I read some more about the secs from the EBU and I understood, that
>'integrated' is not quite what I need for 'master_me' as it is
>specified with a user interaction of play/pause/reset. (from:
>https://tech.ebu.ch/docs/tech/tech3341.pdf)
>>>>
>>>> The ‘EBU Mode’ loudness meter shall at least provide functionality
>that enables the user to –
>>>> 1. start/pause/continue the measurement of integrated loudness
>and Loudness Range simultaneously, that is, switch the meter between
>‘running’ and ‘stand-by’ states;
>>>> 2. reset the measurement of integrated loudness and Loudness
>Range simultaneously, regardless of whether the meter is in the
>‘running’ and ‘stand-by’ state.
>>>>
>>>> For master_me, I need a 'long-term' with gating. Or even better
>'variable-term' with gating ;)
>>>>
>>>> So much for now... Trying to understand your gating code now... :)
>>>>
>>>> Thanks, Klaus
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On 16.07.21 21:32, Juan Carlos Blancas wrote:
>>>>> Hi Klaus,
>>>>>
>>>>> Glad to hear the project update with M LUFS meters.
>>>>>
>>>>> I did a little research, scheme and a working sketch in Max, maybe
>it helps you somehow but my code in Faust its not working at the
>moment, kind of lost with this program, 0 intuitive for me... I’m using
>ba.if for the gates, ba.countup+ba.peakhold for resetable counter, and
>for the running cumulative average this formula I found in internet; (
>(counter * _ ) + newValue) / (counter+1) ) ~ _; Main issue how to keep
>track of the values from the gates and compute the running averages
>with an incremental automatic counter until the next manual reset.
>Second round soon when get more free time.
>>>>>
>>>>> Cheers,
>>>>> Juan Carlos
>>>>>
>>>>> ////////////////////////////
>>>>> /* 1770-3 scheme
>>>>>
>>>>> (M and I):
>>>>>
>>>>> 1) K-filter (HSF+RLB)—> sliding rect window, integration 400 ms,
>no gate —>
>>>>> 2) Update the linear output of the 400 ms sliding rect window
>every 100 ms (75% overlap, 10Hz refresh) => get Momentary LUFS (power
>dB, -0.691 correction).
>>>>> 3) Absolute gate: threshold at -70 LUFS, values below are ignored,
>take the linear values from the 10Hz updated 400 ms sliding window —>
>>>>> 4) Counting every value above the gate and calculate the running
>cumulative average, with a manual reset button for the counter —>
>>>>> 5) Relative gate: compare the output of the absolute gate with a
>-10 LU drop of the previous averaging —>
>>>>> 6) Counting every value above the relative gate and calculate the
>running cumulative average, with a manual reset button for the counter
>=> get Integrated LUFS (power dB, -0.691 correction).
>>>>>
>>>>> (S and LRA):
>>>>>
>>>>> 1) Sliding rect window, integration 3 sec, no gate —>
>>>>> 2) Update the linear output of the 3 sec sliding rect window every
>100 ms (75% overlap, 10Hz refresh) => get Shorterm LUFS (power dB,
>-0.691 correction).
>>>>> 3) Calculate LRA …
>>>>> ………
>>>>>
>>>>> */
>>>>>
>>>>> import("stdfaust.lib");
>>>>>
>>>>> A48kHz = ( /* 1.0, */ -1.99004745483398, 0.99007225036621);
>>>>> B48kHz = (1.0, -2.0, 1.0);
>>>>> highpass48kHz = fi.iir(B48kHz,A48kHz);
>>>>> highpass = fi.highpass(2, 40);
>>>>>
>>>>> boostDB = 4;
>>>>> boostFreqHz = 1430;
>>>>> highshelf = fi.high_shelf(boostDB, boostFreqHz);
>>>>>
>>>>> kfilter = highshelf : highpass;
>>>>>
>>>>> MAXN = 262144;
>>>>> Tg = 0.4;
>>>>> Ovlp = 10; // Hz
>>>>>
>>>>> W = ma.SR*0.4;
>>>>> float2fix(n) = *(2^n) : int;
>>>>> fix2float(n) = float : /(2^n);
>>>>>
>>>>> avg400msWindow = kfilter : ^(2) : float2fix(16) <: _,@(W) : - :
>+~_ : fix2float(16) : /(W);
>>>>>
>>>>> overlap100ms = ba.if( os.lf_pulsetrain(Ovlp) > 0.5,
>avg400msWindow, !);
>>>>> dB = (-0.691 + (10*log10(overlap100ms)));
>>>>>
>>>>> reset = button("reset") : ba.impulsify;
>>>>> gateAbsolute = ba.if( dB > -70, overlap100ms, !);
>>>>> counter1 = ba.if( dB > -70.0, 1, 0);
>>>>> sampleHold1 = ba.countup(ma.SR*300, 1-counter1+reset) <: _,
>ba.peakhold(1-reset) :> _;
>>>>> cumulativeAverage1 = (((sampleHold1*_)+gateAbsolute) /
>(sampleHold1+1)) ~ _;
>>>>>
>>>>> gateRelative = ba.if( (-0.691 + (10*log10(gateAbsolute))) >
>(-10.691 + (10*log10(cumulativeAverage1))), overlap100ms, !);
>>>>> counter2 = ba.if( (-0.691 + (10*log10(gateRelative))) > -70.0, 1,
>0);
>>>>> sampleHold2 = ba.countup(ma.SR*300, 1-counter2+reset) <: _,
>ba.peakhold(1-reset) :> _;
>>>>> cumulativeAverage2 = (((sampleHold2*_)+gateRelative) /
>(sampleHold2+1)) ~ _;
>>>>> integratedLUFS = (-0.691 + (10*log10(cumulativeAverage2)));
>>>>>
>>>>> process = _ <: _, ( integratedLUFS : vbargraph("[0]INTEGRATED
>LUFS",-70,0.0)) : attach;
>>>>>
>>>>> ////////////////////////////
>>>>>
>>>>>
>>>>>> El 16 jul 2021, a las 9:57, Klaus Scheuermann <kla...@posteo.de>
>escribió:
>>>>>>
>>>>>> Hello Juan Carlos,
>>>>>>
>>>>>> with great help from the list (thanks!) I could implement
>(momentary) lufs metering in my project:
>>>>>> https://github.com/trummerschlunk/master_me
>>>>>>
>>>>>>> also thinking about how to do the -70 dB gate and most important
>the integrated loudness.
>>>>>> Did you give this a thought? I am - once again - a bit lost here.
>>>>>> The specs say:
>(https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1770-3-201208-S!!PDF-E.pdf)
>>>>>>
>>>>>> gating of 400 ms blocks (overlapping by 75%), where two
>thresholds are used:
>>>>>> – the first at –70 LKFS;
>>>>>> – the second at –10 dB relative to the level measured
>after application of the first threshold.
>>>>>>
>>>>>> I guess, the gating can be done with a sliding window too, right?
>Or is it done in the same window we use for measurement?
>>>>>>
>>>>>> How do I gate a variable in two stages?
>>>>>>
>>>>>> Thanks, Klaus
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 10.07.21 18:15, Juan Carlos Blancas wrote:
>>>>>>>
>>>>>>>> El 10 jul 2021, a las 15:31, Klaus Scheuermann
><kla...@posteo.de> escribió:
>>>>>>>>
>>>>>>>> Hello Juan Carlos,
>>>>>>>>
>>>>>>>>> Klaus, I’m using Atom+FaustLive, Max and SC to do the tests,
>but I get the same crash as you with faustide/editor.
>>>>>>>>> https://www.dropbox.com/s/blwtwao7j317db0/test.mov?dl=0
>>>>>>>> cool, thanks!
>>>>>>>>
>>>>>>>>> Btw the reading are aprox but not the same as Youlean nor
>Insight2 for instance…
>>>>>>>> great, that’s promising!
>>>>>>>>
>>>>>>>>> also thinking about how to do the -70 dB gate and most
>important the integrated loudness.
>>>>>>>> Yes, I was wondering about that too… Just so you have some
>context, I don’t want to replicate an lufs meter, but I want to use
>lufs it in my project master_me, which is meant to stabilise audio
>during streaming events: https://github.com/trummerschlunk/master_me
>>>>>>>> For that I would like to be able to adjust the agility of the
>integrated loudness. Also the gating should be adjustable.
>>>>>>>
>>>>>>> Nice project! definitely would be great to add LUFS meters and
>kind of a loudness stabilizer with targets.
>>>>>>> Best,
>>>>>>> Juan Carlos
>>>>>>>
>>>>>>>
>>>>>>>>> On 10. Jul 2021, at 14:47, Juan Carlos Blancas
><lav...@gmail.com> wrote:
>>>>>>>>>
>>>>>>>>> Klaus, I’m using Atom+FaustLive, Max and SC to do the tests,
>but I get the same crash as you with faustide/editor.
>>>>>>>>> https://www.dropbox.com/s/blwtwao7j317db0/test.mov?dl=0
>>>>>>>>>
>>>>>>>>> Btw the reading are aprox but not the same as Youlean nor
>Insight2 for instance…
>>>>>>>>> also thinking about how to do the -70 dB gate and most
>important the integrated loudness.
>>>>>>>>>
>>>>>>>>> Cheers,
>>>>>>>>> Juan Carlos
>>>>>>>>>
>>>>>>>>>> El 10 jul 2021, a las 12:17, Klaus Scheuermann
><kla...@posteo.de> escribió:
>>>>>>>>>>
>>>>>>>>>> Thanks, Juan :)
>>>>>>>>>>
>>>>>>>>>> Your code crashes my faustide on firefox and on chromium
>(both linux).
>>>>>>>>>> Here is the error message:
>>>>>>>>>>
>>>>>>>>>> ASSERT : please report this message and the failing DSP file
>to Faust
>>>>>>>>>> developers (file: wasm_instructions.hh, line: 918, version:
>2.32.16,
>>>>>>>>>> options: -lang wasm-ib -es 1 -single -ftz 0)
>>>>>>>>>>
>>>>>>>>>> When 'realtime compile' is active, the only way to gain
>control again is
>>>>>>>>>> to delete all cookies and cache from the site.
>>>>>>>>>>
>>>>>>>>>> I'll try Dario's workaround now ;)
>>>>>>>>>>
>>>>>>>>>> Cheers, Klaus
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 09.07.21 18:08, Juan Carlos Blancas wrote:
>>>>>>>>>>> Hi Klaus,
>>>>>>>>>>>
>>>>>>>>>>> For me ms_envelope and rms_envelope functions are not
>working properly. I’ve done some test in my Mac Pro with High Sierra,
>porting without barograph to Max or Supercollider and I get the strange
>gate behaviour in low levels.
>>>>>>>>>>>
>>>>>>>>>>> My workaround at the moment is using ba.slidingMeanp instead
>of ms_envelope, but it’s 2x cpu intense, so I guess Dario solution of
>1plp filter would be the best for the mean square stage.
>>>>>>>>>>>
>>>>>>>>>>>>> lp1p(cf, x) = fi.pole(b, x * (1 - b))
>>>>>>>>>>>>> with {
>>>>>>>>>>>>> b = exp(-2 * ma.PI * cf / ma.SR);
>>>>>>>>>>>>> };
>>>>>>>>>>>>> zi_lp(x) = lp1p(1 / Tg, x * x);
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Cheers,
>>>>>>>>>>> Juan Carlos
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> // Mono Momentary LUFS meter without gate of Julius, using
>slidingMeanp instead of ms_envelope
>>>>>>>>>>>
>>>>>>>>>>> import("stdfaust.lib");
>>>>>>>>>>>
>>>>>>>>>>> A48kHz = ( /* 1.0, */ -1.99004745483398, 0.99007225036621);
>>>>>>>>>>> B48kHz = (1.0, -2.0, 1.0);
>>>>>>>>>>> highpass48kHz = fi.iir(B48kHz,A48kHz);
>>>>>>>>>>> highpass = fi.highpass(2, 40);
>>>>>>>>>>>
>>>>>>>>>>> boostDB = 4;
>>>>>>>>>>> boostFreqHz = 1430;
>>>>>>>>>>> highshelf = fi.high_shelf(boostDB, boostFreqHz);
>>>>>>>>>>> kfilter = highshelf : highpass;
>>>>>>>>>>>
>>>>>>>>>>> MAXN = 262144;
>>>>>>>>>>> Tg = 0.4;
>>>>>>>>>>> Lk = kfilter <: _*_ : ba.slidingMeanp(Tg*ma.SR, MAXN) :
>ba.linear2db : *(0.5);
>>>>>>>>>>>
>>>>>>>>>>> process = _ <: attach(_, Lk : hbargraph("[1]Momentary
>LUFS",-70,0));
>>>>>>>>>>>
>>>>>>>>>>> //
>>>>>>>>>>>
>>>>>>>>>>>> El 9 jul 2021, a las 16:55, Klaus Scheuermann
><kla...@posteo.de> escribió:
>>>>>>>>>>>>
>>>>>>>>>>>> Ha, so I was really on to something ;)
>>>>>>>>>>>>
>>>>>>>>>>>> Is the bug in the meter or in the envelope?
>>>>>>>>>>>> Would you have a workaround for me to get on with the lufs
>analyser?
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks, Klaus
>>>>>>>>>>>>
>>>>>>>>>>>> On 08.07.21 19:19, Julius Smith wrote:
>>>>>>>>>>>>> Hi Dario,
>>>>>>>>>>>>>
>>>>>>>>>>>>> The problem seems to be architecture-dependent. I am on a
>Mac (latest
>>>>>>>>>>>>> non-beta software) using faust2caqt. What are you using?
>>>>>>>>>>>>>
>>>>>>>>>>>>> I do not see the "strange behavior" you describe.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Your test looks good for me in faust2octave, with gain set
>to 0.01 (-40
>>>>>>>>>>>>> dB, which triggers the display bug on my system). In
>>>>>>>>>>>>> Octave, faustout(end,:) shows
>>>>>>>>>>>>>
>>>>>>>>>>>>> -44.744 -44.968 -44.708
>>>>>>>>>>>>>
>>>>>>>>>>>>> which at first glance seems close enough for noise input
>and slightly
>>>>>>>>>>>>> different averaging windows. Changing the signal to a
>constant 0.01, I get
>>>>>>>>>>>>>
>>>>>>>>>>>>> -39.994 -40.225 -40.000
>>>>>>>>>>>>>
>>>>>>>>>>>>> which is not too bad, but which should probably be
>sharpened up. The
>>>>>>>>>>>>> third value (zi_lp) is right on, of course.
>>>>>>>>>>>>>
>>>>>>>>>>>>> gain = 0.01; // hslider("Gain [unit:dB]",-70,-70,0,0.1) :
>ba.db2linear;
>>>>>>>>>>>>> sig = gain; //sig = no.noise * gain;
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Thu, Jul 8, 2021 at 3:53 AM Dario Sanfilippo
>>>>>>>>>>>>> <sanfilippo.da...@gmail.com
><mailto:sanfilippo.da...@gmail.com>> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> Hi, Julius.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I must be missing something, but I couldn't see the
>behaviour that
>>>>>>>>>>>>> you described, that is, the gating behaviour happening
>only for the
>>>>>>>>>>>>> display and not for the output.
>>>>>>>>>>>>>
>>>>>>>>>>>>> If a removethe hbargraphaltogether, I can still see the
>strange
>>>>>>>>>>>>> behaviour. Just so we're all on the same page, the
>strange behaviour
>>>>>>>>>>>>> we're referring to is the fact that, after going back to
>low input
>>>>>>>>>>>>> gains, the displayed levels are -inf instead of some low,
>>>>>>>>>>>>> quantifiable ones, right?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Using a leaky integrator makes the calculations rather
>inaccurate.
>>>>>>>>>>>>> I'd say that, if one needs to use single-precision,
>averaging with a
>>>>>>>>>>>>> one-pole lowpass would be best:
>>>>>>>>>>>>>
>>>>>>>>>>>>> import("stdfaust.lib");
>>>>>>>>>>>>> zi = an.ms_envelope_rect(Tg);
>>>>>>>>>>>>> slidingSum(n) = fi.pole(.999999) <: _, _@int(max(0,n)) :>
>-;
>>>>>>>>>>>>> slidingMean(n) = slidingSum(n)/rint(n);
>>>>>>>>>>>>> zi_leaky(x) = slidingMean(Tg*ma.SR, x * x);
>>>>>>>>>>>>> lp1p(cf, x) = fi.pole(b, x * (1 - b))
>>>>>>>>>>>>> with {
>>>>>>>>>>>>> b = exp(-2 * ma.PI * cf / ma.SR);
>>>>>>>>>>>>> };
>>>>>>>>>>>>> zi_lp(x) = lp1p(1 / Tg, x * x);
>>>>>>>>>>>>> Tg = 0.4;
>>>>>>>>>>>>> sig = no.noise * gain;
>>>>>>>>>>>>> gain = hslider("Gain [unit:dB]",-70,-70,0,0.1) :
>ba.db2linear;
>>>>>>>>>>>>> level = ba.linear2db : *(0.5);
>>>>>>>>>>>>> process = sig <: level(zi) , level(zi_leaky) ,
>level(zi_lp);
>>>>>>>>>>>>>
>>>>>>>>>>>>> Ciao,
>>>>>>>>>>>>> Dr Dario Sanfilippo
>>>>>>>>>>>>> http://dariosanfilippo.com <http://dariosanfilippo.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Thu, 8 Jul 2021 at 00:39, Julius Smith
><julius.sm...@gmail.com
>>>>>>>>>>>>> <mailto:julius.sm...@gmail.com>> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> I think that the problem is in an.ms_envelope_rect,
>>>>>>>>>>>>> particularly the fact that it has a non-leaky
>integrator. I
>>>>>>>>>>>>> assume that when large values recirculate in the
>integrator, the
>>>>>>>>>>>>> smaller ones, after pushing the gain down, are
>truncated to 0
>>>>>>>>>>>>> due to single-precision. As a matter of fact,
>compiling the code
>>>>>>>>>>>>> in double precision looks fine here.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I just took a look and see that it's essentially
>based on + ~ _
>>>>>>>>>>>>> : (_ - @(rectWindowLenthSamples))
>>>>>>>>>>>>> This will indeed suffer from a growing roundoff error
>variance
>>>>>>>>>>>>> over time (typically linear growth).
>>>>>>>>>>>>> However, I do not see any noticeable effects of this
>in my
>>>>>>>>>>>>> testing thus far.
>>>>>>>>>>>>> To address this properly, we should be using TIIR
>filtering
>>>>>>>>>>>>> principles ("Truncated IIR"), in which two such units
>pingpong
>>>>>>>>>>>>> and alternately reset.
>>>>>>>>>>>>> Alternatively, a small exponential decay can be
>added: + ~
>>>>>>>>>>>>> *(0.999999) ... etc.
>>>>>>>>>>>>>
>>>>>>>>>>>>> - Julius
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, Jul 7, 2021 at 12:32 PM Dario Sanfilippo
>>>>>>>>>>>>> <sanfilippo.da...@gmail.com
><mailto:sanfilippo.da...@gmail.com>>
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> I think that the problem is in
>an.ms_envelope_rect,
>>>>>>>>>>>>> particularly the fact that it has a non-leaky
>integrator. I
>>>>>>>>>>>>> assume that when large values recirculate in the
>integrator,
>>>>>>>>>>>>> the smaller ones, after pushing the gain down,
>are truncated
>>>>>>>>>>>>> to 0 due to single-precision. As a matter of
>fact, compiling
>>>>>>>>>>>>> the code in double precision looks fine here.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Ciao,
>>>>>>>>>>>>> Dr Dario Sanfilippo
>>>>>>>>>>>>> http://dariosanfilippo.com
><http://dariosanfilippo.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, 7 Jul 2021 at 19:25, Stéphane Letz
><l...@grame.fr
>>>>>>>>>>>>> <mailto:l...@grame.fr>> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> « hargraph seems to have some kind of a gate
>in it that
>>>>>>>>>>>>> kicks in around -35 dB. » humm….
>hargraph/vbargrah only
>>>>>>>>>>>>> keep the last value of their written
>FAUSTFLOAT* zone,
>>>>>>>>>>>>> so once per block, without any processing of
>course…
>>>>>>>>>>>>>
>>>>>>>>>>>>> Have you looked at the produce C++ code?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Stéphane
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Le 7 juil. 2021 à 18:31, Julius Smith
>>>>>>>>>>>>> <julius.sm...@gmail.com
><mailto:julius.sm...@gmail.com>>
>>>>>>>>>>>>> a écrit :
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> That is strange - hbargraph seems to have some kind of
>>>>>>>>>>>>> a gate in it that kicks in around -35 dB.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> In this modified version, you can hear that the sound
>>>>>>>>>>>>> is ok:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> import("stdfaust.lib");
>>>>>>>>>>>>>> Tg = 0.4;
>>>>>>>>>>>>>> zi = an.ms_envelope_rect(Tg);
>>>>>>>>>>>>>> gain = hslider("Gain [unit:dB]",-10,-70,0,0.1) :
>>>>>>>>>>>>> ba.db2linear;
>>>>>>>>>>>>>> sig = no.noise * gain;
>>>>>>>>>>>>>> process = attach(sig, (sig : zi : ba.linear2db :
>>>>>>>>>>>>> *(0.5) : hbargraph("test",-70,0)));
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, Jul 7, 2021 at 12:59 AM Klaus Scheuermann
>>>>>>>>>>>>> <kla...@posteo.de <mailto:kla...@posteo.de>>
>wrote:
>>>>>>>>>>>>>> Hi all,
>>>>>>>>>>>>>> I did some testing and
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> an.ms_envelope_rect()
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> seems to show some strange behaviour (at least to me).
>>>>>>>>>>>>> Here is a video
>>>>>>>>>>>>>> of the test:
>>>>>>>>>>>>>> https://cloud.4ohm.de/s/64caEPBqxXeRMt5
>>>>>>>>>>>>> <https://cloud.4ohm.de/s/64caEPBqxXeRMt5>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> The audio is white noise and the testing code is:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> import("stdfaust.lib");
>>>>>>>>>>>>>> Tg = 0.4;
>>>>>>>>>>>>>> zi = an.ms_envelope_rect(Tg);
>>>>>>>>>>>>>> process = _ : zi : ba.linear2db :
>hbargraph("test",-95,0);
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Could you please verify?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks, Klaus
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 05.07.21 20:16, Julius Smith wrote:
>>>>>>>>>>>>>>> Hmmm, '!' means "block the signal", but attach
>>>>>>>>>>>>> should save the bargraph
>>>>>>>>>>>>>>> from being optimized away as a result. Maybe I
>>>>>>>>>>>>> misremembered the
>>>>>>>>>>>>>>> argument order to attach? While it's very simple in
>>>>>>>>>>>>> concept, it can be
>>>>>>>>>>>>>>> confusing in practice.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I chose not to have a gate at all, but you can grab
>>>>>>>>>>>>> one from
>>>>>>>>>>>>>>> misceffects.lib if you like. Low volume should not
>>>>>>>>>>>>> give -infinity,
>>>>>>>>>>>>>>> that's a bug, but zero should, and zero should
>>>>>>>>>>>>> become MIN as I mentioned
>>>>>>>>>>>>>>> so -infinity should never happen.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>>>> Julius
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Mon, Jul 5, 2021 at 10:39 AM Klaus Scheuermann
>>>>>>>>>>>>> <kla...@posteo.de <mailto:kla...@posteo.de>
>>>>>>>>>>>>>>> <mailto:kla...@posteo.de <mailto:kla...@posteo.de>>>
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Cheers Julius,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> At least I understood the 'attach' primitive now
>>>>>>>>>>>>> ;) Thanks.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> This does not show any meter here...
>>>>>>>>>>>>>>> process(x,y) = x,y <: (_,_), attach(x, (Lk2 :
>>>>>>>>>>>>> vbargraph("LUFS",-90,0)))
>>>>>>>>>>>>>>> : _,_,!;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> But this does for some reason (although the
>>>>>>>>>>>>> output is 3-channel then):
>>>>>>>>>>>>>>> process(x,y) = x,y <: (_,_), attach(x, (Lk2 :
>>>>>>>>>>>>> vbargraph("LUFS",-90,0)))
>>>>>>>>>>>>>>> : _,_,_;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> What does the '!' do?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I still don't quite get the gating topic. In my
>>>>>>>>>>>>> understanding, the meter
>>>>>>>>>>>>>>> should hold the current value if the input
>>>>>>>>>>>>> signal drops below a
>>>>>>>>>>>>>>> threshold. In your version, the meter drops to
>>>>>>>>>>>>> -infinity when very low
>>>>>>>>>>>>>>> volume content is played.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Which part of your code does the gating?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Many thanks,
>>>>>>>>>>>>>>> Klaus
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On 05.07.21 18:06, Julius Smith wrote:
>>>>>>>>>>>>>>>> Hi Klaus,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Yes, I agree the filters are close enough. I
>>>>>>>>>>>>> bet that the shelf is
>>>>>>>>>>>>>>>> exactly correct if we determined the exact
>>>>>>>>>>>>> transition frequency, and
>>>>>>>>>>>>>>>> that the Butterworth highpass is close enough
>>>>>>>>>>>>> to the
>>>>>>>>>>>>>>> Bessel-or-whatever
>>>>>>>>>>>>>>>> that is inexplicably not specified as a filter
>>>>>>>>>>>>> type, leaving it
>>>>>>>>>>>>>>>> sample-rate dependent. I would bet large odds
>>>>>>>>>>>>> that the differences
>>>>>>>>>>>>>>>> cannot be reliably detected in listening tests.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Yes, I just looked again, and there are
>>>>>>>>>>>>> "gating blocks" defined,
>>>>>>>>>>>>>>> each Tg
>>>>>>>>>>>>>>>> = 0.4 sec long, so that only ungated blocks
>>>>>>>>>>>>> are averaged to form a
>>>>>>>>>>>>>>>> longer term level-estimate. What I wrote
>>>>>>>>>>>>> gives a "sliding gating
>>>>>>>>>>>>>>>> block", which can be lowpass filtered further,
>>>>>>>>>>>>> and/or gated, etc.
>>>>>>>>>>>>>>>> Instead of a gate, I would simply replace 0 by
>>>>>>>>>>>>> ma.EPSILON so that the
>>>>>>>>>>>>>>>> log always works (good for avoiding denormals
>>>>>>>>>>>>> as well).
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I believe stereo is supposed to be handled
>>>>>>>>>>>>> like this:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Lk2 = _,0,_,0,0 : Lk5;
>>>>>>>>>>>>>>>> process(x,y) = Lk2(x,y);
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> or
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Lk2 = Lk(0),Lk(2) :> 10 * log10 : -(0.691);
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> but since the center channel is processed
>>>>>>>>>>>>> identically to left
>>>>>>>>>>>>>>> and right,
>>>>>>>>>>>>>>>> your solution also works.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Bypassing is normal Faust, e.g.,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> process(x,y) = x,y <: (_,_), attach(x, (Lk2 :
>>>>>>>>>>>>>>> vbargraph("LUFS",-90,0)))
>>>>>>>>>>>>>>>> : _,_,!;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>>>>> Julius
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Mon, Jul 5, 2021 at 1:56 AM Klaus
>>>>>>>>>>>>> Scheuermann <kla...@posteo.de
><mailto:kla...@posteo.de>
>>>>>>>>>>>>>>> <mailto:kla...@posteo.de <mailto:kla...@posteo.de>>
>>>>>>>>>>>>>>>> <mailto:kla...@posteo.de
>>>>>>>>>>>>> <mailto:kla...@posteo.de>
><mailto:kla...@posteo.de
>>>>>>>>>>>>> <mailto:kla...@posteo.de>>>> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I can never resist these things! Faust
>>>>>>>>>>>>> makes it too
>>>>>>>>>>>>>>> enjoyable :-)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Glad you can't ;)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I understood you approximate the filters
>>>>>>>>>>>>> with standard faust
>>>>>>>>>>>>>>> filters.
>>>>>>>>>>>>>>>> That is probably close enough for me :)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I also get the part with the sliding
>>>>>>>>>>>>> window envelope. If I
>>>>>>>>>>>>>>> wanted to
>>>>>>>>>>>>>>>> make the meter follow slowlier, I would
>>>>>>>>>>>>> just widen the window
>>>>>>>>>>>>>>> with Tg.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The 'gating' part I don't understand for
>>>>>>>>>>>>> lack of mathematical
>>>>>>>>>>>>>>> knowledge,
>>>>>>>>>>>>>>>> but I suppose it is meant differently.
>>>>>>>>>>>>> When the input signal
>>>>>>>>>>>>>>> falls below
>>>>>>>>>>>>>>>> the gate threshold, the meter should stay
>>>>>>>>>>>>> at the current
>>>>>>>>>>>>>>> value, not drop
>>>>>>>>>>>>>>>> to -infinity, right? This is so 'silent'
>>>>>>>>>>>>> parts are not taken into
>>>>>>>>>>>>>>>> account.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> If I wanted to make a stereo version it
>>>>>>>>>>>>> would be something like
>>>>>>>>>>>>>>>> this, right?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Lk2 = par(i,2, Lk(i)) :> 10 * log10 :
>>>>>>>>>>>>> -(0.691);
>>>>>>>>>>>>>>>> process = _,_ : Lk2 : vbargraph("LUFS",-90,0);
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Probably very easy, but how do I attach
>>>>>>>>>>>>> this to a stereo
>>>>>>>>>>>>>>> signal (passing
>>>>>>>>>>>>>>>> through the stereo signal)?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks again!
>>>>>>>>>>>>>>>> Klaus
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I made a pass, but there is a small
>>>>>>>>>>>>> scaling error. I think
>>>>>>>>>>>>>>> it can be
>>>>>>>>>>>>>>>>> fixed by reducing boostFreqHz until the
>>>>>>>>>>>>> sine_test is nailed.
>>>>>>>>>>>>>>>>> The highpass is close (and not a source
>>>>>>>>>>>>> of the scale error),
>>>>>>>>>>>>>>> but I'm
>>>>>>>>>>>>>>>>> using Butterworth instead of whatever
>>>>>>>>>>>>> they used.
>>>>>>>>>>>>>>>>> I glossed over the discussion of
>>>>>>>>>>>>> "gating" in the spec, and
>>>>>>>>>>>>>>> may have
>>>>>>>>>>>>>>>>> missed something important there, but
>>>>>>>>>>>>>>>>> I simply tried to make a sliding
>>>>>>>>>>>>> rectangular window, instead
>>>>>>>>>>>>>>> of 75%
>>>>>>>>>>>>>>>>> overlap, etc.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> If useful, let me know and I'll propose
>>>>>>>>>>>>> it for analyzers.lib!
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>>>>>> Julius
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> import("stdfaust.lib");
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> // Highpass:
>>>>>>>>>>>>>>>>> // At 48 kHz, this is the right highpass
>>>>>>>>>>>>> filter (maybe a
>>>>>>>>>>>>>>> Bessel or
>>>>>>>>>>>>>>>>> Thiran filter?):
>>>>>>>>>>>>>>>>> A48kHz = ( /* 1.0, */ -1.99004745483398,
>>>>>>>>>>>>> 0.99007225036621);
>>>>>>>>>>>>>>>>> B48kHz = (1.0, -2.0, 1.0);
>>>>>>>>>>>>>>>>> highpass48kHz = fi.iir(B48kHz,A48kHz);
>>>>>>>>>>>>>>>>> highpass = fi.highpass(2, 40); //
>>>>>>>>>>>>> Butterworth highpass:
>>>>>>>>>>>>>>> roll-off is a
>>>>>>>>>>>>>>>>> little too sharp
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> // High Shelf:
>>>>>>>>>>>>>>>>> boostDB = 4;
>>>>>>>>>>>>>>>>> boostFreqHz = 1430; // a little too high
>>>>>>>>>>>>> - they should give
>>>>>>>>>>>>>>> us this!
>>>>>>>>>>>>>>>>> highshelf = fi.high_shelf(boostDB,
>>>>>>>>>>>>> boostFreqHz); // Looks
>>>>>>>>>>>>>>> very close,
>>>>>>>>>>>>>>>>> but 1 kHz gain has to be nailed
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> kfilter = highshelf : highpass;
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> // Power sum:
>>>>>>>>>>>>>>>>> Tg = 0.4; // spec calls for 75% overlap
>>>>>>>>>>>>> of successive
>>>>>>>>>>>>>>> rectangular
>>>>>>>>>>>>>>>>> windows - we're overlapping MUCH more
>>>>>>>>>>>>> (sliding window)
>>>>>>>>>>>>>>>>> zi = an.ms_envelope_rect(Tg); // mean
>>>>>>>>>>>>> square: average power =
>>>>>>>>>>>>>>>> energy/Tg
>>>>>>>>>>>>>>>>> = integral of squared signal / Tg
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> // Gain vector Gv = (GL,GR,GC,GLs,GRs):
>>>>>>>>>>>>>>>>> N = 5;
>>>>>>>>>>>>>>>>> Gv = (1, 1, 1, 1.41, 1.41); // left
>>>>>>>>>>>>> GL(-30deg), right GR
>>>>>>>>>>>>>>> (30), center
>>>>>>>>>>>>>>>>> GC(0), left surround GLs(-110), right
>>>>>>>>>>>>> surr. GRs(110)
>>>>>>>>>>>>>>>>> G(i) = *(ba.take(i+1,Gv));
>>>>>>>>>>>>>>>>> Lk(i) = kfilter : zi : G(i); // one
>>>>>>>>>>>>> channel, before summing
>>>>>>>>>>>>>>> and before
>>>>>>>>>>>>>>>>> taking dB and offsetting
>>>>>>>>>>>>>>>>> LkDB(i) = Lk(i) : 10 * log10 : -(0.691);
>>>>>>>>>>>>> // Use this for a mono
>>>>>>>>>>>>>>>> input signal
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> // Five-channel surround input:
>>>>>>>>>>>>>>>>> Lk5 = par(i,5,Lk(i)) :> 10 * log10 :
>>>>>>>>>>>>> -(0.691);
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> // sine_test = os.oscrs(1000); // should
>>>>>>>>>>>>> give –3.01 LKFS, with
>>>>>>>>>>>>>>>>> GL=GR=GC=1 (0dB) and GLs=GRs=1.41 (~1.5 dB)
>>>>>>>>>>>>>>>>> sine_test = os.osc(1000);
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> process = sine_test : LkDB(0); // should
>>>>>>>>>>>>> read -3.01 LKFS -
>>>>>>>>>>>>>>> high-shelf
>>>>>>>>>>>>>>>>> gain at 1 kHz is critical
>>>>>>>>>>>>>>>>> // process = 0,sine_test,0,0,0 : Lk5; //
>>>>>>>>>>>>> should read -3.01
>>>>>>>>>>>>>>> LKFS for
>>>>>>>>>>>>>>>>> left, center, and right
>>>>>>>>>>>>>>>>> // Highpass test: process = 1-1' <:
>>>>>>>>>>>>> highpass, highpass48kHz;
>>>>>>>>>>>>>>> // fft in
>>>>>>>>>>>>>>>>> Octave
>>>>>>>>>>>>>>>>> // High shelf test: process = 1-1' :
>>>>>>>>>>>>> highshelf; // fft in Octave
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Sat, Jul 3, 2021 at 1:08 AM Klaus
>>>>>>>>>>>>> Scheuermann
>>>>>>>>>>>>>>> <kla...@posteo.de <mailto:kla...@posteo.de>
>>>>>>>
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
_______________________________________________
Faudiostream-users mailing list
Faudiostream-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/faudiostream-users