//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 */ |