# How to create a real bandpass filter?

I'm trying to create a real bandpass filter (17-point) in Python by calculating the coefficients b of a signal. This is the formula I'm using: $$b = \cos(ω(k-k_m))$$ for $$k = 0,1,..,L-1$$, where $$k_m$$ is the midpoint of the impulse response, $$k_m = 1/2(L-1)$$ I calculated omega with this formula: $$ω = 2πf/f_s$$ where $$f_s=16000$$ Hz and $$f= 960$$ Hz and therefore $$ω = 0.12π$$. The bandpass should be a 17 point bandpass filter. I suppose thats the $$L$$ in the formula if I'm correct, and therefore $$k_m = 1/2(L-1) = 1/2(17-1) = 8$$ So when putting all calculated variables in the formula i get: $$b = \cos(0.12π(k-8))$$ where $$k$$ is $$0,1,...,16$$. When calculating the coefficients for every $$k$$ until $$16$$ i get this coefficients array, which I use to filter my signal:

coefficients = np.array((-0.9921147013144778, -0.8763066800438634,-0.6374239897486894,-0.30901699437494734,0.06279051952931353,0.4257792915650728, 0.7289686274214116, 0.9297764858882515, 1.0, 0.9297764858882515, 0.7289686274214116,  0.4257792915650728,  0.06279051952931353,-0.30901699437494734,-0.6374239897486894, -0.8763066800438634, -0.9921147013144778))


However, this real bandpass should also have the center frequency 2000 Hz. My questions is how do I implement the center frequency, because I already have the coefficients(if I did it right) and if there is an easier way to calculate all this?

The easiest ways to generate a bandpass FIR filter in Python are to use one of firwin or remez.

Below are four filters: your original (blue), another like your original that is centered on 2000 Hz (green), a remez design (orange), and an firwin design (red).

The impulse responses are:

The frequency responses are:

Depending on your requirements, either the orange (remez) or red (firwin) designs are closer to what you want.

# Python code below

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import remez, freqz, firwin

L = 17
k = np.arange(L)
km = (L-1)/2
fs = 16000
f = 960
f_center = 2000
omega = 2*f/fs*np.pi
omega_center = 2*f_center/fs*np.pi

b = np.cos(omega*(k-km))
b2 = np.cos(omega_center*(k-km))

edges = [0, f_center-f/2-160, f_center-f/2+160, f_center+f/2-160, f_center+f/2+160, fs/2 ]
b1 = remez(L, edges, [0, 1, 0], Hz=fs)
b3 = firwin(L, [f_center-f/2, f_center+f/2], pass_zero=False, fs=fs)

plt.figure(1)
plt.plot(b)
plt.plot(b1)
plt.plot(b2)
plt.plot(b3)

plt.figure(2)
w, mag = freqz(b, fs=fs)
w, mag1 = freqz(b1, fs=fs)
w, mag2 = freqz(b2, fs=fs)
w, mag3 = freqz(b3, fs=fs)
plt.plot(w,np.abs(mag)/np.abs(mag).max())
plt.plot(w, np.abs(mag1)/np.abs(mag1).max())
plt.plot(w, np.abs(mag2)/np.abs(mag2).max())
plt.plot(w, np.abs(mag3)/np.abs(mag3).max())