- class sdr.Decimator(sdr.FIR)
Implements a polyphase decimating FIR filter.
Notes¶
The polyphase decimating filter is equivalent to first filtering the input signal \(x[n]\) with the prototype FIR filter with feedforward coefficients \(h_{i}\) and then decimating the filtered signal by \(r\) (by discarding \(r-1\) samples between each sample).
Instead, the polyphase decimating filter first decomposes the prototype FIR filter into \(r\) polyphase filters with feedforward coefficients \(h_{i, j}\). The polyphase filters are then applied to the commutated input signal \(x[n]\) in parallel. The outputs of the polyphase filters are then summed. This prevents the need to compute outputs that will be discarded, as is done in the first case.
+------------------------+ ..., x[4], x[2], x[0] -->| h[0], h[2], h[4], h[6] |--+ +------------------------+ | @--> ..., y[1], y[0] +------------------------+ | ..., x[3], x[1], 0 -->| h[1], h[3], h[5], 0 |--+ +------------------------+ Input Commutator Output Summation (bottom-to-top) x[n] = Input signal with sample rate fs y[n] = Output signal with sample rate fs/r h[n] = Prototype FIR filter @ = Adder
The polyphase feedforward taps \(h_{i, j}\) are related to the prototype feedforward taps \(h_i\) by
\[h_{i, j} = h_{i + j r} .\]Examples¶
Create an input signal to interpolate.
In [1]: x = np.cos(np.pi / 64 * np.arange(280))
Create a polyphase filter that decimates by 7 using the Kaiser window method.
In [2]: fir = sdr.Decimator(7); fir Out[2]: sdr.Decimator(7, 'kaiser', streaming=False) In [3]: y = fir(x) In [4]: plt.figure(figsize=(8, 4)); \ ...: sdr.plot.time_domain(x, marker=".", label="Input"); \ ...: sdr.plot.time_domain(y, sample_rate=1/fir.rate, marker="o", label="Decimated"); \ ...: plt.title("Decimation by 7 with the Kaiser window method"); \ ...: plt.tight_layout(); ...:
Create a streaming polyphase filter that decimates by 7 using the Kaiser window method. This filter preserves state between calls.
In [5]: fir = sdr.Decimator(7, streaming=True); fir Out[5]: sdr.Decimator(7, 'kaiser', streaming=True) In [6]: y1 = fir(x[0:70]); \ ...: y2 = fir(x[70:140]); \ ...: y3 = fir(x[140:210]); \ ...: y4 = fir(x[210:280]); \ ...: y5 = fir.flush() ...: In [7]: plt.figure(figsize=(8, 4)); \ ...: sdr.plot.time_domain(x, marker=".", label="Input"); \ ...: sdr.plot.time_domain(y1, sample_rate=1/fir.rate, offset=-fir.delay*fir.rate + 0, marker="o", label="Decimated $y_1[n]$"); \ ...: sdr.plot.time_domain(y2, sample_rate=1/fir.rate, offset=-fir.delay*fir.rate + 70, marker="o", label="Decimated $y_2[n]$"); \ ...: sdr.plot.time_domain(y3, sample_rate=1/fir.rate, offset=-fir.delay*fir.rate + 140, marker="o", label="Decimated $y_3[n]$"); \ ...: sdr.plot.time_domain(y4, sample_rate=1/fir.rate, offset=-fir.delay*fir.rate + 210, marker="o", label="Decimated $y_4[n]$"); \ ...: sdr.plot.time_domain(y5, sample_rate=1/fir.rate, offset=-fir.delay*fir.rate + 280, marker="o", label="Decimated $y_5[n]$"); \ ...: plt.title("Streaming decimation by 7 with the Kaiser window method"); \ ...: plt.tight_layout(); ...:
Constructors¶
-
Decimator(rate: int, taps: 'kaiser' | ArrayLike =
'kaiser'
, ...) Creates a polyphase FIR decimating filter.
Special methods¶
-
__call__(x: ArrayLike, mode: 'rate' | 'full' =
'rate'
) NDArray Filters and decimates the input signal \(x[n]\) with the polyphase FIR filter.
String representation¶
Streaming mode only¶
- reset()
Resets the filter state. Only useful when using streaming mode.
- flush() NDArray
Flushes the filter state by passing zeros through the filter. Only useful when using streaming mode.
- property state : NDArray
The filter state consisting of the previous \(N\) inputs.
Methods¶
-
impulse_response(N: int | None =
None
) NDArray Returns the impulse response \(h[n]\) of the FIR filter. The impulse response \(h[n]\) is the filter output when the input is an impulse \(\delta[n]\).
-
step_response(N: int | None =
None
) NDArray Returns the step response \(s[n]\) of the FIR filter. The step response \(s[n]\) is the filter output when the input is a unit step \(u[n]\).
- frequency_response(...) tuple[NDArray, NDArray]
Returns the frequency response \(H(\omega)\) of the FIR filter.
- frequency_response_log(...) tuple[NDArray, NDArray]
Returns the frequency response \(H(\omega)\) of the FIR filter on a logarithmic frequency axis.
Properties¶
- property method : 'kaiser' | 'custom'
The method used to design the multirate filter.
- property taps : NDArray
The prototype feedforward taps \(h_i\).
- property polyphase_taps : NDArray
The polyphase feedforward taps \(h_{i, j}\).
- property delay : int
The delay of FIR filter in samples. The delay indicates the output sample index that corresponds to the first input sample.
-
Decimator(rate: int, taps: 'kaiser' | ArrayLike =