views:

1397

answers:

3

I have a a low pass filter described by the following transfer function:

h[n] = (w_c/Pi) * sinc( n * w_c / Pi ), where is w_c is the cutoff frequency

I have to convert this low-pass filter to a band-pass filter.

+2  A: 

You h[n] transforms into a rect in frequency domain. To make it band pass you need to move its central frequency higher.

To do this, multiply h[n] by exp(j*w_offset*n), where w_offset is the amount to shift. If w_offset is positive, then you shift towards higher frequencies.

Multiplication in time domain is convolution in frequency domain. Since exp(j*w_offset*n) turns into impulse function centred on w_offset, the multiplication shifts the H(w) by w_offset.

See Discrete Time Fourier Transform for more details.

Note: such a filter will not be symmetric about 0, which means it will have complex values. To make it symmetric, you need to add h[n] multiplied by exp(-j*w_offset*n):

h_bandpass[n] = h[n](exp(j*w_offset*n)+exp(-j*w_offset*n))

Since cos(w*n) = (exp(j*w*n)+exp(-j*w*n))/2 we get:

h_bandpass[n] = h[n]cos(w_offset*n)

This filter then has purely real values.

freespace
@freespace, "filter is realisable since it has purely real values" You are implying that complex valued coefficients make a filter impossible to implement... you are wrong. When you have complex coefficients you do complex-multiplications and complex-adds (each complex-multiplication is 4 real-mults and 2 real-adds).
Trevor Boyd Smith
@Trevor Boyd Smith: My apologies, you are correct. My initial answer just considered what happened to a real value signal - you would get a complex value output which I thought was useless to say, speakers. But there are naturally cases where the signal itself is complex, and a complex output is expected and useful.
freespace
A: 

Let f[n] be the signal you get from the low-pass filter with w_c at the lower bound of the desired band. You can get the frequencies above this lower bound by subtracting f[n] from the original signal. This is the input you want for the second low-pass filter.

Nathan Kitchen
+1  A: 

The short answer is that you will multiply by a complex exponential in the time domain. Multiplication in the time domain will shift the signal in the frequency domain.

Matlab code:

n_taps = 100;
n = 1:n_taps;
h = ( w_c / Pi ) * sinc( ( n - n_taps / 2) * w_c / Pi ) .* ...
    exp( i * w_offset * ( n - n_taps / 2) );


p.s. I happened to have just implemented this exact functionality for school a couple of weeks ago.

Here is code for creating your own band pass filter using the windowing method:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function: Create bandpass filter using windowing method
% Purpose:  Simple method for creating filter taps ( useful when more elaborate
%           filter design libraries are not available )
%
% @author   Trevor B. Smith, 24MAR2009
%
% @param    n_taps    How many taps are in your output filter
% @param    omega_p1  The lower cutoff frequency for your passband filter
% @param    omega_p2  The upper cutoff frequency for your passband filter
% @return   h_bpf_hammingWindow     The filter coefficients for your passband filter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function h_bpf_hammingWindow = BPF_hammingWindow(n_taps,omega_p1,omega_p2)
    % Error checking
    if( ( omega_p2 == omega_p1 ) || ( omega_p2 < omega_p1 ) || ( n_taps < 10 ) )
        str = 'ERROR - h_bpf_hammingWindow():   Incorrect input parameters'
        h_bpf_hammingWindow = -1;
        return;
    end

    % Compute constants from function parameters
    length = n_taps - 1; % How many units of T ( i.e. how many units of T, sampling period, in the continuous time. )
    passbandLength = omega_p2 - omega_p1;
    passbandCenter = ( omega_p2 + omega_p1 ) / 2;
    omega_c = passbandLength / 2; % LPF omega_c is half the size of the BPF passband
    isHalfSample = 0;
    if( mod(length,2) == 1 )
        isHalfSample = 1/2;
    end

    % Compute hamming window
    window_hamming = hamming(n_taps);

    % Compute time domain samples
    n = transpose(-ceil(length/2):floor(length/2));
    h1 = sinc( (1/pi) * omega_c * ( n + isHalfSample ) ) * pi .* exp( i * passbandCenter * ( n + isHalfSample ) );

    % Window the time domain samples
    h2 = h1 .* window_hamming;
    if 1
        figure; stem(h2); figure; freqz(h2);
    end

    % Return filter coefficients
    h_bpf_hammingWindow = h2;
end % function BPF_hammingWindow()

Example on how to use this function:

h_bpf_hammingWindow = BPF_hammingWindow( 36, pi/4, 3*pi/4 );
freqz(h_bpf_hammingWindow); % View the frequency domain
Trevor Boyd Smith