« 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> >>>>>>>>>>>> <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 >>>>>>>>>>>> <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>>> >>>>>>>>>>>>>>> <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>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> <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>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>> <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 >>> 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 > _______________________________________________ > 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