Polyphase FFT analysis filter bank
The dsp.Channelizer
System object™ separates a broadband input signal into multiple narrow subbands using a fast
Fourier transform (FFT)-based analysis filter bank. The filter bank uses a prototype lowpass
filter and is implemented using a polyphase structure. You can specify the filter coefficients
directly or through design parameters.
To separate a broadband signal into multiple narrow subbands:
Create the dsp.Channelizer
object and set its properties.
Call the object with arguments, as if it were a function.
To learn more about how System objects work, see What Are System Objects?.
creates a
polyphase FFT analysis filter bank System object that separates a broadband input signal into multiple narrowband output
signals. This object implements the inverse operation of the
channelizer
= dsp.Channelizerdsp.ChannelSynthesizer
System object.
creates an
M-band polyphase FFT analysis filter bank, with the NumFrequencyBands property set to M. channelizer
= dsp.Channelizer(M)
creates a polyphase FFT analysis filter bank with each specified property set to the
specified value. Enclose each property name in single quotes.channelizer
= dsp.Channelizer(Name,Value
)
Unless otherwise indicated, properties are nontunable, which means you cannot change their
values after calling the object. Objects lock when you call them, and the
release
function unlocks them.
If a property is tunable, you can change its value at any time.
For more information on changing property values, see System Design in MATLAB Using System Objects.
NumFrequencyBands
— Number of frequency bands8
(default) | positive integer greater than 1Number of frequency bands into which the object separates the input broadband signal, specified as a positive integer greater than 1. This property corresponds to the number of polyphase branches and the FFT length used in the filter bank.
Example: 16
Example: 64
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
OversamplingRatio
— Oversampling ratio1
(default) | positive integerOversampling ratio, specified as a positive scalar divisor of the number of frequency bands.
If the value is greater than 1
, the output sample rate is
different from the channel spacing. The channelizer is then known as the non-maximally
decimated channelizer or oversampled channelizer. For more details, see Algorithm.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
Specification
— Filter design parameters or coefficients'Number of taps per band and stopband
attenuation'
(default) | 'Coefficients'
Filter design parameters or filter coefficients, specified as one of these options:
'Number of taps per band and stopband attenuation'
— Specify the filter design parameters through the
NumTapsPerBand
and Stopband attenuation (dB) properties.
'Coefficients'
— Specify the filter coefficients
directly using the LowpassCoefficients property.
NumTapsPerBand
— Number of filter coefficients per frequency band12
(default) | positive integerNumber of filter coefficients each polyphase branch uses, specified as a positive
integer. The number of polyphase branches matches the number of frequency bands. The
total number of filter coefficients for the prototype lowpass filter is given by
NumFrequencyBands
× NumTapsPerBand
. For
a given stopband attenuation, increasing the number of taps per band narrows the
transition width of the filter. As a result, there is more usable bandwidth for each
frequency band at the expense of increased computation.
Example: 8
Example: 16
This property applies when you set Specification
to
'Number of taps per band and stopband attenuation'
.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
StopbandAttenuation
— Stopband attenuation80
(default) | positive real scalarStopband attenuation of the lowpass filter, specified as a positive real scalar in dB. This value controls the maximum amount of aliasing from one frequency band to the next. When the stopband attenuation increases, the passband ripple decreases. For a given stopband attenuation, increasing the number of taps per band narrows the transition width of the filter. As a result, there is more usable bandwidth for each frequency band at the expense of increased computation.
Example: 80
This property applies when you set Specification
to
'Number of taps per band and stopband attenuation'
.
Data Types: single
| double
LowpassCoefficients
— Coefficients of prototype lowpass filter[1×49 double]
(default) | row vectorCoefficients of the prototype lowpass filter, specified as a row vector. The default
vector of coefficients is obtained using
rcosdesign(0.25,6,8,'sqrt')
. There must be at least one
coefficient per frequency band. If the length of the lowpass filter is less than the
number of frequency bands, the object zero-pads the coefficients.
If you specify complex coefficients, the object designs a prototype filter that is centered at a nonzero frequency, also known as a bandpass filter. The modulated versions of the prototype bandpass filter appear with respect to the prototype filter and are wrapped around the frequency range [−Fs Fs]. For an example, see Channelizer with Complex Coefficients.
Tunable: Yes
This property applies when you set Specification
to
'Coefficients'
.
Data Types: single
| double
Complex Number Support: Yes
input
— Data inputData input, specified as a vector or a matrix. The number of rows in the input signal must be a multiple of the number of frequency bands of the filter bank. Each column of the input corresponds to a separate channel. If M is the number of frequency bands, and the input is an L-by-1 matrix, then the output signal has dimensions L/M-by-M. Each narrowband signal forms a column in the output. If the input has more than one channel, that is, it has dimensions L-by-N with N > 1, then the output has dimensions L/M-by-M-by-N.
This object supports variable-size input signals. You can change the input frame size (number of rows) even after calling the algorithm. However, the number of channels (number of columns) must remain constant.
Example: randn(64,4)
Data Types: single
| double
Complex Number Support: Yes
channOut
— Channelizer outputChannelizer output, returned as a matrix or a 3-D array. If the input is an L-by-1 matrix, then the output signal has dimensions L/M-by-M, where M is the number of frequency bands. Each narrowband signal forms a column in the output. If the input has more than one channel, that is, it has dimensions L-by-N with N > 1, then the output has dimensions L/M-by-M-by-N.
Data Types: single
| double
Complex Number Support: Yes
To use an object function, specify the
System object as the first input argument. For
example, to release system resources of a System object named obj
, use
this syntax:
release(obj)
coeffs | Coefficients of prototype lowpass filter |
tf | Return transfer function of overall prototype lowpass filter |
polyphase | Return polyphase matrix |
freqz | Frequency response of filters in channelizer |
fvtool | Visualize the filters in the channelizer |
bandedgeFrequencies | Compute the bandedge frequencies |
centerFrequencies | Compute center frequencies |
getFilters | Return matrix of channelizer FIR filters |
The quadrature mirror filter bank (QMF) contains an analysis filter bank section and a synthesis filter bank section. dsp.Channelizer
implements the analysis filter bank. dsp.ChannelSynthesizer
implements the synthesis filter bank using the efficient polyphase implementation based on a prototype lowpass filter.
Initialization
Initialize the dsp.Channelizer
and dsp.ChannelSynthesizer
System objects. Each object is set up with 8 frequency bands, 8 polyphase branches in each filter, 12 coefficients per polyphase branch, and a stopband attenuation of 140 dB. Use a sine wave with multiple frequencies as the input signal. View the input spectrum and the output spectrum using a spectrum analyzer.
offsets = [-40,-30,-20,10,15,25,35,-15]; sinewave = dsp.SineWave('ComplexOutput',true,'Frequency',... offsets+(-375:125:500),'SamplesPerFrame',800); channelizer = dsp.Channelizer('StopbandAttenuation',140); synthesizer = dsp.ChannelSynthesizer('StopbandAttenuation',140); spectrumAnalyzer = dsp.SpectrumAnalyzer('ShowLegend',true,'NumInputPorts',... 2,'ChannelNames',{'Input','Output'},'Title','Input and Output of QMF');
Streaming
Use the channelizer to split the broadband input signal into multiple narrow bands. Then pass the multiple narrowband signals into the synthesizer, which merges these signals to form the broadband signal. Compare the spectra of the input and output signals. The input and output spectra match very closely.
for i = 1:5000 x = sum(sinewave(),2); y = channelizer(x); v = synthesizer(y); spectrumAnalyzer(x,v) end
Create a dsp.Channelizer
object and set the LowpassCoefficients
property to a vector of complex coefficients.
Complex Coefficients
Using firpm
, determine the coefficients of a Park-McClellan's optimal equiripple FIR filter of order 30, and frequency and amplitude characteristics described by F = [0 0.2 0.4 1.0] and A = [1 1 0 0] vectors, respectively.
Create a complex version of these coefficients by multiplying with a complex exponential. The resultant frequency response is that of a bandpass filter at the specified frequency, in this case 0.4.
blowpass = firpm(30,[0 .2 .4 1],[1 1 0 0]); N = length(blowpass)-1; Fc = 0.4; j = complex(0,1); bbandpass = blowpass.*exp(j*Fc*pi*(0:N));
Channelizer
Create a dsp.Channelizer
object with 4 frequency bands and set the Specification
property to 'Coefficients'
.
chann = dsp.Channelizer('NumFrequencyBands',4,'Specification',"Coefficients");
Pass the complex coefficients to the channelizer. The prototype filter is a bandpass filter with a center frequency of 0.4. The modulated versions of this filter appear with respect to the prototype filter and are wrapped around the frequency range [Fs Fs].
chann.LowpassCoefficients = bbandpass
chann = dsp.Channelizer with properties: NumFrequencyBands: 4 OversamplingRatio: 1 Specification: 'Coefficients' LowpassCoefficients: [1x31 double]
Visualize the frequency response of the channelizer.
fvtool(chann)
The generic analysis filter bank consists of a series of parallel bandpass filters that split an input broadband signal, x(n), into a series of narrow subbands. Each bandpass filter retains a different portion of the input signal. After the bandwidth is reduced by one of the bandpass filters, the signal is downsampled to a lower sampling rate commensurate with the new bandwidth.
To implement the analysis filter bank efficiently, the channelizer uses a prototype lowpass filter.
The prototype lowpass filter has an impulse response of h[n], a normalized two-sided bandwidth of 2π/M, and a cutoff frequency of π/M. M is the number of frequency bands, that is, the branches of the analysis filter bank. This value corresponds to the FFT length that the filter bank uses. M can be high on the order of 2048 or more. The stopband attenuation determines the minimum level of interference (aliasing) from one frequency band to another. The passband ripple must be small so that the input signal is not distorted in the passband.
The prototype lowpass filter corresponds to H0(z) in the filter bank. The first branch of the filter bank contains H0(z) followed by the decimator. The other M – 1 branches contain filters that are modulated versions of the prototype filter. The modulation factor is given by the following equation:
The transfer function of the modulated kth bandpass filter is given by:
This figure shows the frequency response of M filters.
To obtain the frequency response characteristics of the filter Hk(z), where k = 1,..., M−1, uniformly shift the frequency response of the prototype filter, H0(z), by multiples of 2π/M. Each subband filter, Hk(z), {k = 1,..., M – 1}, is derived from the prototype filter.
Following is an equivalent representation of the frequency response diagram with ω ranging from [−π π].
The frequency components in the input signal, x(n), are translated in frequency to baseband by multiplying x(n) with the complex exponentials, , where , and . The resulting product signals are passed through the lowpass filters, H0(z). The output of the lowpass filter is relatively narrow in bandwidth. Downsample the signal commensurate with the new bandwidth. Choose a decimation factor, D ≤ M, where M is the number of branches of the analysis filter bank. When D < M, the channelizer is known as oversampled or non-maximally decimated channelizer.
The figure shows an analysis filter bank that uses the prototype lowpass filter.
y1(n), y2(n), ..., yM-1(n) are narrow subband signals translated into baseband.
The analysis filter bank can be implemented efficiently using the polyphase structure. For more details on the analysis filter bank, see Analysis Filter Bank.
To derive the polyphase structure, start with the transfer function of the prototype lowpass filter:
N+1 is the length of the prototype filter.
You can rearrange this equation as follows:
M is the number of polyphase components.
You can write this equation as:
E0(zM), E1(zM), ..., EM-1(zM) are polyphase components of the prototype lowpass filter, H0(z).
The other filters in the filter bank, Hk(z), where k = 1, ..., M-1, are modulated versions of this prototype filter.
You can write the transfer function of the kth modulated bandpass filter as .
Replacing z with ze-jwk,
N+1 is the length of the kth filter.
In polyphase form, the equation is as follows:
For all M channels in the filter bank, the transfer function, H(z), is given by:
Maximally decimated channelizer (D = M)
When D = M, the channelizer is known as the maximally decimated channelizer or critically sampled channelizer.
Here is the multirate noble identity for decimation, assuming that D = M.
For illustration, consider the first branch of the filter bank that contains the lowpass filter.
Replace H0(z) with its polyphase representation.
After applying the noble identity for decimation, you can replace the delays and the decimation factor with a commutator switch. The switch starts on the first branch and moves in the counter clockwise direction as shown in the following diagram.
For all M channels in the filter bank, the transfer function, H(z), is given by:
The matrix on the left is a discrete Fourier transform (DFT) matrix. With the DFT matrix, the efficient implementation of the lowpass prototype based filter bank looks like the following.
The switch starts on the first branch 0, delivers one sample at a time to each branch, and progresses in the counter clockwise direction through the branches 0, M−1, M−2, all the way up to branch 1. When the first set of M input samples are delivered to the M branches of the polyphase structure, the channelizer computes the first set of output values. Hence, the sample rate at the output of the maximally decimated channelizer is fs/M.
When the next set of input data samples are available, the switch starts at branch 0, and delivers these samples one at a time in the counter clock wise direction. Every time the polyphase structure receives a new set of M input samples, the channelizer computes a new set of output values.
Non-maximally decimated channelizer (D < M)
When D < M, the channelizer is known as the non-maximally decimated channelizer or oversampled channelizer. In this configuration, the output sample rate is different from the channel spacing. In addition to that, the non-maximally decimated channelizers offer increased design freedom, but at the expense of increasing computational cost.
The number of frequency bands, M = RD, where R = 1, 2,…, M, is known as the oversampling ratio, and D is the decimation factor.
When R = 1, M equals D, and the decimator is known as the maximally decimated channelizer. The commutator switch in the filter bank starts at branch 0 and delivers one sample at a time to each branch in the counter clockwise direction. Once all M branches have a data sample, the filter bank computes the output data. For more details, see Maximally decimated channelizer.
When R > 1, the switch starts at the branch (M/R) − 1, loads D samples, delivers one sample at a time to each branch in the counter clockwise direction, and progresses up the stack to branch 0. When a new set of D input samples come in, these samples are delivered to the first set of M/R addresses. The formal contents of these addresses are shifted to the next set of M/R addresses, and this process of data shift continues every time there is a new set of D input samples. All the samples undergo a serpentine shift.
For every D input samples that are fed to the polyphase structure, the channelizer outputs M samples, y0(m), y1(m), … , yM-1(m). This process increases the output sample rate from fs/M in the case of maximally decimated channelizer, to Rfs/M in the case of non-maximally decimated channelizer.
For more details, see [2].
After each D-point data sequence is delivered to the partitioned M-stage polyphase filter, the outputs of the M stages are computed and conditioned for delivery to the M-point FFT. The data shifting through the filter introduces frequency-dependent phase shift. To correct for this phase shift and alias all bands to DC, a circular shift buffer is inserted after the polyphase filters and before the M-point FFT.
With the commutator switch followed by M-stage polyphase filter, circular shift buffer, and a DFT matrix, the efficient implementation of the lowpass prototype-based filter bank looks like the following.
[1] Harris, Fredric J, Multirate Signal Processing for Communication Systems, Prentice Hall PTR, 2004.
[2] Harris, F.J., Chris Dick, and Michael Rice. "Digital Receivers and Transmitters Using Polyphase Filter Banks for Wireless Communications." IEEE® Transactions on Microwave Theory and Techniques. 51, no. 4 (2003).
Usage notes and limitations:
See System Objects in MATLAB Code Generation (MATLAB Coder).
bandedgeFrequencies
| centerFrequencies
| coeffs
| freqz
| fvtool
| getFilters
| polyphase
| tf
dsp.ChannelSynthesizer
| dsp.DyadicAnalysisFilterBank
| dsp.FIRHalfbandDecimator
| dsp.FIRHalfbandInterpolator
| dsp.IIRHalfbandDecimator
You have a modified version of this example. Do you want to open this example with your edits?