Hi Dario, Ok, I see what you're after now. (I was considering only the VU meter display issue up to now.)
There's only 23 bits of mantissa in 32-bit floating point, and your test counts up to ~100k, which soaks up about 17 bits, and then you hit it with ~1/1024, or 2^(-10), which is then a dynamic range swing of 27 bits. We can't add numbers separated by 27 bits of dynamic level using a mantissa (or integer) smaller than 27 bits. Yes, double precision will fix that (52-bit mantissas), but even TIIR methods can't solve this problem. When adding x and y, the wordlength must be on the order of at least |log2(|x|/|y|)|. The situation is not so dire with a noise input, since it should be zero mean (and if not, a dcblocker will fix it). However, the variance of integrated squared white noise does grow linearly, so TIIR methods are needed for anything long term, and double-precision allows the TIIR resets to be much farther separated, and maybe not even needed in a given application. Note, by the way (Hey Klaus!), we can simply allocate a 0.4 second delay line for the sliding mean and be done with all this recursive-filter dynamic range management. It can be a pain, but it also can be managed. That said, 0.4 seconds at 96 kHz is around 15 bits worth (log2(0.4*96000)=15.2), so single-precision seems to me like enough for a simple level meter (e.g., having a 3-digit display), given a TIIR reset every 0.4 seconds. Since this works out so neatly, I wouldn't be surprised if 0.4 seconds was chosen for the gated-measurement duration for that reason. Cheers, Julius On Fri, Jul 9, 2021 at 1:54 PM Dario Sanfilippo <sanfilippo.da...@gmail.com> wrote: > Thanks, Julius. > > So it appears that the issue I was referring to is in that architecture > too. > > To isolate the problem with ba.slidingMean, we can see that we also get 0 > when transitioning from a constant input of 1 to .001 (see code below). > Double-precision solves the issue. Perhaps we could advise using DP for > this function and the others involving it. > > Ciao, > Dario > > import("stdfaust.lib"); > lp1p(cf, x) = fi.pole(b, x * (1 - b)) > with { > b = exp(-2 * ma.PI * cf / ma.SR); > }; > sig = ba.if(ba.time > ma.SR * 2, .001, 1.0); > t = .4; > process = sig <: ba.slidingMean(t * ma.SR) , lp1p(1.0 / t) , ba.time; > > On Fri, 9 Jul 2021 at 22:40, Julius Smith <julius.sm...@gmail.com> wrote: > >> I get the zero but not the other: >> >> octave:2> format long >> octave:3> faustout(115200,:) >> ans = >> >> 0 -2.738748490000000e-02 5.555857930000000e-05 >> >> >> On Fri, Jul 9, 2021 at 1:03 PM Dario Sanfilippo < >> sanfilippo.da...@gmail.com> wrote: >> >>> Thanks, Julius. >>> >>> I don't have Octave installed, and I can't see it myself, sorry; if you >>> can inspect the generated values, can you also see if at sample #115200 >>> (48 kHz SR) you get 0 for ms_rec, and, 0.000658808684 for the lowpass? >>> >>> Yes, I might have done something wrong, but the leaky integrator doesn't >>> work well. >>> >>> Ciao, >>> Dario >>> >>> On Fri, 9 Jul 2021 at 21:49, Julius Smith <julius.sm...@gmail.com> >>> wrote: >>> >>>> Here is a longer run that shows Dario's latest test more completely. >>>> I don't think zi_leaky looks right at the end, but the other two look >>>> reasonable to me. >>>> >>>> Here is the Octave magic for the plot: >>>> >>>> plot(faustout,'linewidth',2); >>>> legend('zi','zi\_leaky','zi\_lp','location','southeast'); >>>> grid; >>>> >>>> I had to edit faust2octave to change the process duration, it's >>>> hardwired. Length option needed! (Right now no options can take an >>>> argument.) >>>> >>>> Cheers, >>>> - Julius >>>> >>>> On Fri, Jul 9, 2021 at 12:01 PM Julius Smith <julius.sm...@gmail.com> >>>> wrote: >>>> >>>>> Hi Dario, >>>>> >>>>> I tried your latest test and it looks plausible in faust2octave (see >>>>> plot attached). >>>>> >>>>> TIIR filters present a nice, juicy Faust puzzle :-) >>>>> I thought about a TIIR sliding average, but haven't implemented >>>>> anything yet. >>>>> You basically want to switch between two moving-average filters, >>>>> clearing the state of the unused one, and bringing it back to steady state >>>>> before switching it back in. >>>>> In the case of an.ms_envelope_rect, the switching period can be >>>>> anything greater than the rectangular-window length (which is the "warm up >>>>> time" of the moving-average filter). >>>>> >>>>> Cheers, >>>>> - Julius >>>>> >>>>> On Fri, Jul 9, 2021 at 10:49 AM Dario Sanfilippo < >>>>> sanfilippo.da...@gmail.com> wrote: >>>>> >>>>>> Dear Julius, I just pulled and installed Faust 2.33.0. >>>>>> >>>>>> I'm running the test below on caqt and csvplot and I see the same >>>>>> problem: when large inputs are fed in an.ms_envelope_rect, small >>>>>> inputs are truncated to zero afterwards. >>>>>> >>>>>> 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 * ba.if(ba.time > ma.SR * 2, .01, 1.0); >>>>>> process = sig <: zi , zi_leaky , zi_lp , ba.time; >>>>>> >>>>>> I'll look into TIIR filters or have you already implemented those in >>>>>> Faust? >>>>>> >>>>>> Ciao, >>>>>> Dr Dario Sanfilippo >>>>>> http://dariosanfilippo.com >>>>>> >>>>>> >>>>>> On Thu, 8 Jul 2021 at 19:19, Julius Smith <julius.sm...@gmail.com> >>>>>> 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> 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 remove the hbargraph altogether, 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 >>>>>>>> >>>>>>>> >>>>>>>> On Thu, 8 Jul 2021 at 00:39, Julius Smith <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> 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 >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> "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 >> > -- "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