There's a type on line 9: ma.ma.EPSILON. I'm afraid that that's all I can do for now.
Ciao. :-) On Tue, 10 Aug 2021 at 13:47, Klaus Scheuermann <kla...@posteo.de> wrote: > Works like a charm, thanks!! Again, I learned a lot. > My new test-file now includes audio for mono-invert, stereo-invert, > mono-half-left-invert, mono-half-right-invert: > https://cloud.4ohm.de/s/bsbAA4Jk3NBPLRD > > I included cases for corr = -1 and corr between -1 and 0. > > I also added volume compensation for corr = 1 and corr = -1. > > And hey, it works! ;) > > I would be happy if you find a minute to review. (and maybe improve) (or > comment on clumsiness) ;) > > Comments / todo: > - On the way, I lost is fading between the cases. Probably doable with > smoo'ing all corr_ cases? > - I guess volume compensation could be improved by checking the panning > when corr = 1 or corr = -1. but for now I am happy. > Klaus > > import("stdfaust.lib"); > avg(t, x) = fi.pole(p, (1 - p) * x) // 1-pole lowpass as average > with { > p = exp((((-2.0 * ma.PI) / t) / ma.SR)); > }; > var(t, x) = avg(t, (x - avg(t, x)) ^ 2); // variance > sd(t, x) = sqrt(var(t, x)); // standard deviation > cov(t, x1, x2) = avg(t, (x1 - avg(t, x1)) * (x2 - avg(t, x2))); // > covariance > corr(t, x1, x2) = cov(t, x1, x2) / max(ma.ma.EPSILON, (sd(t, x1) * sd(t, > x2))); // correlation > t = .1; // averaging period in seconds > correlate_meter(x,y) = x,y <: x , attach(y, (corr(t) : hbargraph("corr",-1 > ,1))) : _,_; > correlate_correct(t,l,r) = out_pos1, out_neg1, out_0, out_pos, out_neg :> > _,_ with { > th =.001; > corr_pos1 = avg(t, (corr(t,l,r) > (1-th))); > corr_neg1 = avg(t, corr(t,l,r) < (-1+th)); > corr_0 = avg(t, ((corr(t,l,r) < th) & (corr(t,l,r) > (0-th)))); > corr_pos = avg(t, ((corr(t,l,r) > (0+th)) & (corr(t,l,r) < (1-th)))); > corr_neg = avg(t, ((corr(t,l,r) > (-1+th)) & (corr(t,l,r) < (0-th)))); > out_pos1 = ((l * corr_pos1 + r * corr_pos1) /2) , ((l * corr_pos1 + r * > corr_pos1) /2); > out_neg1 = ((l * corr_neg1 + (-r) * corr_neg1) /2) , ((l * corr_neg1 + (-r > ) * corr_neg1) /2); > out_0 = (l * corr_0 + r * corr_0) , (l * corr_0 + r * corr_0); > out_pos = l * corr_pos , r * corr_pos; > out_neg = l * corr_neg , (0-(r * corr_neg)); > }; > process = _,_ : correlate_meter : ba.bypass2(hslider("bypass",0,0,1,1), > correlate_correct(t)); > > > On 09.08.21 18:26, Dario Sanfilippo wrote: > > Hi, Klaus. > > From the top of my head, maybe something like this: > > import("stdfaust.lib"); > avg(t, x) = fi.pole(p, (1 - p) * x) // 1-pole lowpass as average > with { > p = exp((((-2.0 * ma.PI) / t) / ma.SR)); > }; > var(t, x) = avg(t, (x - avg(t, x)) ^ 2); // variance > sd(t, x) = sqrt(var(t, x)); // standard deviation > cov(t, x1, x2) = avg(t, (x1 - avg(t, x1)) * (x2 - avg(t, x2))); // > covariance > corr(t, x1, x2) = cov(t, x1, x2) / max(ma.ma.EPSILON, (sd(t, x1) * sd(t, > x2))); // correlation > t = .1; // averaging period in seconds > correlate_meter(x,y) = x,y <: x , attach(y, (corr(t) : > hbargraph("corr",-1,1))) : _,_; > correlate_correct(t,l,r) = (l + r) * mSmoo + l * stSmoo , (l + r) * mSmoo > + r * stSmoo > with { > th = .001; > isMono = (corr(t,l,r) > (1 - th)) | ((corr(t,l,r) < th) & ((avg(t, l * l) > < th) | ((avg(t, r * r) < th)))); > mSmoo = avg(t, isMono); > stSmoo = 1.0 - mSmoo; > }; > process = _,_ : correlate_meter : correlate_correct(t); > > I think that several non-mono cases can result in a correlation that is > close to zero so I'd add another condition to check if either of the two > channels is really quiet. > > Ciao, > Dr Dario Sanfilippo > http://dariosanfilippo.com > > > On Mon, 9 Aug 2021 at 09:44, Klaus Scheuermann <kla...@posteo.de> wrote: > >> Dear Julius, dear Dario, >> >> thanks - again ! >> >> @Julius: >> ba.if(1 > corr(t,l,r) > 0 , l, (l+r)) >> >> was my clumsy way of saying 'if corr is smaller than 1 AND greater than >> 0'. Or if you turn it around 'if corr ==0 OR corr ==1'. What would be the >> most elegant way to do this in faust? >> You are right about the L == -R case... I did not look into out-of-phase >> cases yet. Probably then the condition should be 'if corr nears -1 OR 0 OR >> 1', right? >> >> @Dario, the code works very nicely and the smoothing sounds delicious ;) >> By explaining my clumsy ba.if statement, you will understand, that I'd >> like mono-left and mono-right (which result in corr=0) to be centered, too. >> If corr nears 0 or 1, the result should be in the center. Same question: >> how to do an elegant OR condition? >> >> Another thing I was thinking about is, if it makes more sense to convert >> the stereo signal to M-S and regulate the S channel for mono or stereo. But >> it's probably the same result as smoothing between l+r,l+r and l,r. >> >> Cheers, >> Klaus >> >> On 09.08.21 00:56, Dario Sanfilippo wrote: >> >> Hi, Klaus; nice to hear from you, Julius. :) >> >> As Julius points out, I also think that you'd need less demanding >> thresholds: even for identical channels, the average using a one-pole lp >> will oscillate and it might not be reliable if checking against the corner >> case. >> >> I'd go with something like this, but Julius also has a point about >> phase-inverted mono signals. Also, you may want to normalise when you sum L >> and R. It was necessary to guard against division by 0 too. I've included a >> smoother to avoid clicks when switching. >> >> I've tested that with your audio example and it's all mono except mono-left, >> mono-right, and stereo. Is that correct? >> >> import("stdfaust.lib"); >> avg(t, x) = fi.pole(p, (1 - p) * x) // 1-pole lowpass as average >> with { >> p = exp((((-2.0 * ma.PI) / t) / ma.SR)); >> }; >> var(t, x) = avg(t, (x - avg(t, x)) ^ 2); // variance >> sd(t, x) = sqrt(var(t, x)); // standard deviation >> cov(t, x1, x2) = avg(t, (x1 - avg(t, x1)) * (x2 - avg(t, x2))); // >> covariance >> corr(t, x1, x2) = cov(t, x1, x2) / max(ma.ma.EPSILON, (sd(t, x1) * sd(t, >> x2))); // correlation >> t = .5; // averaging period in seconds >> correlate_meter(x,y) = x,y <: x , attach(y, (corr(t) : >> hbargraph("corr",-1,1))) : _,_; >> correlate_correct(t,l,r) = (l + r) * mSmoo + l * stSmoo , (l + r) * >> mSmoo + r * stSmoo >> with { >> isMono = corr(t,l,r) > .999; >> mSmoo = avg(.05, isMono); >> stSmoo = 1.0 - mSmoo; >> }; >> process = _,_ : correlate_meter : correlate_correct(t); >> >> Ciao, >> Dr Dario Sanfilippo >> http://dariosanfilippo.com >> >> >> On Mon, 9 Aug 2021 at 00:25, Julius Smith <julius.sm...@gmail.com> wrote: >> >>> And of course I mean "cross-correlation coefficient" >>> >>> On Sun, Aug 8, 2021 at 3:22 PM Julius Smith <julius.sm...@gmail.com> >>> wrote: >>> >>>> Hi Klaus, >>>> >>>> I am late to this (just read some of the thread with interest), and I >>>> have a question: what do you mean by "1 > corr(t,l,r) > 0" ? It appears to >>>> be "parsed" left to right, so that the 2nd ">" only sees "1>0" most (all?) >>>> of the time, which is always true (1) of course (so no "else" activated). >>>> Maybe you want something like "abs(corr(t,l,r)) > 0.95" ? (i.e., 95% >>>> correlation deemed to be "panned mono"). I'm taking the absolute value >>>> because I assume you don't care if the left channel is merely the negative >>>> of the right (unless that's an accepted cheezy "stereoizer" of sorts). >>>> >>>> FYI, this is what we call a time-domain "normalized cross-correlation" >>>> or "correlation coefficient" measurement (official buzzwords) >>>> >>>> Cheers, >>>> Julius >>>> >>>> >>>> On Sun, Aug 8, 2021 at 10:07 AM Klaus Scheuermann <kla...@posteo.de> >>>> wrote: >>>> >>>>> Dear Dario, >>>>> >>>>> cool, your corr function gives me the desired results. At least when >>>>> feeding it to a meter. >>>>> >>>>> Here is my test audio which contains vocals in mono-mid, mono-left, >>>>> mono-right, mono-half-left, mono-half-right, stereo: >>>>> https://cloud.4ohm.de/s/y9oZzqFGyrZT5ej >>>>> For mono-mid, mono-half-left, mono-half-right it shows 1. >>>>> For mono-left, mono-right it shows 0. >>>>> For stereo it shows values between 0 and 1. >>>>> >>>>> I would like to detect mono signals that are not exactly in the middle >>>>> and put them there. Stereo signals should be unchanged. >>>>> >>>>> My code is here, but for some reason it does not work correctly. >>>>> Especially when corr shows 0, ba.if does not go to the else-path. >>>>> >>>>> import("stdfaust.lib"); >>>>> avg(t, x) = fi.pole(p, (1 - p) * x) // 1-pole lowpass as average >>>>> with { >>>>> p = exp((((-2.0 * ma.PI) / t) / ma.SR)); >>>>> }; >>>>> var(t, x) = avg(t, (x - avg(t, x)) ^ 2); // variance >>>>> sd(t, x) = sqrt(var(t, x)); // standard deviation >>>>> cov(t, x1, x2) = avg(t, (x1 - avg(t, x1)) * (x2 - avg(t, x2))); // >>>>> covariance >>>>> corr(t, x1, x2) = cov(t, x1, x2) / (sd(t, x1) * sd(t, x2)) : _ ; // >>>>> correlation >>>>> t = 0.5; // averaging period in seconds >>>>> correlate_meter(x,y) = x,y <: x , attach(y, (corr(t) : hbargraph( >>>>> "corr",-1,1))) : _,_; >>>>> correlate_correct(t,l,r) = ba.if(1 > corr(t,l,r) > 0 , l, (l+r)) , >>>>> ba.if(1 > corr(t,l,r) > 0 , r, (l+r)); >>>>> process = _,_ : correlate_meter : correlate_correct(t); >>>>> >>>>> Am I doing the ba.if wrong? >>>>> >>>>> Thank s very much, >>>>> Klaus >>>>> >>>>> >>>>> On 04.08.21 18:25, Dario Sanfilippo wrote: >>>>> >>>>> I had implemented a few statistics function a while back, kindly taken >>>>> from Wikipedia, and they seem to produce the expected values mentioned on >>>>> the webpage. I hope that these can be useful. >>>>> >>>>> Ciao, >>>>> Dr Dario Sanfilippo >>>>> http://dariosanfilippo.com >>>>> >>>>> import("stdfaust.lib"); >>>>> avg(t, x) = fi.pole(p, (1 - p) * x) // 1-pole lowpass as average >>>>> with { >>>>> p = exp((((-2.0 * ma.PI) / t) / ma.SR)); >>>>> }; >>>>> var(t, x) = avg(t, (x - avg(t, x)) ^ 2); // variance >>>>> sd(t, x) = sqrt(var(t, x)); // standard deviation >>>>> cov(t, x1, x2) = avg(t, (x1 - avg(t, x1)) * (x2 - avg(t, x2))); // >>>>> covariance >>>>> corr(t, x1, x2) = cov(t, x1, x2) / (sd(t, x1) * sd(t, x2)); // >>>>> correlation >>>>> ph0 = os.phasor(2.0 * ma.PI, 200); >>>>> red = sin(ph0) + .35 * sin(ph0 * 3.0) + .91 * sin(ph0 * 5.0); >>>>> blue = sin(ph0) + .5 * sin(ph0 * 3.0) - .5 * sin(ph0 * 5.0); >>>>> red1 = sin(ph0) + sin(ph0 * 3.0); >>>>> blue1 = sin(ph0) - sin(ph0 * 3.0) / 3.0; >>>>> t = 1.0; // averaging period in seconds >>>>> process = (red , blue : corr(t)) , (red1 , blue1 : corr(t)); >>>>> >>>>> >>>>> >>>>> On Wed, 4 Aug 2021 at 16:52, Klaus Scheuermann <kla...@posteo.de> >>>>> wrote: >>>>> >>>>>> Thanks Giuseppe, >>>>>> >>>>>> I checked it out, but somehow it still does not give me the desired >>>>>> result... >>>>>> I did some more research and found this, which indicates that it can >>>>>> be done with arctan more easily. >>>>>> >>>>>> The way this is done on phase (correlation) meters in audio equipment >>>>>> is rather simple: >>>>>> >>>>>> Phase = arctan(L/R) >>>>>> >>>>>> With phase of 45 or 225 = 1, and phase of 135 and 315 (-45) is -1. >>>>>> >>>>>> Essentially, the Y Axis is the L, and the X axis is the R. The phase >>>>>> is simply the polar angle of the vector between the two. >>>>>> >>>>>> This type of meters will show 1 if the signal is mono, and -1 if the >>>>>> left and right are perfectly phase inverted. >>>>>> >>>>>> Notice however, that phase meters of this type also account for the >>>>>> magnitude in the polar coordinates. So: >>>>>> >>>>>> Magnitude = (L^2 + R^2)^1/2 >>>>>> >>>>>> Thus the actual meter display is a normalised version of: >>>>>> >>>>>> Correlation = Phase * Magnitude >>>>>> >>>>>> I'm not sure that satisfies your requirements, but this answers the >>>>>> question in the subject. >>>>>> >>>>>> So I transfered this to faust, but it still behaves weired... >>>>>> import("stdfaust.lib"); >>>>>> phase(l,r) = (l/r) : aa.arctan; >>>>>> magnitude(l,r) = (l^2 + r^2)^1/2; >>>>>> correlate(l,r) = phase(l,r) * magnitude(l,r); >>>>>> correlate_meter(x,y) = x,y <: x , attach(y, (correlate : hbargraph( >>>>>> "corr",-1,1))) : _,_; >>>>>> process = _,_ : correlate_meter: _,_; >>>>>> >>>>>> Any ideas? >>>>>> >>>>>> Klaus >>>>>> >>>>>> On 03.08.21 14:48, Giuseppe Silvi wrote: >>>>>> >>>>>> Hi Klaus, >>>>>> The filters are necessary to obtain a -1 +1 range, I think. >>>>>> >>>>>> import("stdfaust.lib"); >>>>>> >>>>>> correlate(l,r) = l*l ,r*r , l*r : par(i,3, si.smooth(0.9)) : sqrt, sqrt, >>>>>> _ : *,_ : /; >>>>>> correlate_meter(x,y) = x,y <: x , attach(y, (correlate : >>>>>> hbargraph("corr”,-1,1))); >>>>>> >>>>>> process = correlate_meter; >>>>>> >>>>>> Try playing with the si.smooth coefficient. >>>>>> >>>>>> best, >>>>>> giuseppe >>>>>> >>>>>> >>>>>> On 3 Aug 2021, at 14:09, Klaus Scheuermann <kla...@posteo.de> >>>>>> <kla...@posteo.de> wrote: >>>>>> >>>>>> Could it be something like this? >>>>>> >>>>>> (according to the 'correct' algorithm in >>>>>> https://www.beis.de/Elektronik/Correlation/CorrelationCorrectAndWrong.html >>>>>> ) >>>>>> import("stdfaust.lib"); >>>>>> >>>>>> correlate(l,r) = l*l ,r*r , l*r : sqrt, sqrt, _ : *,_ : / :_; >>>>>> correlate_meter(x,y) = x,y <: x , attach(y, (correlate : >>>>>> hbargraph("corr",-1,1))) : _,_; >>>>>> >>>>>> process = _,_ : correlate_meter: _,_; >>>>>> >>>>>> I am not sure about the lowpass filters though. Maybe not needed in the >>>>>> digital domain? >>>>>> >>>>>> Also, my code only returns -1 or 1 while it should be returning a range >>>>>> of -1 and 1, right? >>>>>> >>>>>> The correlation is either expressed in % from -100% to +100% or as the >>>>>> correlation factor, which ranges from -1 to +1. Note that due to the >>>>>> correlation algorithm the level of both signals does not matter, i.e., >>>>>> it does not influence the measured result. >>>>>> >>>>>> When a mono source is used for a stereo signal both stereo channels will >>>>>> be +100% correlated. When e.g. in a stereo signal both channels contain >>>>>> completely different signals, e.g. left (and only left) is the trumpet >>>>>> and right (and only right) is the guitar these stereo channels will be >>>>>> 0% correlated. With a third instrument appearing in both channels, the >>>>>> correlation will be somewhere between 0 and +100%. >>>>>> >>>>>> >>>>>> Ideas? >>>>>> Danke :) >>>>>> Klaus >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On 03.08.21 12:48, Klaus Scheuermann wrote: >>>>>> >>>>>> Hello List, >>>>>> >>>>>> I just wondered, if anyone has implemented a stereo audio correlation >>>>>> meter/analyser in faust? >>>>>> >>>>>> If yes - great! >>>>>> If no - I have another project :) >>>>>> >>>>>> Here is what I found about the algorithm(s): >>>>>> https://www.beis.de/Elektronik/Correlation/CorrelationCorrectAndWrong.html >>>>>> >>>>>> >>>>>> I never learned analog electronic schematics, but it seems it should not >>>>>> be extremely hard to transfer to faust. >>>>>> >>>>>> Cheers, Klaus >>>>>> >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> Faudiostream-users mailing list >>>>>> Faudiostream-users@lists.sourceforge.nethttps://lists.sourceforge.net/lists/listinfo/faudiostream-users >>>>>> >>>>>> _______________________________________________ >>>>>> Faudiostream-users mailing >>>>>> listFaudiostream-users@lists.sourceforge.nethttps://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 >>>>> >>>> >>>> >>>> -- >>>> "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