class sdr.Channelizer(sdr.PolyphaseFIR)

Implements a polyphase channelizer FIR filter.

Notes

The polyphase channelizer efficiently splits the input signal \(x[n]\) with sample rate \(f_s\) into \(C\) equally-spaced channels. Each channel has a bandwidth of \(f_s / C\).

The polyphase channelizer is equivalent to first mixing the input signal \(x[n]\) with \(C\) complex exponentials with frequencies \(f_i = -i \cdot f_s / C\), filtering the mixed signals with the prototype FIR filter with feedforward coefficients \(h[n]\), and then downsampling the filtered signals by \(C\) (by discarding \(C-1\) samples every \(C\) samples).

Instead, the polyphase channelizer first decomposes the prototype FIR filter into \(C\) polyphase filters with feedforward coefficients \(h_i[n]\). The polyphase filters are then applied to the commutated input signal \(x[n]\) in parallel. The outputs of the polyphase filters are then inverse Discrete Fourier transformed (IDFT) to produce the \(C\) channelized output signals \(y_i[n]\).

Polyphase Channelizer FIR Filter Block Diagram
                                                       +------+
                          +------------------------+   |      |
 ..., x[6], x[3], x[0] -->| h[0], h[3], h[6], h[9] |-->|      |--> ..., y[0,1], y[0,0]
                          +------------------------+   |      |
                          +------------------------+   |      |
 ..., x[5], x[2], 0    -->| h[1], h[4], h[7], 0    |-->| IDFT |--> ..., y[1,1], y[1,0]
                          +------------------------+   |      |
                          +------------------------+   |      |
 ..., x[4], x[1], 0    -->| h[2], h[5], h[8], 0    |-->|      |--> ..., y[2,1], y[2,0]
                          +------------------------+   |      |
                                                       +------+

 Input Commutator                                                 Parallel Outputs
 (bottom-to-top)

 x[n] = Input signal with sample rate fs
 y[i,n] = Channel i output signal with sample rate fs / C
 h[n] = Prototype FIR filter

The polyphase feedforward taps \(h_i[n]\) are related to the prototype feedforward taps \(h[n]\) by

\[h_i[j] = h[i + j C] .\]

References

  • fred harris, Multirate Signal Processing for Communication Systems, Chapter 6.1: Channelizer.

Examples

Create a channelizer with 10 channels.

In [1]: C = 10

In [2]: channelizer = sdr.Channelizer(C); channelizer
Out[2]: sdr.Channelizer(10, 'kaiser', streaming=False)

Create an input signal. Each channel has a tone with increasing frequency. The amplitude of each tone also increases by 2 dB for each channel.

In [3]: x = np.random.randn(10_000) + 1j * np.random.randn(10_000)

In [4]: for i in range(C):
   ...:     x += sdr.linear(10 + 2 * i) * np.exp(1j * 2 * np.pi * (i + 0.25 / C * i) / C * np.arange(10_000))
   ...: 

Plot the input signal and overlay the channel boundaries. Note, Channel 5 is centered at \(f = 0.5\). So, it wraps from positive to negative frequencies.

In [5]: plt.figure(figsize=(8, 4)); \
   ...: sdr.plot.periodogram(x, fft=1024, color="k", label="Input $x[n]$");
   ...: 

In [6]: for i in range(C):
   ...:     f_start = (i - 0.5) / C
   ...:     f_stop = (i + 0.5) / C
   ...:     if f_start > 0.5:
   ...:         f_start -= 1
   ...:         f_stop -= 1
   ...:     plt.fill_betweenx([0, 80], f_start, f_stop, alpha=0.2, label=f"Channel {i}")
   ...: 

In [7]: plt.xticks(np.arange(-0.5, 0.6, 0.1)); \
   ...: plt.legend(); \
   ...: plt.title("Input signals spread across 10 channels");
   ...: 
../../_images/sdr_Channelizer_1.png

Channelize the input signal with sample rate \(f_s\) into 10 channels, each with sample rate \(f_s / 10\).

In [8]: Y = channelizer(x)

In [9]: x.shape, Y.shape
Out[9]: ((10000,), (10, 1001))
In [10]: plt.figure(figsize=(8, 4));

In [11]: for i in range(C):
   ....:     sdr.plot.periodogram(Y[i, :], fft=1024, label=f"Channel {i}")
   ....: 

In [12]: plt.xticks(np.arange(-0.5, 0.6, 0.1)); \
   ....: plt.title("Output signals from 10 channels");
   ....: 
../../_images/sdr_Channelizer_2.png

Constructors

Channelizer(channels: int, ...)

Creates a polyphase FIR channelizing filter.

Special methods

__call__(x: ArrayLike, mode: 'rate' | 'full' = 'rate') → NDArray

Channelizes the input signal \(x[n]\) with the polyphase FIR filter.

__len__() → int

Returns the filter length \(N + 1\).

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 streaming : bool

Indicates whether the filter is in 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[numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.complex128]]]
frequency_response(freqs: float, ...) → complex
frequency_response(freqs, ...) → ndarray[Any, dtype[complex128]]

Returns the frequency response \(H(\omega)\) of the FIR filter.

group_delay(...) → tuple[NDArray, NDArray]

Returns the group delay \(\tau_g(\omega)\) of the FIR filter.

phase_delay(...) → tuple[NDArray, NDArray]

Returns the phase delay \(\tau_{\phi}(\omega)\) of the FIR filter.

Properties

property channels : float

The number of channels \(C\).

property method : 'kaiser' | 'custom'

The method used to design the polyphase channelizing filter.

property branches : int

The number of polyphase branches \(B\).

property taps : NDArray

The prototype feedforward taps \(h[n]\).

property polyphase_taps : NDArray

The polyphase feedforward taps \(h_i[n]\).

property order : int

The order \(N = (M + 1)B - 1\) of the FIR prototype filter \(h[n]\).

property polyphase_order : int

The order \(M = (N + 1)/B - 1\) of each FIR polyphase filter \(h_i[n]\).

property input : 'hold' | 'top-to-bottom' | 'bottom-to-top'

The input connection method.

property output : 'sum' | 'top-to-bottom' | 'bottom-to-top' | 'all'

The output connection method.

property interpolation : int

The integer interpolation rate \(P\).

property decimation : int

The integer decimation rate \(Q\).

property rate : float

The fractional resampling rate \(r = P/Q\). The output sample rate is \(f_{s,out} = f_{s,in} \cdot r\).

property delay : int

The delay of polyphase FIR filter in samples. The delay indicates the output sample index that corresponds to the first input sample.