Many thanks James,

this is pretty cool!

To understand what your code does I compared 4 examples (maybe useful for others):

```
// example 1:
// same signal
(
x = Signal.sineFill(512, [1]); //red
y = Signal.sineFill(512, [1]); //green
z=(x*y); //blue
a=sum(x*y).postln; //260
)
//degree of correlation: 260
( //red cannot be seen as green is on top;
var data = [x,y,z];
var plotter = Plotter("plotter",Rect(5,5,630,235));
plotter.plotMode = \points;
plotter.value_(data);
plotter.superpose_(true);
plotter.setProperties(
\plotColor, [Color.red,Color.green,Color.blue]
);
);
```

```
(
~table = Signal.fftCosTable(x.size);
~xfft = x.fft(Signal.newClear(x.size), ~table);
~yfft = y.fft(Signal.newClear(y.size), ~table);
~crosscorrfft = ~yfft * ~xfft.conjugate;
~crosscorr = ~crosscorrfft.real.ifft(~crosscorrfft.imag, ~table);
~crosscorr.real.plot;
~crosscorr.real.maxIndex; // 0
)
// 0 means no shift of phase between the two signals
```

```
//example 2:
//slightly out of phase signals with same amp
(
x = Signal.sineFill(512, [1]); //red
y = x.rotate(25); //green
z=(x*y); //blue
a=sum(x*y).postln; //244
)
//degree of correlation: 244
(
var data = [x,y,z];
var plotter = Plotter("plotter",Rect(5,5,630,235));
plotter.plotMode = \points;
plotter.value_(data);
plotter.superpose_(true);
plotter.setProperties(
\plotColor, [Color.red,Color.green,Color.blue]
);
);
```

```
(
~table = Signal.fftCosTable(x.size);
~xfft = x.fft(Signal.newClear(x.size), ~table);
~yfft = y.fft(Signal.newClear(y.size), ~table);
~crosscorrfft = ~yfft * ~xfft.conjugate;
~crosscorr = ~crosscorrfft.real.ifft(~crosscorrfft.imag, ~table);
~crosscorr.real.plot;
~crosscorr.real.maxIndex; // 25
)
// 25: means signals are 25 'frames' out of phase;
```

```
// example 3:
// same phase, different amp;
(
x = Signal.sineFill(512, [1]); //red
y = Signal.sineFill(512, [1])*0.5; //green
z=(x*y); //blue
a=sum(x*y).postln;//128
)
//degree of correlation: 128
(
var data = [x,y,z];
var plotter = Plotter("plotter",Rect(5,5,630,235));
plotter.plotMode = \points;
plotter.value_(data);
plotter.superpose_(true);
plotter.setProperties(
\plotColor, [Color.red,Color.green,Color.blue]
);
);
```

```
(
~table = Signal.fftCosTable(x.size);
~xfft = x.fft(Signal.newClear(x.size), ~table);
~yfft = y.fft(Signal.newClear(y.size), ~table);
~crosscorrfft = ~yfft * ~xfft.conjugate;
~crosscorr = ~crosscorrfft.real.ifft(~crosscorrfft.imag, ~table);
~crosscorr.real.plot;
~crosscorr.real.maxIndex; //0
)
// 0: means signals are 0 'frames' out of phase;
```

```
// example 4:
// more out of phase and different amp
(
x = Signal.sineFill(512, [1]); //red
y = x.rotate(100)*0.5; //green
z=(x*y); //blue
a=sum(x*y).postln; //43
)
//degree of correlation: 43
(
var data = [x,y,z];
var plotter = Plotter("plotter",Rect(5,5,630,235));
plotter.plotMode = \points;
plotter.value_(data);
plotter.superpose_(true);
plotter.setProperties(
\plotColor, [Color.red,Color.green,Color.blue]
);
);
```

```
(
~table = Signal.fftCosTable(x.size);
~xfft = x.fft(Signal.newClear(x.size), ~table);
~yfft = y.fft(Signal.newClear(y.size), ~table);
~crosscorrfft = ~yfft * ~xfft.conjugate;
~crosscorr = ~crosscorrfft.real.ifft(~crosscorrfft.imag, ~table);
~crosscorr.real.plot;
~crosscorr.real.maxIndex; // 100
)
// 100: means signals are 100 'frames' out of phase;
```

Maximum degree of correlation is around sample-rate/2 i.e. in the examples above 512/2.

Maybe turning some of the values absolute before plotting could help see correlations, I will experiment. I will try to implement in the EEG code now…

Cheers! Have a great day, k