View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

convolution of signals

Literature:

//ring modulation does not convolute, it just does a multiply
 a = Signal[1,2,3];
 b = Signal[1,1,1];
 (a.ring1(b) - a).asCompileString.postln;

 a = Signal[1,2,3];
 b = Signal[1,1,1,1];
 (a.ring1(b) - a).asCompileString.postln;


 a = Signal[1,2,3];
 b = Signal[1,1.5,-1];
 (a.ring1(b) - a).asCompileString.postln;




////////////store convolution function first///////////////
//this is a basic method, that works, but is much slower than its fft counterpart.
//I use it here to see the basic idea of convolution which is more hidden in fft.
(
f = { arg sig1, sig2;
	var out, iLast, d;
	out = Signal.newClear(sig1.size);
	
	iLast = sig2.size - 1;
	d = sig1.size - sig2.size;
	sig1.do({ arg  item, i;
		out.overDub(sig2*item, i);
		if(i > d, { //overDub clips: wrap the the overlapping rest and multiply
			out.overDub(sig2.copyRange((i-d), iLast) * item, 0);
		})
	});
	out
	
};
)

//tests
a = Signal[1,2,3,4,5,6];
//testing commutative property
f.value(a, Signal[1,2.4,-1.1, -1, 1, -1]).asCompileString.postln;
f.value(Signal[1,2.4,-1.1, -1, 1, -1], a).asCompileString.postln;
//testing delta function (equal signal out)
f.value(a, Signal[1,0,0,0,0,0]).asCompileString.postln;
//shifted delta function:
f.value(a, Signal[0,1,0,0,0,0]).asCompileString.postln;

)

(
//repeated selfconvolution of any signal should result in gaussian
a = Signal.newClear(128);
a = a.overDub(Signal.fill(32, { 0.5 + 0.5.rand2 }), 0);
a.plot;
b = a.copy;
3.do({ b = f.value(b, a).normalize.plot });
)

(
//larger signals take a bit longer..
n = 1024*2;
a = Signal.newClear(n);
a.overDub(Signal.sineFill(512, 1/#[1, 3, 2.3, 5, 3]).copyRange(0, 400), 0);
b = Signal.newClear(n);
3.do({ //add some random peaks
	var mul; 
	mul = 1.0.rand;  
	b.overDub(Signal.series(128, mul, mul/ -128), n.rand) 
});
a.plot;
b.plot;
x = f.value(b, a).normalize.plot;
//Synth.play({ Osc.ar(x.asWavetable, 150, 0, 0.1) });
)


//mathematicaly, convolution should be the same as multiplication of the 
//fourier transform (spectra).
//the problem here is that the size of the signal is the binsize of the fft.
//there is further investigation to be taken here..
(
//larger signals take a bit longer..
var n, imag, table, a, b, x, y;
n = 1024*2;

a = Signal.newClear(n);
a.overDub(Signal.sineFill(512, 1/#[1, 3, 2.3, 5, 3]).copyRange(0, 400), 0);

b = Signal.newClear(n);
3.do({ //add some random peaks
	var mul; 
	mul = 1.0.rand;  
	b.overDub(Signal.series(128, mul, mul/ -128), n.rand) 
});

a.plot;
b.plot;

//normal convolution:
x = f.value(b, a).normalize;
x.plot;

//fft multipy:
imag = Signal.newClear(n);
table = Signal.fftCosTable(n);

//fft is in place, overwrites the signal.
fft(a, imag, table);
fft(b, imag, table);
y = (a * b);
ifft(y, imag, table);
y.plot;
)
*****
/*
authors so far:
jrh
*/


Link to this Page