Is there a way to get the extremum of the cross-correlation of two
signals in real-time? Dan had a solution in an old thread in 2009, but claimed it did not work (see below). Then there was another approach in an attachment but the list no longer has the attachment. Any help will be much appreciated. Thanks, Mike ~maxcorr = { |sig1, sig2| var ch1, ch2, buf1, buf2; buf1 = LocalBuf(2048); buf2 = LocalBuf(2048); ch1 = FFT(buf1, sig1, wintype: 1); ch2 = FFT(buf2, sig2, wintype: 1); ch2 = PV_Conj(ch2); ch1 = PV_Mul(ch1, ch2); IFFT(ch1); // ignore the result, but hope it comes before BufMax in the synth graph! BufMax.kr(buf1, ch1 >= 0); } _______________________________________________ sc-users mailing list info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
If you are happy with plain old time-domain correlation (i.e. the "maximal" part is optional, you can avoid the usual spectral domain frustrations by using plain old multiplication. Here's an example:
SynthDef.new(\corr, {|bus1, bus2, resultbus, rate=40| var sig1amp, sig2amp, sig1=In.ar(bus1), sig2=In.ar(bus2); sig1amp = A2K.kr( OpLPF.ar( sig1.squared, rate, iter: 4 ) ); sig2amp = A2K.kr( OpLPF.ar( sig2.squared, rate, iter: 4 ) ); Out.kr(resultbus, A2K.kr( OpLPF.ar( sig1*sig2, rate, iter: 4 ) )/((sig1amp*sig2amp).sqrt.max(0.00001))); }).add; ~outsame = Bus.control; ~outdiff = Bus.control; ~twoHundred={Out.ar(0,SinOsc.ar(200, mul: 0.2))}.play; ~threeHundred={Out.ar(1,SinOsc.ar(300, mul: 0.2))}.play; ~corrsame = Synth.new(\corr, [\bus1, 0, \bus2, 0, \resultbus, ~outsame], addAction:\addToTail); ~corrdiff = Synth.new(\corr, [\bus1, 0, \bus2, 1, \resultbus, ~outdiff], addAction:\addToTail); //results available here: ~outsame.get; ~outdiff.get; NB, that uses a Pseudo-Ugen that I cribbed from the mailing list because sometime you want non-resonant filters with cutoff frequencies. See below. -Dan (Not the dan you referred to in your last mail) ------ // http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Calculating-OnePole-coefficient-for-one-pole-LP-HP-filter-td4034000.html //see also http://www.dspguide.com/ //One pole LPF with freq input (instead of coef) //Thanks to Volker B�hm for the (freq -> coef) conversion formula. //And Batuhan Bozkurt for initial pseudo ugen //takes an "iter" param telling you how many times to apply the filter OpLPF { *kr {|in, freq=100, iter=1| var coef = exp(-2*pi * (freq * ControlDur.ir)); iter.do({in=OnePole.kr(in, coef);}); ^in; } *ar {|in, freq=100, iter=1| var coef = exp(-2*pi * (freq * SampleDur.ir)); iter.do({in=OnePole.ar(in, coef);}); ^in; } } |
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Thanks Dan, I have not had a chance to run this, but by looking at it. This is a correlation of two lists, but does not do the cross-correlation, where the correlation is taken at a set of time-lags. I think doing that and then finding the maximum of the time-lagged correlations is the part that is difficult to do in real-time. Please correct me if I am missing something. - -Mike On 02/16/2015 08:10 AM, parking-sun wrote: > If you are happy with plain old time-domain correlation (i.e. the "maximal" > part is optional, you can avoid the usual spectral domain frustrations by > using plain old multiplication. Here's an example: > > > SynthDef.new(\corr, {|bus1, bus2, resultbus, rate=40| > var sig1amp, sig2amp, sig1=In.ar(bus1), sig2=In.ar(bus2); > sig1amp = A2K.kr( > OpLPF.ar( > sig1.squared, > rate, > iter: 4 > ) > ); > sig2amp = A2K.kr( > OpLPF.ar( > sig2.squared, > rate, > iter: 4 > ) > ); > Out.kr(resultbus, > A2K.kr( > OpLPF.ar( > sig1*sig2, > rate, > iter: 4 > ) > )/((sig1amp*sig2amp).sqrt.max(0.00001))); > }).add; > > ~outsame = Bus.control; > ~outdiff = Bus.control; > ~twoHundred={Out.ar(0,SinOsc.ar(200, mul: 0.2))}.play; > ~threeHundred={Out.ar(1,SinOsc.ar(300, mul: 0.2))}.play; > ~corrsame = Synth.new(\corr, [\bus1, 0, \bus2, 0, \resultbus, ~outsame], > addAction:\addToTail); > ~corrdiff = Synth.new(\corr, [\bus1, 0, \bus2, 1, \resultbus, ~outdiff], > addAction:\addToTail); > //results available here: > ~outsame.get; > ~outdiff.get; > > > NB, that uses a Pseudo-Ugen that I cribbed from the mailing list because > sometime you want non-resonant filters with cutoff frequencies. See below. > > -Dan (Not the dan you referred to in your last mail) > > > > ------ > // > > //see also http://www.dspguide.com/ > //One pole LPF with freq input (instead of coef) > //Thanks to Volker B�hm for the (freq -> coef) conversion formula. > //And Batuhan Bozkurt for initial pseudo ugen > //takes an "iter" param telling you how many times to apply the filter > OpLPF { > *kr {|in, freq=100, iter=1| > var coef = exp(-2*pi * (freq * ControlDur.ir)); > iter.do({in=OnePole.kr(in, coef);}); > ^in; > } > *ar {|in, freq=100, iter=1| > var coef = exp(-2*pi * (freq * SampleDur.ir)); > iter.do({in=OnePole.ar(in, coef);}); > ^in; > } > } > > > > > -- > View this message in context: > Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com. > > _______________________________________________ > sc-users mailing list > > info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml > archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ > search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJU4iFMAAoJENzaHFeuRhTRtkMIAJPKpJhxieeSg63cv9LfVU3h HAz9ypM1SM4N+G9O/UvInlFP71hcjODm7kS0Mjvu9bcykzdsvwHS4qZzHkdJ9CjF btoC5u675mHcOAcnYPZH4/6mS22jvNpCny8UWkrtDfEWwoMqZZv9w6oqFEK/GyKI GXVf39oNi7RbD1xnXjUFvdFlhnfFUL0ye2Hh6e2Zf1KYcfHt9Q6mfJh8Bke0vu3Q Z626uoad9GDT/VjZUu0pOeR/GrkR5aIm0OCKOve7bnIKj68LDMjopctGSXfZp7B1 vzmOIQAAu70/COdpjG9k9CgHpRsWimM8Ry25ueig8CNF2FxTzCmBEvdT9fKJipo= =nxGJ -----END PGP SIGNATURE----- _______________________________________________ sc-users mailing list info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
The Pitch Ugen (in DelayUGens.cpp I believe) has
a nice implementation of real-time peak-tracking in an AUTO-correlation function. It would be straightforward to adapt that to a real-time cross-correlation tracker (for continuous inter-channel time-delay estimation etc.). - Julius At 08:56 AM 2/16/2015, Michael Winter wrote: >-----BEGIN PGP SIGNED MESSAGE----- >Hash: SHA1 > >Thanks Dan, > >I have not had a chance to run this, but by looking at it. This is a >correlation of two lists, but does not do the cross-correlation, where >the correlation is taken at a set of time-lags. I think doing that and >then finding the maximum of the time-lagged correlations is the part >that is difficult to do in real-time. Please correct me if I am missing >something. > >- -Mike > >On 02/16/2015 08:10 AM, parking-sun wrote: > > If you are happy with plain old time-domain correlation (i.e. the "maximal" > > part is optional, you can avoid the usual spectral domain frustrations by > > using plain old multiplication. Here's an example: > > > > > > SynthDef.new(\corr, {|bus1, bus2, resultbus, rate=40| > > var sig1amp, sig2amp, sig1=In.ar(bus1), sig2=In.ar(bus2); > > sig1amp = A2K.kr( > > OpLPF.ar( > > sig1.squared, > > rate, > > iter: 4 > > ) > > ); > > sig2amp = A2K.kr( > > OpLPF.ar( > > sig2.squared, > > rate, > > iter: 4 > > ) > > ); > > Out.kr(resultbus, > > A2K.kr( > > OpLPF.ar( > > sig1*sig2, > > rate, > > iter: 4 > > ) > > )/((sig1amp*sig2amp).sqrt.max(0.00001))); > > }).add; > > > > ~outsame = Bus.control; > > ~outdiff = Bus.control; > > ~twoHundred={Out.ar(0,SinOsc.ar(200, mul: 0.2))}.play; > > ~threeHundred={Out.ar(1,SinOsc.ar(300, mul: 0.2))}.play; > > ~corrsame = Synth.new(\corr, [\bus1, 0, \bus2, 0, \resultbus, ~outsame], > > addAction:\addToTail); > > ~corrdiff = Synth.new(\corr, [\bus1, 0, \bus2, 1, \resultbus, ~outdiff], > > addAction:\addToTail); > > //results available here: > > ~outsame.get; > > ~outdiff.get; > > > > > > NB, that uses a Pseudo-Ugen that I cribbed from the mailing list because > > sometime you want non-resonant filters with cutoff frequencies. See below. > > > > -Dan (Not the dan you referred to in your last mail) > > > > > > > > ------ > > // > > >http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Calculating-OnePole-coefficient-for-one-pole-LP-HP-filter-td4034000.html > > //see also http://www.dspguide.com/ > > //One pole LPF with freq input (instead of coef) > > //Thanks to Volker Bï¿½hm for the (freq -> coef) conversion formula. > > //And Batuhan Bozkurt for initial pseudo ugen > > //takes an "iter" param telling you how many times to apply the filter > > OpLPF { > > *kr {|in, freq=100, iter=1| > > var coef = exp(-2*pi * (freq * ControlDur.ir)); > > iter.do({in=OnePole.kr(in, coef);}); > > ^in; > > } > > *ar {|in, freq=100, iter=1| > > var coef = exp(-2*pi * (freq * SampleDur.ir)); > > iter.do({in=OnePole.ar(in, coef);}); > > ^in; > > } > > } > > > > > > > > > > -- > > View this message in context: >http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Extremum-of-Cross-Correlation-tp7616151p7616189.html > > Sent from the SuperCollider Users New (Use this!!!!) mailing list >archive at Nabble.com. > > > > _______________________________________________ > > sc-users mailing list > > > > info (subscription, etc.): >http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml > > archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ > > search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ > >-----BEGIN PGP SIGNATURE----- >Version: GnuPG v1 > >iQEcBAEBAgAGBQJU4iFMAAoJENzaHFeuRhTRtkMIAJPKpJhxieeSg63cv9LfVU3h >HAz9ypM1SM4N+G9O/UvInlFP71hcjODm7kS0Mjvu9bcykzdsvwHS4qZzHkdJ9CjF >btoC5u675mHcOAcnYPZH4/6mS22jvNpCny8UWkrtDfEWwoMqZZv9w6oqFEK/GyKI >GXVf39oNi7RbD1xnXjUFvdFlhnfFUL0ye2Hh6e2Zf1KYcfHt9Q6mfJh8Bke0vu3Q >Z626uoad9GDT/VjZUu0pOeR/GrkR5aIm0OCKOve7bnIKj68LDMjopctGSXfZp7B1 >vzmOIQAAu70/COdpjG9k9CgHpRsWimM8Ry25ueig8CNF2FxTzCmBEvdT9fKJipo= >=nxGJ >-----END PGP SIGNATURE----- > > >_______________________________________________ >sc-users mailing list > >info (subscription, etc.): >http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml >archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ >search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ Julius O. Smith III <[hidden email]> Professor of Music and, by courtesy, Electrical Engineering CCRMA, Stanford University http://ccrma.stanford.edu/~jos/ _______________________________________________ sc-users mailing list info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
Thanks Julius. I was starting to think that this would have to be
done at a lower lever. I will see if I can give it a try once time
permits.
-Mike On 02/16/2015 02:02 PM, Julius Smith wrote: > The Pitch Ugen (in DelayUGens.cpp I believe) has a nice implementation of real-time peak-tracking in an AUTO-correlation function. It would be straightforward to adapt that to a real-time cross-correlation tracker (for continuous inter-channel time-delay estimation etc.). > > - Julius > > At 08:56 AM 2/16/2015, Michael Winter wrote: > Thanks Dan,>> >> >> _______________________________________________ >> sc-users mailing list >> >> info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml >> archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ >> search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ > > > Julius O. Smith III [hidden email] > Professor of Music and, by courtesy, Electrical Engineering > CCRMA, Stanford University > http://ccrma.stanford.edu/~jos/ > > _______________________________________________ > sc-users mailing list > > info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml > archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ > search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
In reply to this post by Julius Smith
Actually, going back to (the other) Dan's idea. Shouldn't this be
correct?:
( a = Buffer.alloc(s, 2048, 1); b = Buffer.alloc(s, 2048, 1); SynthDef(\xcorr, {|f1 = 440 f2 = 440| var ch1, ch2, trig, max; ch1 = FFT(a, SinOsc.ar(f1), wintype: 1); ch2 = FFT(b, SinOsc.ar(f2), wintype: 1); ch2 = PV_Conj(ch2); ch1 = PV_Mul(ch1, ch2); IFFT(ch1); trig = Impulse.kr(44100.0/2048.0); max = Latch.ar(RunningMax.ar(PlayBuf.ar(1, a, loop: 1), trig), trig); Poll.kr(trig, max, \max); }).send(s); ) x = Synth(\xcorr, [\f1, 440, \f2, 440]); x.set(\f2, 800); x.free; a.plot(\a, Rect(200, 430, 700, 300)); On 02/16/2015 02:02 PM, Julius Smith wrote: > The Pitch Ugen (in DelayUGens.cpp I believe) has a nice implementation of real-time peak-tracking in an AUTO-correlation function. It would be straightforward to adapt that to a real-time cross-correlation tracker (for continuous inter-channel time-delay estimation etc.). > > - Julius > > At 08:56 AM 2/16/2015, Michael Winter wrote: > Thanks Dan,>> >> >> _______________________________________________ >> sc-users mailing list >> >> info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml >> archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ >> search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ > > > Julius O. Smith III [hidden email] > Professor of Music and, by courtesy, Electrical Engineering > CCRMA, Stanford University > http://ccrma.stanford.edu/~jos/ > > _______________________________________________ > sc-users mailing list > > info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml > archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ > search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
Wow, Julius, I hadn't noticed the Pitch ugen used autocorrelation. That's neat.
Mike, if you wanted to do an n-sample lagged correlation with my version, you would insert an n-sample delay in one of the inputs. If you were going to do many different possible delays it could become computationally inefficient, but how many such delays you wanted would depend on your goal. But with regard to implementation difficulty... not much can be easier than inserting a single Ugen. If modesty prevents Julius from recommending it himself, may I recommend his excellent online book https://ccrma.stanford.edu/~jos/st/Cross_Correlation.html for getting the terminology right here, with regard to "cross correlation", "cross spectrum" (which I think is what you are actually after?) etc. It might clarify the goals a little... -Dan <quote author="Michael Winter"> On 02/16/2015 02:02 PM, Julius Smith wrote: > The Pitch Ugen (in DelayUGens.cpp I believe) has a nice implementation of real-time peak-tracking in an AUTO-correlation function. It would be straightforward to adapt that to a real-time cross-correlation tracker (for continuous inter-channel time-delay estimation etc.). ... > Thanks Dan, > > I have not had a chance to run this, but by looking at it. This is a > correlation of two lists, but does not do the cross-correlation, where > the correlation is taken at a set of time-lags. I think doing that and > then finding the maximum of the time-lagged correlations is the part > that is difficult to do in real-time. Please correct me if I am missing > something. > > -Mike > |
Thanks Dan,
I am aware of Julius's online book and indeed reference it all the time! It is an invaluable resource. At this point, I am not sure what is better for my purposes: cross-correlation in the time domain or in the frequency domain (what Julius refers to as "cross spectrum"). The other Dan's version is the latter and can be done rather efficiently (if I did get it working correctly - see my last post). So I am inclined to do that. As you point out, a cross-correlation in the time domain with small n-sample lags might be inefficient. And then there is computing the extremum, which is what I think I was able to tweak in the other Dan's version. More soon Best, Mike On 02/17/2015 04:19 AM, parking-sun wrote: > Wow, Julius, I hadn't noticed the Pitch ugen used autocorrelation. That's > neat. > > Mike, if you wanted to do an n-sample lagged correlation with my version, > you would insert an n-sample delay in one of the inputs. If you were going > to do /many/ different possible delays it could become computationally > inefficient, but how many such delays you wanted would depend on your goal. > But with regard to implementation difficulty... not much can be easier than > inserting a single Ugen. > > If modesty prevents Julius from recommending it himself, may /I/ recommend > his excellent online book > https://ccrma.stanford.edu/~jos/st/Cross_Correlation.html > for getting the terminology right here, with regard to "cross correlation", > "cross spectrum" (which I think is what you are actually after?) etc. It > might clarify the goals a little... > > -Dan > > > On 02/16/2015 02:02 PM, Julius Smith wrote: >> The Pitch Ugen (in DelayUGens.cpp I believe) has a nice implementation of >> real-time > peak-tracking in an AUTO-correlation function. It would be > straightforward to adapt that to a real-time cross-correlation tracker > (for continuous inter-channel time-delay estimation etc.). > ... >> Thanks Dan, >> >> I have not had a chance to run this, but by looking at it. This is a >> correlation of two lists, but does not do the cross-correlation, where >> the correlation is taken at a set of time-lags. I think doing that and >> then finding the maximum of the time-lagged correlations is the part >> that is difficult to do in real-time. Please correct me if I am missing >> something. >> >> -Mike >> > > > -- > View this message in context: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Extremum-of-Cross-Correlation-tp7616151p7616205.html > Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com. > > _______________________________________________ > sc-users mailing list > > info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml > archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ > search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ _______________________________________________ sc-users mailing list info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
In reply to this post by mwinter
That looks good! I would test it with WhiteNoise
in buffer a and the same noise delayed by N samples in buffer b. Then you expect the max to be N samples greater than its value when N is 0. - Julius At 06:01 PM 2/16/2015, Michael Winter wrote: >Actually, going back to (the other) Dan's idea. Shouldn't this be correct?: > >( >a = Buffer.alloc(s, 2048, 1); >b = Buffer.alloc(s, 2048, 1); > >SynthDef(\xcorr, {|f1 = 440 f2 = 440| > var ch1, ch2, trig, max; > ch1 = FFT(a, SinOsc.ar(f1), wintype: 1); > ch2 = FFT(b, SinOsc.ar(f2), wintype: 1); > ch2 = PV_Conj(ch2); > ch1 = PV_Mul(ch1, ch2); > IFFT(ch1); > trig = Impulse.kr(44100.0/2048.0); > max = Latch.ar(RunningMax.ar(PlayBuf.ar(1, a, loop: 1), trig), trig); > Poll.kr(trig, max, \max); >}).send(s); >) > >x = Synth(\xcorr, [\f1, 440, \f2, 440]); >x.set(\f2, 800); >x.free; > >a.plot(\a, Rect(200, 430, 700, 300)); > >On 02/16/2015 02:02 PM, Julius Smith wrote: > > The Pitch Ugen (in DelayUGens.cpp I believe) > has a nice implementation of real-time > peak-tracking in an AUTO-correlation > function. It would be straightforward to adapt > that to a real-time cross-correlation tracker > (for continuous inter-channel time-delay estimation etc.). > > > > - Julius > > > > At 08:56 AM 2/16/2015, Michael Winter wrote: > > >>Thanks Dan, >> >>I have not had a chance to run this, but by looking at it. This is a >>correlation of two lists, but does not do the cross-correlation, where >>the correlation is taken at a set of time-lags. I think doing that and >>then finding the maximum of the time-lagged correlations is the part >>that is difficult to do in real-time. Please correct me if I am missing >>something. >> >>-Mike >> >>On 02/16/2015 08:10 AM, parking-sun wrote: >> > If you are happy with plain old time-domain >> correlation (i.e. the "maximal" >> > part is optional, you can avoid the usual spectral domain frustrations by >> > using plain old multiplication. Here's an example: >> >> >> > SynthDef.new(\corr, {|bus1, bus2, resultbus, rate=40| >> > var sig1amp, sig2amp, sig1=In.ar(bus1), sig2=In.ar(bus2); >> > sig1amp = A2K.kr( >> > OpLPF.ar( >> > sig1.squared, >> > rate, >> > iter: 4 >> > ) >> > ); >> > sig2amp = A2K.kr( >> > OpLPF.ar( >> > sig2.squared, >> > rate, >> > iter: 4 >> > ) >> > ); >> > Out.kr(resultbus, >> > A2K.kr( >> > OpLPF.ar( >> > sig1*sig2, >> > rate, >> > iter: 4 >> > ) >> > )/((sig1amp*sig2amp).sqrt.max(0.00001))); >> > }).add; >> >> > ~outsame = Bus.control; >> > ~outdiff = Bus.control; >> > ~twoHundred={Out.ar(0,SinOsc.ar(200, mul: 0.2))}.play; >> > ~threeHundred={Out.ar(1,SinOsc.ar(300, mul: 0.2))}.play; >> > ~corrsame = Synth.new(\corr, [\bus1, 0, \bus2, 0, \resultbus, ~outsame], >> > addAction:\addToTail); >> > ~corrdiff = Synth.new(\corr, [\bus1, 0, \bus2, 1, \resultbus, ~outdiff], >> > addAction:\addToTail); >> > //results available here: >> > ~outsame.get; >> > ~outdiff.get; >> >> >> > NB, that uses a Pseudo-Ugen that I cribbed from the mailing list because >> > sometime you want non-resonant filters with cutoff frequencies. See below. >> >> > -Dan (Not the dan you referred to in your last mail) >> >> >> >> > ------ >> > // >> >><http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Calculating-OnePole-coefficient-for-one-pole-LP-HP-filter-td4034000.html>http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Calculating-OnePole-coefficient-for-one-pole-LP-HP-filter-td4034000.html >> > //see also <http://www.dspguide.com/>http://www.dspguide.com/ >> > //One pole LPF with freq input (instead of coef) >> > //Thanks to Volker Bï¿½hm for the (freq -> coef) conversion formula. >> > //And Batuhan Bozkurt for initial pseudo ugen >> > //takes an "iter" param telling you how many times to apply the filter >> > OpLPF { >> > *kr {|in, freq=100, iter=1| >> > var coef = exp(-2*pi * (freq * ControlDur.ir)); >> > iter.do({in=OnePole.kr(in, coef);}); >> > ^in; >> > } >> > *ar {|in, freq=100, iter=1| >> > var coef = exp(-2*pi * (freq * SampleDur.ir)); >> > iter.do({in=OnePole.ar(in, coef);}); >> > ^in; >> > } >> > } >> >> >> >> >> > -- >> > View this message in context: >><http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Extremum-of-Cross-Correlation-tp7616151p7616189.html>http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Extremum-of-Cross-Correlation-tp7616151p7616189.html >> > Sent from the SuperCollider Users New (Use this!!!!) mailing list >>archive at Nabble.com. >> >> > _______________________________________________ >> > sc-users mailing list >> >> > info (subscription, etc.): >><http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml>http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml >> > archive: >> <http://www.listarc.bham.ac.uk/marchives/sc-users/>http://www.listarc.bham.ac.uk/marchives/sc-users/ >> > search: >> <http://www.listarc.bham.ac.uk/lists/sc-users/search/>http://www.listarc.bham.ac.uk/lists/sc-users/search/ > >> > >> > >> _______________________________________________ > >> sc-users mailing list > >> > >> info (subscription, etc.): > <http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml>http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml > >> archive: > <http://www.listarc.bham.ac.uk/marchives/sc-users/>http://www.listarc.bham.ac.uk/marchives/sc-users/ > >> search: > <http://www.listarc.bham.ac.uk/lists/sc-users/search/>http://www.listarc.bham.ac.uk/lists/sc-users/search/ > > > > > > Julius O. Smith III <mailto:[hidden email]><[hidden email]> > > Professor of Music and, by courtesy, Electrical Engineering > > CCRMA, Stanford University > > <http://ccrma.stanford.edu/~jos/>http://ccrma.stanford.edu/~jos/ > > > > _______________________________________________ > > sc-users mailing list > > > > info (subscription, etc.): > <http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml>http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml > > archive: > <http://www.listarc.bham.ac.uk/marchives/sc-users/>http://www.listarc.bham.ac.uk/marchives/sc-users/ > > search: > <http://www.listarc.bham.ac.uk/lists/sc-users/search/>http://www.listarc.bham.ac.uk/lists/sc-users/search/ > Julius O. Smith III <[hidden email]> Professor of Music and, by courtesy, Electrical Engineering CCRMA, Stanford University http://ccrma.stanford.edu/~jos/ _______________________________________________ sc-users mailing list info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
Thank you Julius,
I will try that. Best, Mike On 02/21/2015 02:40 PM, Julius Smith wrote: > That looks good! I would test it with WhiteNoise in buffer a and the > same noise delayed by N samples in buffer b. Then you expect the max > to be N samples greater than its value when N is 0. - Julius > > At 06:01 PM 2/16/2015, Michael Winter wrote: >> Actually, going back to (the other) Dan's idea. Shouldn't this be >> correct?: >> >> ( >> a = Buffer.alloc(s, 2048, 1); >> b = Buffer.alloc(s, 2048, 1); >> >> SynthDef(\xcorr, {|f1 = 440 f2 = 440| >> var ch1, ch2, trig, max; >> ch1 = FFT(a, SinOsc.ar(f1), wintype: 1); >> ch2 = FFT(b, SinOsc.ar(f2), wintype: 1); >> ch2 = PV_Conj(ch2); >> ch1 = PV_Mul(ch1, ch2); >> IFFT(ch1); >> trig = Impulse.kr(44100.0/2048.0); >> max = Latch.ar(RunningMax.ar(PlayBuf.ar(1, a, loop: 1), trig), >> trig); >> Poll.kr(trig, max, \max); >> }).send(s); >> ) >> >> x = Synth(\xcorr, [\f1, 440, \f2, 440]); >> x.set(\f2, 800); >> x.free; >> >> a.plot(\a, Rect(200, 430, 700, 300)); >> >> On 02/16/2015 02:02 PM, Julius Smith wrote: >> > The Pitch Ugen (in DelayUGens.cpp I believe) has a nice >> implementation of real-time peak-tracking in an AUTO-correlation >> function. It would be straightforward to adapt that to a real-time >> cross-correlation tracker (for continuous inter-channel time-delay >> estimation etc.). >> > >> > - Julius >> > >> > At 08:56 AM 2/16/2015, Michael Winter wrote: >> > >>> Thanks Dan, >>> >>> I have not had a chance to run this, but by looking at it. This is a >>> correlation of two lists, but does not do the cross-correlation, where >>> the correlation is taken at a set of time-lags. I think doing that and >>> then finding the maximum of the time-lagged correlations is the part >>> that is difficult to do in real-time. Please correct me if I am missing >>> something. >>> >>> -Mike >>> >>> On 02/16/2015 08:10 AM, parking-sun wrote: >>> > If you are happy with plain old time-domain correlation (i.e. the >>> "maximal" >>> > part is optional, you can avoid the usual spectral domain >>> frustrations by >>> > using plain old multiplication. Here's an example: >>> >>> >>> > SynthDef.new(\corr, {|bus1, bus2, resultbus, rate=40| >>> > var sig1amp, sig2amp, sig1=In.ar(bus1), sig2=In.ar(bus2); >>> > sig1amp = A2K.kr( >>> > OpLPF.ar( >>> > sig1.squared, >>> > rate, >>> > iter: 4 >>> > ) >>> > ); >>> > sig2amp = A2K.kr( >>> > OpLPF.ar( >>> > sig2.squared, >>> > rate, >>> > iter: 4 >>> > ) >>> > ); >>> > Out.kr(resultbus, >>> > A2K.kr( >>> > OpLPF.ar( >>> > sig1*sig2, >>> > rate, >>> > iter: 4 >>> > ) >>> > )/((sig1amp*sig2amp).sqrt.max(0.00001))); >>> > }).add; >>> >>> > ~outsame = Bus.control; >>> > ~outdiff = Bus.control; >>> > ~twoHundred={Out.ar(0,SinOsc.ar(200, mul: 0.2))}.play; >>> > ~threeHundred={Out.ar(1,SinOsc.ar(300, mul: 0.2))}.play; >>> > ~corrsame = Synth.new(\corr, [\bus1, 0, \bus2, 0, \resultbus, >>> ~outsame], >>> > addAction:\addToTail); >>> > ~corrdiff = Synth.new(\corr, [\bus1, 0, \bus2, 1, \resultbus, >>> ~outdiff], >>> > addAction:\addToTail); >>> > //results available here: >>> > ~outsame.get; >>> > ~outdiff.get; >>> >>> >>> > NB, that uses a Pseudo-Ugen that I cribbed from the mailing list >>> because >>> > sometime you want non-resonant filters with cutoff frequencies. >>> See below. >>> >>> > -Dan (Not the dan you referred to in your last mail) >>> >>> >>> >>> > ------ >>> > // >>> >>> <http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Calculating-OnePole-coefficient-for-one-pole-LP-HP-filter-td4034000.html>http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Calculating-OnePole-coefficient-for-one-pole-LP-HP-filter-td4034000.html >>> >>> > //see also <http://www.dspguide.com/>http://www.dspguide.com/ >>> > //One pole LPF with freq input (instead of coef) >>> > //Thanks to Volker Bï¿½hm for the (freq -> coef) conversion formula. >>> > //And Batuhan Bozkurt for initial pseudo ugen >>> > //takes an "iter" param telling you how many times to apply the >>> filter >>> > OpLPF { >>> > *kr {|in, freq=100, iter=1| >>> > var coef = exp(-2*pi * (freq * ControlDur.ir)); >>> > iter.do({in=OnePole.kr(in, coef);}); >>> > ^in; >>> > } >>> > *ar {|in, freq=100, iter=1| >>> > var coef = exp(-2*pi * (freq * SampleDur.ir)); >>> > iter.do({in=OnePole.ar(in, coef);}); >>> > ^in; >>> > } >>> > } >>> >>> >>> >>> >>> > -- >>> > View this message in context: >>> <http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Extremum-of-Cross-Correlation-tp7616151p7616189.html>http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Extremum-of-Cross-Correlation-tp7616151p7616189.html >>> >>> > Sent from the SuperCollider Users New (Use this!!!!) mailing list >>> archive at Nabble.com. >>> >>> > _______________________________________________ >>> > sc-users mailing list >>> >>> > info (subscription, etc.): >>> <http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml>http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml >>> >>> > archive: >>> <http://www.listarc.bham.ac.uk/marchives/sc-users/>http://www.listarc.bham.ac.uk/marchives/sc-users/ >>> > search: >>> <http://www.listarc.bham.ac.uk/lists/sc-users/search/>http://www.listarc.bham.ac.uk/lists/sc-users/search/ >> >> >> >> >> >> _______________________________________________ >> >> sc-users mailing list >> >> >> >> info (subscription, etc.): >> <http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml>http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml >> >> archive: >> <http://www.listarc.bham.ac.uk/marchives/sc-users/>http://www.listarc.bham.ac.uk/marchives/sc-users/ >> >> search: >> <http://www.listarc.bham.ac.uk/lists/sc-users/search/>http://www.listarc.bham.ac.uk/lists/sc-users/search/ >> > >> > >> > Julius O. Smith III >> <mailto:[hidden email]><[hidden email]> >> > Professor of Music and, by courtesy, Electrical Engineering >> > CCRMA, Stanford University >> > <http://ccrma.stanford.edu/~jos/>http://ccrma.stanford.edu/~jos/ >> > >> > _______________________________________________ >> > sc-users mailing list >> > >> > info (subscription, etc.): >> <http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml>http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml >> > archive: >> <http://www.listarc.bham.ac.uk/marchives/sc-users/>http://www.listarc.bham.ac.uk/marchives/sc-users/ >> > search: >> <http://www.listarc.bham.ac.uk/lists/sc-users/search/>http://www.listarc.bham.ac.uk/lists/sc-users/search/ >> > > > Julius O. Smith III <[hidden email]> > Professor of Music and, by courtesy, Electrical Engineering > CCRMA, Stanford University > http://ccrma.stanford.edu/~jos/ > > _______________________________________________ > sc-users mailing list > > info (subscription, etc.): > http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml > archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ > search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ _______________________________________________ sc-users mailing list info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
I know that this is a very old post but I'm trying to find my way around
cross correlation right now. What I need to do is exactly what julius is proposing: find the delay between the 2 signals. mwinter wrote >> That looks good! I would test it with WhiteNoise in buffer a and the >> same noise delayed by N samples in buffer b. Then you expect the max >> to be N samples greater than its value when N is 0. - Julius >> >>> >>> ( >>> a = Buffer.alloc(s, 2048, 1); >>> b = Buffer.alloc(s, 2048, 1); >>> >>> SynthDef(\xcorr, {|f1 = 440 f2 = 440| >>> var ch1, ch2, trig, max; >>> ch1 = FFT(a, SinOsc.ar(f1), wintype: 1); >>> ch2 = FFT(b, SinOsc.ar(f2), wintype: 1); >>> ch2 = PV_Conj(ch2); >>> ch1 = PV_Mul(ch1, ch2); >>> IFFT(ch1); >>> trig = Impulse.kr(44100.0/2048.0); >>> max = Latch.ar(RunningMax.ar(PlayBuf.ar(1, a, loop: 1), trig), >>> trig); >>> Poll.kr(trig, max, \max); >>> }).send(s); >>> ) >>> >>> x = Synth(\xcorr, [\f1, 440, \f2, 440]); >>> x.set(\f2, 800); >>> x.free; >>> >>> a.plot(\a, Rect(200, 430, 700, 300)); I do get the theory, up to the point of making the fft, but then why would you get the max from the a buffer? What is the point of doing the multiplication of the spectra? I'm not questioning the algorithm, I'm just trying to understand it.... thank you ddgg -- Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html _______________________________________________ sc-users mailing list info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
Free forum by Nabble | Edit this page |