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 <[email protected]
> <mailto:[email protected]>> wrote:
>
> And of course I mean "cross-correlation coefficient"
>
> On Sun, Aug 8, 2021 at 3:22 PM Julius Smith
> <[email protected] <mailto:[email protected]>> 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
> <[email protected] <mailto:[email protected]>> 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
>> <[email protected] <mailto:[email protected]>> 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
>>>> <[email protected]> <mailto:[email protected]> 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
>>>>>
>>>>> [email protected]
>>>>> <mailto:[email protected]>
>>>>>
>>>>> https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>>>>> <https://lists.sourceforge.net/lists/listinfo/faudiostream-users>
>>>> _______________________________________________
>>>> Faudiostream-users mailing list
>>>> [email protected]
>>>> <mailto:[email protected]>
>>>>
>>>> https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>>>> <https://lists.sourceforge.net/lists/listinfo/faudiostream-users>
>> _______________________________________________
>> Faudiostream-users mailing list
>> [email protected]
>> <mailto:[email protected]>
>>
>> https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>>
>> <https://lists.sourceforge.net/lists/listinfo/faudiostream-users>
>>
> _______________________________________________
> Faudiostream-users mailing list
> [email protected]
> <mailto:[email protected]>
> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/faudiostream-users