Amplitude not attenuated after bandpass filtering? I want to make a bandpass filter for an IQ signal recorded from an Software Defined Radio with center frequency "Fc" &amp; sampling frequency "Fs". For futhur analysis I wanted to focus upon signal received between a fixed frequency range &amp; filter out rest frequencies.

I generated "sinc" funtion using Python Scipy firwin then I convoluted it with my signal using Python fftconvolve. But as you see in the plots amplitude of the frequency bins outside the pass band of my are still not attenuated.

Approach


Read the data,convert it from uint8 &amp; strore it as complex notation.
Generate a "sinc" function of width half of difference of cutoff frequencies eg. for 20MHz to 40MHz width of filter will be 10MHz. Since "sinc" is symmetric it will filter frequencies from -10MHz to +10MHz.
Move the centre of filter to mean of cutoff frequencies using frequency shift property.
Convolve the filter with the data.


Relevant Code

data_raw=signal.flatten()
data_raw=data_raw-127.5

data = np.empty(data_raw.shape[0]//2, dtype=np.complex128)
data.real = data_raw[::2]
data.imag = data_raw[1::2]

nyq = 0.5 * fs

# Normalized frequency to be used for frequency shift
centre=(highcut+lowcut)/2-fc

width=np.ceil((highcut-lowcut)/2)
h = firwin(513,width,nyq=nyq,window='hanning')
h = np.append(h,np.zeros(1024-len(h)))

t=np.arange(len(h))
h=h*(np.exp(1j*2*np.pi*t*(centre/fs)))
filtered_data = fftconvolve(data, h)


Details:


Fcentre = 137.65 MHz
Fsample = 2 MHz
Lowcut = 137.65 MHz
Hightcut = 138.15 MHz


Plots:

Firwin filter linear plot

Firwin filter semilog plot

Output after applying filter
You seem to be aware of the Fourier Transform pair that relates a sinc function in the time domain to a rectangle function in the frequency domain, but you don't seem to be able to correctly apply this to your situation. I am going to take one more stab at answering you. Let me know if you have questions.

A sinc filter can be designed using the relationship
\begin{equation}
\DeclareMathOperator{sin}{sin}
\DeclareMathOperator{sinc}{sinc}
\DeclareMathOperator{rect}{rect}
2 B \sinc\left(2 B t\right) \iff \rect\left(\frac{f}{2 B}\right)
\end{equation}
where $\sinc(x) = \frac{\sin(\pi x)}{\pi x}$. This shows us that the desired low pass bandwidth $B$ must be used in our expression to generate the sinc samples. Note that a modulated sinc has a bandwidth equal to $2B$ whereas a sinc centered at DC has a bandwidth of $B$.

In your example, you define several quantities. I am going to give these quantities symbols so I can do some math on them.


  Fcentre = 137.65 MHz


I'll call this $f_c$.


  Fsample = 2 MHz


I'll call this $f_s$.


  Lowcut = 137.65 MHz


I'll call this $f_l$.


  Hightcut = 138.15 MHz


I'll call this $f_h$.

For you to generate the sinc with the correct bandwidth, you would sample the sinc function above with
\begin{equation}
B = \frac{f_h - f_l}{2}.
\end{equation}

This means that your bandpass filter is given as
\begin{equation}
h[n] = \left(f_h - f_l\right) \sinc\left(\frac{f_h - f_l}{f_s} n\right) \exp\left(j \pi \frac{f_h + f_l - 2 f_c}{f_s} n \right)
\end{equation}
where I have ignored the required time shift to make the filter causal (implementable). The amount you shift it by will be determined by the length of the filter. The length of the filter will be determined by how much stopband attenuation you want. 

Note that no finite length filter will yield zero gain in the stopband and all filters have a transition band (a band where the amplitude gradually goes from the desired passband value to the designed stopband value). You can't avoid this.

As a side note, you could have just as easily used the Remez Exchange algorithm (a.k.a. Parks-McClellan) to obtain an optimal filter. The window method is computationally simple, but it is in no sense optimal.