> 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>
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
>
>
> On Wed, 7 Jul 2021 at 19:25, Stéphane Letz <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> 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>
>> 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
>> >
>> > 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>> 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>>> 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>
>> > >     >     <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:
>> > >     >     >
>> > >     >     >     Hello everyone :)
>> > >     >     >
>> > >     >     >     Would someone be up for helping me implement an LUFS
>> > >     loudness
>> > >     >     analyser
>> > >     >     >     in faust?
>> > >     >     >
>> > >     >     >     Or has someone done it already?
>> > >     >     >
>> > >     >     >     LUFS (aka LKFS) is becoming more and more the
>> standard for
>> > >     >     loudness
>> > >     >     >     measurement in the audio industry. Youtube, Spotify
>> and
>> > >     broadcast
>> > >     >     >     stations use the concept to normalize loudness. A very
>> > >     >     positive side
>> > >     >     >     effect is, that loudness-wars are basically over.
>> > >     >     >
>> > >     >     >     I looked into it, but my programming skills clearly
>> > >     don't match
>> > >     >     >     the level for implementing this.
>> > >     >     >
>> > >     >     >     Here is some resource about the topic:
>> > >     >     >
>> > >     >     >     https://en.wikipedia.org/wiki/LKFS
>> > >     <https://en.wikipedia.org/wiki/LKFS>
>> > >     >     <https://en.wikipedia.org/wiki/LKFS
>> > >     <https://en.wikipedia.org/wiki/LKFS>>
>> > >     >     <https://en.wikipedia.org/wiki/LKFS
>> > >     <https://en.wikipedia.org/wiki/LKFS>
>> > >     >     <https://en.wikipedia.org/wiki/LKFS
>> > >     <https://en.wikipedia.org/wiki/LKFS>>>
>> > >     >     >
>> > >     >     >     Specifications (in Annex 1):
>> > >     >     >
>> > >     >
>> > >
>> https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1770-3-201208-S!!PDF-E.pdf
>> > >     <
>> https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1770-3-201208-S!!PDF-E.pdf
>> >
>> > >     >
>> > >      <
>> https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1770-3-201208-S!!PDF-E.pdf
>> > >     <
>> https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1770-3-201208-S!!PDF-E.pdf
>> >>
>> > >     >     >
>> > >     >
>> > >       <
>> https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1770-3-201208-S!!PDF-E.pdf
>> > >     <
>> https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1770-3-201208-S!!PDF-E.pdf
>> >
>> > >     >
>> > >      <
>> https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1770-3-201208-S!!PDF-E.pdf
>> > >     <
>> https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1770-3-201208-S!!PDF-E.pdf
>> >>>
>> > >     >     >
>> > >     >     >     An implementation by 'klangfreund' in JUCE / C:
>> > >     >     >     https://github.com/klangfreund/LUFSMeter
>> > >     <https://github.com/klangfreund/LUFSMeter>
>> > >     >     <https://github.com/klangfreund/LUFSMeter
>> > >     <https://github.com/klangfreund/LUFSMeter>>
>> > >     >     >     <https://github.com/klangfreund/LUFSMeter
>> > >     <https://github.com/klangfreund/LUFSMeter>
>> > >     >     <https://github.com/klangfreund/LUFSMeter
>> > >     <https://github.com/klangfreund/LUFSMeter>>>
>> > >     >     >
>> > >     >     >     There is also a free LUFS Meter in JS / Reaper by
>> > >     Geraint Luff.
>> > >     >     >     (The code can be seen in reaper, but I don't know if I
>> > >     should
>> > >     >     paste it
>> > >     >     >     here.)
>> > >     >     >
>> > >     >     >     Please let me know if you are up for it!
>> > >     >     >
>> > >     >     >     Take care,
>> > >     >     >     Klaus
>> > >     >     >
>> > >     >     >
>> > >     >     >     _______________________________________________
>> > >     >     >     Faudiostream-users mailing list
>> > >     >     >     Faudiostream-users@lists.sourceforge.net
>> > >     <mailto:Faudiostream-users@lists.sourceforge.net>
>> > >     >     <mailto:Faudiostream-users@lists.sourceforge.net
>> > >     <mailto:Faudiostream-users@lists.sourceforge.net>>
>> > >     >     >     <mailto:Faudiostream-users@lists.sourceforge.net
>> > >     <mailto:Faudiostream-users@lists.sourceforge.net>
>> > >     >     <mailto:Faudiostream-users@lists.sourceforge.net
>> > >     <mailto:Faudiostream-users@lists.sourceforge.net>>>
>> > >     >     >
>> > >     >
>> > >       https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>> > >     <https://lists.sourceforge.net/lists/listinfo/faudiostream-users>
>> > >     >
>> > >      <https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>> > >     <https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>> >>
>> > >     >     >
>> > >     >
>> > >       <
>> https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>> > >     <https://lists.sourceforge.net/lists/listinfo/faudiostream-users>
>> > >     >
>> > >      <https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>> > >     <https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>> >>>
>> > >     >     >
>> > >     >     >
>> > >     >     >
>> > >     >     > --
>> > >     >     > "Anybody who knows all about nothing knows everything" --
>> > >     Leonard
>> > >     >     Susskind
>> > >     >
>> > >     >
>> > >     >
>> > >     > --
>> > >     > "Anybody who knows all about nothing knows everything" --
>> Leonard
>> > >     Susskind
>> > >
>> > >
>> > >
>> > > --
>> > > "Anybody who knows all about nothing knows everything" -- Leonard
>> Susskind
>> >
>> >
>> > --
>> > "Anybody who knows all about nothing knows everything" -- Leonard
>> Susskind
>> > _______________________________________________
>> > Faudiostream-users mailing list
>> > Faudiostream-users@lists.sourceforge.net
>> > https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>>
>>
>>
>> _______________________________________________
>> Faudiostream-users mailing list
>> Faudiostream-users@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>>
>

-- 
"Anybody who knows all about nothing knows everything" -- Leonard Susskind
_______________________________________________
Faudiostream-users mailing list
Faudiostream-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/faudiostream-users

Reply via email to