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