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