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 <http://dariosanfilippo.com> > > > On Mon, 9 Aug 2021 at 00:25, Julius Smith <julius.sm...@gmail.com > <mailto: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 <mailto: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 <mailto: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 > <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 <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 <mailto: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> <mailto:kla...@posteo.de> wrote: >>>> >>>> Could it be something like this? >>>> >>>> (according to the 'correct' algorithm in >>>> https://www.beis.de/Elektronik/Correlation/CorrelationCorrectAndWrong.html >>>> <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 >>>>> >>>>> <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.net >>>>> <mailto:Faudiostream-users@lists.sourceforge.net> >>>>> >>>>> https://lists.sourceforge.net/lists/listinfo/faudiostream-users >>>>> <https://lists.sourceforge.net/lists/listinfo/faudiostream-users> >>>> _______________________________________________ >>>> Faudiostream-users mailing list >>>> 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> >> _______________________________________________ >> Faudiostream-users mailing list >> 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> >> > _______________________________________________ > Faudiostream-users mailing list > 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> > > > > -- > "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