Obtain frequency response from digital filter with DSP.jl

Hi, I have a simple and potentially very stupid question. I use DSP.jl to construct a filter via digitalfilter(), which leaves me with a filter kernel I can apply to my signal.

If I wanted to take a look at the response in the frequency domain, freqz() seems to be the appropriate function. However, it only accepts filter coefficient objects, which leads to the question of how to convert a filter kernel from digitalfilter() to such an object.

I found the documentation of what otherwise looks like an excellent and well-designed package a bit sparse (at least for people with no DSP background), but it seems like this does what I want for filters constrcuted with the remez() method:

julia> bpass = remez(35, [(0, 0.1)=>0, (0.15, 0.4)=>1, (0.45, 0.5)=>0]);
julia> b = DSP.Filters.PolynomialRatio(bpass, [1.0])
julia> f = range(0, stop=0.5, length=1000)
julia> plot(f, 20*log10.(abs.(freqz(b,f,1.0))))

It seems to work just fine für filters created by digitalfilter(), so am I correct that e.g. DSP.Filters.PolynomialRatio(digitalfilter(FIRWindow(hamming(3), Highpass(10; fs=100)), [1.0]) will yield a correct frequency response?

And a bonus question: Does anyone have a good resource for learning about how these filter coefficients relate to e.g. a window-based FIR filter?

I am not an expert but some feedback:

  • It seem that freqz does not compute the frequency response of FIR filters (it works alright for others).
  • You can use function available in: FIRfreqz, to display your FIR filter response as follows:
fs = 100
f = digitalfilter(Highpass(10; fs=fs), FIRWindow(hamming(3)))
w = range(0, stop=pi, length=1024)
h = FIRfreqz(f, w)
ws = w/pi*(fs/2)
plot(ws, 20*log10.(abs.(h)), xlabel="Frequency(Hz)",ylabel="Magnitude(db)",label="10Hz high-pass" )
1 Like

Thanks! That helps actually quite a lot! My understanding is that sw += b[j]*exp(-im*w[i])^-j is basically just a Fourier transformation, right?

Correct. Called Discrete Time Fourier Transform (DTFT) in article FIR_filter, see the FIR filter’s frequency response equation in section “Frequency response”.

As a quick hack, you could extend freqz to work with FIR filters.

freqz(h::Vector{T}, N) where T = fft([h; zeros(T, N-length(h))])

Edit: In this case the corresponding normalised frequency vector (in radians) would be

w = range(0, step=2π/N, length=N)
2 Likes