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

Reply via email to