Actually, the pattern we want kicks in at durSamples = 32 (circular-buffer delay line).
On Sat, Jul 10, 2021 at 10:53 AM Julius Smith <julius.sm...@gmail.com> wrote: > > I'm not sure I understand what you mean by allocating a delay line for > the sliding mean, but I'll look into it. > > Here's an example implementation in Faust. The "small test" allocates a > length 8 delay line. > The full test takes too long to compile, but you can see the pattern, so > it's easy to just write it. > > import("stdfaust.lib"); > > // Small test: > durSamples = 8; > DUR_SAMPLES_MAX = durSamples*2; > > // What we really need (but takes a LONG time to compile): > // DUR_SAMPLES_MAX = 2^16; > // durSamples = int(0.5 + 0.4 * ma.SR); > > sliding_mean(durSamples) = _ <: > par(i,DUR_SAMPLES_MAX,ba.if(i<durSamples,@(i),0)) :> /(durSamples); > > process = sliding_mean(durSamples); > > On Sat, Jul 10, 2021 at 1:12 AM Dario Sanfilippo < > sanfilippo.da...@gmail.com> wrote: > >> Dear Julius, thanks for putting it nicely. :) >> >> I'm not sure I understand what you mean by allocating a delay line for >> the sliding mean, but I'll look into it. >> >> A quick improvement to the slidingMean function could be to put the >> integrator after the difference. With a sliding window of .4 sec at 48 kHz, >> we should have about 60 dBs of dynamic range when feeding a full-amp >> constant. It should be even better with close-to-zero-mean signals. >> >> import("stdfaust.lib"); >> slidingSum(n) = _ <: _, _@int(max(0,n)) : - : fi.pole(1); >> slidingMean(n) = slidingSum(n)/rint(n); >> t=.4; >> process = ba.if(ba.time < ma.SR * 1, 1.0, .001) <: slidingMean(t*ma.SR) , >> ba.slidingMean(t*ma.SR) : ba.linear2db , ba.linear2db; >> >> Ciao, >> Dr Dario Sanfilippo >> http://dariosanfilippo.com >> >> >> On Sat, 10 Jul 2021 at 00:27, Julius Smith <julius.sm...@gmail.com> >> wrote: >> >>> 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 >>> >> > > -- > "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