Let's construct a simple digital band-pass filter based in the sinc filter.
As everyone know, the sinc function is the impulse response
of a low-pass filter. That is, the convolution
of a signal and the sinc function
will produce a low-pass filtered signal
without frequencies higher than
. Similarly, the function
where
represents the Dirac delta function, is the frequency response of the ideal high-pass filter of frequency
.
Heuristically, we can right away derive the discrete versions of the impulse responses:
for the high-pass filter. The variable is the sampling frequency and
is the Kronecker delta.
Now, having a discrete signal at hand, band-pass filtering is (in the simplest approach) just a matter of discrete convolution of the signal with the functions above. The following Octave code does the job.
##Sinc band-pass filter. f0 = B_L/fs, f1 = B_H/fs function filtered = sincfilter(signal, f0, f1) if(mod(length(signal), 2) != 0) #Check if the signal length is even or odd. signal = signal(1 : length(signal) - 1); end M = 10000; #Increase this to increase accuracy. sincF = zeros(1, M); for m = -M/2 + 1 : 1 : M/2 if(!(m == 0)) sincF(m + M/2) = sin(2*pi*f1*m)./(pi*m); else sincF(m + M/2) = 2*f1; end end sincH = zeros(1,M); for m = -M/2 + 1 : 1 : M/2 if(!(m == 0)) sincH(m + M/2) = -sin(2*pi*f0*m)./(pi*m); else sincH(m + M/2) = -2*f0 + 1; end end ##Plot stuff. figure(1) plot(sincF) figure(2) plot(signal) tic filtered = conv(signal, sincF, "same"); filtered = conv(filtered, sincH, "same"); toc figure(3) plot(filtered) end
For more accuracy and effectiveness, one should use windowed or recursive filters. One can check in the references for more sophisticated methods!
References: