o----o-> oSee also http://people.seas.harvard.edu/~jones/cscie129/nu_lectures/lecture11/switching/strowger/strowger.html
| o
| o
| o----o-> o
| o | o
| o--------o-> o
| o | o-------------
| o | o
| o
| o
Specifically, convolution of an array samples[] by a second array K, a shorter array of double of length len, means to set result[n] as follows:
double sum = 0;Sometimes you might divide by len; more often, K has been adjusted so that the K[i] add up to 1.0 (or 0.0). Purists do the reversed indexing of K, as above, but if you replace K[len-i-1] with K[i], all you have to do is make sure that K itself is created in the reversed order. If K is symmetrical, you won't even have to do that. This reversed form means taking the sum of samples[i+n]*K[i], for i<len.
for (int i = 0; i<len; i++) sum += samples[i+n]*K[len-i-1];
result[n] = (short) sum;
You can do two things when you reach the upper end of the array samples[]:
quit at n = samples.length - len, or else use 0.0 wherever you need a value
samples[n] for n ≥ samples.length.
In the literature, K is often said to be a kernel, though this is a very different usage than in the OS sense.
Mathematically, convolving with a kernel K(t) involves taking the
integral ∫ signal(t)×K(x-t)dt, over an appropriate interval such as
[0,len]. Convolution is the time-domain version of pointwise mulitiplication in the frequency domain; if the frequencies are, say, ⟨f0, f1, f2, f3, f4, f5, f6, f7⟩ and we multiply pointwise by ⟨0,0,0,1,0,0,0,0⟩
we get f3; that is, we have isolated a particular frequency. If we
multiply pointwise by ⟨0,0,0,0,1,1,1,1⟩ we get ⟨0,0,0,0,f4,f5,f6,f7⟩;
that is, we have implemented a high-pass filter. Both frequency isolation (above) and lo/hi/bandpass filters are indeed implemented as convolutions in the time domain.
1 0 0 0 0 0 ... (length depends on delay) ... 0 0 AIf the length here is len+1, this has the effect of setting result[n] = samples[n] + A*samples[n-len]; that is, adding back into the samples the result from len units ago, reduced by factor A.