0

I'd like to display the freq response of a Sallen Key filter type (in the specific case, this simple resonant filter).

on biquad, for example, I calculate magnitude and phase from zeros and poles, such as (in cpp):

// zeros
std::complex<double> resZeros(0.0, 0.0);
resZeros += mCoefficients.mA0 * std::exp(std::complex<double>(0.0, -0 * freq * k2PI));
resZeros += mCoefficients.mA1 * std::exp(std::complex<double>(0.0, -1 * freq * k2PI));
resZeros += mCoefficients.mA2 * std::exp(std::complex<double>(0.0, -2 * freq * k2PI));

// poles std::complex<double> resPoles(0.0, 0.0); resPoles += 1.0 * std::exp(std::complex<double>(0.0, -0 * freq * k2PI)); resPoles += mCoefficients.mB1 * std::exp(std::complex<double>(0.0, -1 * freq * k2PI)); resPoles += mCoefficients.mB2 * std::exp(std::complex<double>(0.0, -2 * freq * k2PI));

std::complex<double> res = resZeros / resPoles;

// magnitude float magnitude = (float)std::abs(res); if (std::isnan(magnitude)) { magnitude = 0.0f; }

// phase float phase = (float)std::arg(res); // i.e. math.atan2(res.im, res.re) if (std::isnan(phase)) { phase = 0.0f; }

return std::polar(magnitude, phase);

this code is taken from the web :) can I do the same with the filter above? generally, can I do it with different kind of filters?

markzzz
  • 45
  • 1
  • 2
  • 10

1 Answers1

1

To calculate the frequency response from the poles and zeros in continuous time (Laplace), write out the transfer function, $H(s)$, as the numerator (zeros) divided by the denominator (poles) and simply replace $s$ with $j\omega$, since the frequency response is the transfer function with $s$ restricted to be the $j\omega$ axis:

$$H(s) = \frac{(s-z_1)(s-z_2)(s-z_3)\ldots}{(s-p_1)(s-p_2)(s-p_3)\ldots} $$

With $z_1$, $z_2$, etc referring to the zero locations on the complex s-plane, and $p_1$, $p_2$, etc referring to the poles.

$$H(j\omega) = \frac{(j\omega-z_1)(j\omega-z_2)(j\omega-z_3)\ldots}{(j\omega-p_1)(j\omega-p_2)(j\omega-p_3)\ldots} $$

This is plug and chug with complex numbers, so multiply it out and then calclulate the magnitude and phase as a function of frequency, which is the frequency response.

For discrete time (Z-transform), it is the same process, except the frequency response is the transfer function in z, $H(z)$, with $z$ replaced with $e^{j\omega}$ with $\omega$ extending from $0$ to $2 \pi$ (the unit circle):

$$H(z) = \frac{(z-z_1)(z-z_2)(z-z_3)\ldots}{(z-p_1)(z-p_2)(z-p_3)\ldots} $$

$$H(e^{j\omega}) = \frac{(e^{j\omega}-z_1)(e^{j\omega}-z_2)(e^{j\omega}-z_3)\ldots}{(e^{j\omega}-p_1)(e^{j\omega}-p_2)(e^{j\omega}-p_3)\ldots} $$

Here's a very simple and graphical demonstration for a first order single pole continuous time RC low pass filter:

The RC filter results in a single real pole in the left half plane at $s=-\frac{1}{RC}$.

The transfer function for this is: $$H(s) = \frac{1}{s-p_1} = \frac{1}{s+1/(RC)}$$

Graphically on the s-plane we have a ratio of phasors where the numerator is always $1/angle{0}$ and the denominator $s-p_1$ with $s=j\omega$ starts off at DC when \omega=0 to be a phasor with magnitude $1/(RC)$ and angle $0$. This is our starting magnitude referenced by 0 dB on the Bode plot showing the relative magnitude and phase over frequency. As we increase $\omega$ up to the magnitude of the pole (when $s=j (1/(RC))$), the length of the denominator phasor will be $\sqrt{2}$ longer and at an angle of 45°. Given this is in the denominator and the numerator in this case was always 1, this is consistent with a -3 dB magnitude and -45° and is noted as the cutoff frequency. As we continue to sweep the frequency toward $\infty$ we see that the magnitude of the denominator approaches $\infty$ and the phase approaches +90°, consistent with the magnitude approaching $0$ and phase approaching -90° for $H(j\omega)$.

Filter Example

Dan Boschen
  • 50,942
  • 2
  • 57
  • 135