Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps.
Fast FFT filter with float input, float output and float taps.
Filter-Delay Combination Block.
The block takes one or two float stream and outputs a complex stream. If only one float stream is input, the real output is a delayed version of this input and the imaginary output is the filtered output. If two floats are connected to the input, then the real output is the delayed version of the first input, and the imaginary output is the filtered output. The delay in the real path accounts for the group delay introduced by the filter in the imaginary path. The filter taps needs to be calculated before initializing this block.
FIR filter with gr_complex input, gr_complex output and gr_complex taps.
FIR filter with gr_complex input, gr_complex output and float taps.
FIR filter with float input, gr_complex output and gr_complex taps.
FIR filter with float input, float output and float taps.
FIR filter with float input, short output and float taps.
FIR filter with short input, gr_complex output and gr_complex taps.
Interpolating mmse filter with gr_complex input, gr_complex output.
Interpolating mmse filter with float input, float output.
FIR filter combined with frequency translation with gr_complex input, gr_complex output and gr_complex taps
This class efficiently combines a frequency translation (typically “down conversion”) with a FIR filter (typically low-pass) and decimation. It is ideally suited for a “channel selection filter” and can be efficiently used to select and decimate a narrow band signal out of wide bandwidth input.
Uses a single input array to produce a single output array. Additional inputs and/or outputs are ignored.
Construct a FIR filter with the given taps and a composite frequency translation that shifts center_freq down to zero Hz. The frequency translation logically comes before the filtering operation.
FIR filter combined with frequency translation with gr_complex input, gr_complex output and float taps
This class efficiently combines a frequency translation (typically “down conversion”) with a FIR filter (typically low-pass) and decimation. It is ideally suited for a “channel selection filter” and can be efficiently used to select and decimate a narrow band signal out of wide bandwidth input.
Uses a single input array to produce a single output array. Additional inputs and/or outputs are ignored.
Construct a FIR filter with the given taps and a composite frequency translation that shifts center_freq down to zero Hz. The frequency translation logically comes before the filtering operation.
FIR filter combined with frequency translation with float input, gr_complex output and gr_complex taps
This class efficiently combines a frequency translation (typically “down conversion”) with a FIR filter (typically low-pass) and decimation. It is ideally suited for a “channel selection filter” and can be efficiently used to select and decimate a narrow band signal out of wide bandwidth input.
Uses a single input array to produce a single output array. Additional inputs and/or outputs are ignored.
Construct a FIR filter with the given taps and a composite frequency translation that shifts center_freq down to zero Hz. The frequency translation logically comes before the filtering operation.
FIR filter combined with frequency translation with float input, gr_complex output and float taps
This class efficiently combines a frequency translation (typically “down conversion”) with a FIR filter (typically low-pass) and decimation. It is ideally suited for a “channel selection filter” and can be efficiently used to select and decimate a narrow band signal out of wide bandwidth input.
Uses a single input array to produce a single output array. Additional inputs and/or outputs are ignored.
Construct a FIR filter with the given taps and a composite frequency translation that shifts center_freq down to zero Hz. The frequency translation logically comes before the filtering operation.
FIR filter combined with frequency translation with short input, gr_complex output and gr_complex taps
This class efficiently combines a frequency translation (typically “down conversion”) with a FIR filter (typically low-pass) and decimation. It is ideally suited for a “channel selection filter” and can be efficiently used to select and decimate a narrow band signal out of wide bandwidth input.
Uses a single input array to produce a single output array. Additional inputs and/or outputs are ignored.
Construct a FIR filter with the given taps and a composite frequency translation that shifts center_freq down to zero Hz. The frequency translation logically comes before the filtering operation.
FIR filter combined with frequency translation with short input, gr_complex output and float taps
This class efficiently combines a frequency translation (typically “down conversion”) with a FIR filter (typically low-pass) and decimation. It is ideally suited for a “channel selection filter” and can be efficiently used to select and decimate a narrow band signal out of wide bandwidth input.
Uses a single input array to produce a single output array. Additional inputs and/or outputs are ignored.
Construct a FIR filter with the given taps and a composite frequency translation that shifts center_freq down to zero Hz. The frequency translation logically comes before the filtering operation.
Hilbert transformer.
real output is input appropriately delayed. imaginary output is hilbert filtered (90 degree phase shift) version of input.
IIR filter with float input, float output and double taps
This filter uses the Direct Form I implementation, where contains the feed-forward taps, and the feedback ones.
The input and output satisfy a difference equation of the form
y[n] - sum_{k=1}^{M} a_k y[n-k] = sum_{k=0}^{N} b_k x[n-k]
with the corresponding rational system function
H(z) = frac{sum_{k=0}^{M} b_k z^{-k}}{1 - sum_{k=1}^{N} a_k z^{-k}}
Note that some texts define the system function with a + in the denominator. If you’re using that convention, you’ll need to negate the feedback taps.
Interpolating FIR filter with gr_complex input, gr_complex output and gr_complex taps.
Interpolating FIR filter with gr_complex input, gr_complex output and float taps.
Interpolating FIR filter with float input, gr_complex output and gr_complex taps.
Interpolating FIR filter with float input, float output and float taps.
Interpolating FIR filter with float input, short output and float taps.
Interpolating FIR filter with short input, gr_complex output and gr_complex taps.
Rational Resampling Polyphase FIR filter with gr_complex input, gr_complex output and gr_complex taps.
Rational Resampling Polyphase FIR filter with gr_complex input, gr_complex output and float taps.
Rational Resampling Polyphase FIR filter with float input, gr_complex output and gr_complex taps.
Rational Resampling Polyphase FIR filter with float input, float output and float taps.
Rational Resampling Polyphase FIR filter with float input, short output and float taps.
Rational Resampling Polyphase FIR filter with short input, gr_complex output and gr_complex taps.
single pole IIR filter with complex input, complex output
The input and output satisfy a difference equation of the form
y[n] - (1-alpha) y[n-1] = alpha x[n]
with the corresponding rational system function
H(z) = frac{alpha}{1 - (1-alpha) z^{-1}}
Note that some texts define the system function with a + in the denominator. If you’re using that convention, you’ll need to negate the feedback tap.
single pole IIR filter with float input, float output
The input and output satisfy a difference equation of the form
y[n] - (1-alpha) y[n-1] = alpha x[n]
with the corresponding rational system function
H(z) = frac{alpha}{1 - (1-alpha) z^{-1}}
Note that some texts define the system function with a + in the denominator. If you’re using that convention, you’ll need to negate the feedback tap.
output is the moving sum of the last N samples, scaled by the scale factor
max_iter limits how long we go without flushing the accumulator This is necessary to avoid numerical instability for float and complex.
output is the moving sum of the last N samples, scaled by the scale factor
max_iter limits how long we go without flushing the accumulator This is necessary to avoid numerical instability for float and complex.
output is the moving sum of the last N samples, scaled by the scale factor
max_iter limits how long we go without flushing the accumulator This is necessary to avoid numerical instability for float and complex.
output is the moving sum of the last N samples, scaled by the scale factor
max_iter limits how long we go without flushing the accumulator This is necessary to avoid numerical instability for float and complex.
Polyphase filterbank arbitrary resampler with gr_complex input, gr_complex output and float taps.
This block takes in a signal stream and performs arbitrary resampling. The resampling rate can be any real number . The resampling is done by constructing filters where is the interpolation rate. We then calculate where .
Using and , we can perform rational resampling where is a rational number close to the input rate where we have filters and we cycle through them as a polyphase filterbank with a stride of so that .
To get the arbitrary rate, we want to interpolate between two points. For each value out, we take an output from the current filter, , and the next filter and then linearly interpolate between the two based on the real resampling rate we want.
The linear interpolation only provides us with an approximation to the real sampling rate specified. The error is a quantization error between the two filters we used as our interpolation points. To this end, the number of filters, , used determines the quantization error; the larger , the smaller the noise. You can design for a specified noise floor by setting the filter size (parameters ). The size defaults to 32 filters, which is about as good as most implementations need.
The trick with designing this filter is in how to specify the taps of the prototype filter. Like the PFB interpolator, the taps are specified using the interpolated filter rate. In this case, that rate is the input sample rate multiplied by the number of filters in the filterbank, which is also the interpolation rate. All other values should be relative to this rate.
For example, for a 32-filter arbitrary resampler and using the GNU Radio’s firdes utility to build the filter, we build a low-pass filter with a sampling rate of , a 3-dB bandwidth of and a transition bandwidth of . We can also specify the out-of-band attenuation to use, , and the filter window function (a Blackman-harris window in this case). The first input is the gain of the filter, which we specify here as the interpolation rate ().
The theory behind this block can be found in Chapter 7.5 of the following book.
Build the polyphase filterbank arbitray resampler.
Print all of the filterbank taps to screen.
Polyphase filterbank channelizer with gr_complex input, gr_complex output and float taps.
This block takes in complex inputs and channelizes it to channels of equal bandwidth. Each of the resulting channels is decimated to the new rate that is the input sampling rate divided by the number of channels, .
The PFB channelizer code takes the taps generated above and builds a set of filters. The set contains number of filters and each filter contains ceil(taps.size()/decim) number of taps. Each tap from the filter prototype is sequentially inserted into the next filter. When all of the input taps are used, the remaining filters in the filterbank are filled out with 0’s to make sure each filter has the same number of taps.
Each filter operates using the gr_fir filter classs of GNU Radio, which takes the input stream at and performs the inner product calculation to where is the number of filter taps. To efficiently handle this in the GNU Radio structure, each filter input must come from its own input stream. So the channelizer must be provided with streams where the input stream has been deinterleaved. This is most easily done using the gr_stream_to_streams block.
The output is then produced as a vector, where index in the vector is the next sample from the th channel. This is most easily handled by sending the output to a gr_vector_to_streams block to handle the conversion and passing streams out.
The input and output formatting is done using a hier_block2 called pfb_channelizer_ccf. This can take in a single stream and outputs streams based on the behavior described above.
The filter’s taps should be based on the input sampling rate.
For example, using the GNU Radio’s firdes utility to building filters, we build a low-pass filter with a sampling rate of , a 3-dB bandwidth of and a transition bandwidth of . We can also specify the out-of-band attenuation to use, , and the filter window function (a Blackman-harris window in this case). The first input is the gain of the filter, which we specify here as unity.
The filter output can also be overs ampled. The over sampling rate is the ratio of the the actual output sampling rate to the normal output sampling rate. It must be rationally related to the number of channels as N/i for i in [1,N], which gives an outputsample rate of [fs/N, fs] where fs is the input sample rate and N is the number of channels.
For example, for 6 channels with fs = 6000 Hz, the normal rate is 6000/6 = 1000 Hz. Allowable oversampling rates are 6/6, 6/5, 6/4, 6/3, 6/2, and 6/1 where the output sample rate of a 6/1 oversample ratio is 6000 Hz, or 6 times the normal 1000 Hz. A rate of 6/5 = 1.2, so the output rate would be 1200 Hz.
The theory behind this block can be found in Chapter 6 of the following book.
Build the polyphase filterbank decimator. For example, for 6 channels with fs = 6000 Hz, the normal rate is 6000/6 = 1000 Hz. Allowable oversampling rates are 6/6, 6/5, 6/4, 6/3, 6/2, and 6/1 where the output sample rate of a 6/1 oversample ratio is 6000 Hz, or 6 times the normal 1000 Hz.
Gets the current channel map.
Print all of the filterbank taps to screen.
Set the channel map. Channels are numbers as:
N/2+1 | ... | N-1 | 0 | 1 | 2 | ... | N/2 <——————- 0 ——————–> freq
So output stream 0 comes from channel 0, etc. Setting a new channel map allows the user to specify which channel in frequency he/she wants to got to which output stream.
The map should have the same number of elements as the number of output connections from the block. The minimum value of the map is 0 (for the 0th channel) and the maximum number is N-1 where N is the number of channels.
We specify M as the number of output connections made where M <= N, so only M out of N channels are driven to an output stream. The number of items in the channel map should be at least M long. If there are more channels specified, any value in the map over M-1 will be ignored. If the size of the map is less than M the behavior is unknown (we don’t wish to check every entry into the work function).
This means that if the channelizer is splitting the signal up into N channels but only M channels are specified in the map (where M <= N), then M output streams must be connected and the map and the channel numbers used must be less than N-1. Output channel number can be reused, too. By default, the map is [0...M-1] with M = N.
Resets the filterbank’s filter taps with the new prototype filter
Return a vector<vector<>> of the filterbank taps
Timing synchronizer using polyphase filterbanks.
This block performs timing synchronization for PAM signals by minimizing the derivative of the filtered signal, which in turn maximizes the SNR and minimizes ISI.
This approach works by setting up two filterbanks; one filterbank contains the signal’s pulse shaping matched filter (such as a root raised cosine filter), where each branch of the filterbank contains a different phase of the filter. The second filterbank contains the derivatives of the filters in the first filterbank. Thinking of this in the time domain, the first filterbank contains filters that have a sinc shape to them. We want to align the output signal to be sampled at exactly the peak of the sinc shape. The derivative of the sinc contains a zero at the maximum point of the sinc (sinc(0) = 1, sinc(0)’ = 0). Furthermore, the region around the zero point is relatively linear. We make use of this fact to generate the error signal.
If the signal out of the derivative filters is d_i[n] for the ith filter, and the output of the matched filter is x_i[n], we calculate the error as: e[n] = (Re{x_i[n]} * Re{d_i[n]} + Im{x_i[n]} * Im{d_i[n]}) / 2.0 This equation averages the error in the real and imaginary parts. There are two reasons we multiply by the signal itself. First, if the symbol could be positive or negative going, but we want the error term to always tell us to go in the same direction depending on which side of the zero point we are on. The sign of x_i[n] adjusts the error term to do this. Second, the magnitude of x_i[n] scales the error term depending on the symbol’s amplitude, so larger signals give us a stronger error term because we have more confidence in that symbol’s value. Using the magnitude of x_i[n] instead of just the sign is especially good for signals with low SNR.
The error signal, e[n], gives us a value proportional to how far away from the zero point we are in the derivative signal. We want to drive this value to zero, so we set up a second order loop. We have two variables for this loop; d_k is the filter number in the filterbank we are on and d_rate is the rate which we travel through the filters in the steady state. That is, due to the natural clock differences between the transmitter and receiver, d_rate represents that difference and would traverse the filter phase paths to keep the receiver locked. Thinking of this as a second-order PLL, the d_rate is the frequency and d_k is the phase. So we update d_rate and d_k using the standard loop equations based on two error signals, d_alpha and d_beta. We have these two values set based on each other for a critically damped system, so in the block constructor, we just ask for “gain,” which is d_alpha while d_beta is equal to (gain^2)/4.
The block’s parameters are:
Build the polyphase filterbank timing synchronizer.
Returns the loop gain alpha.
Returns the loop gain beta.
Returns the taps of the matched filter for a particular channel
Returns the current clock rate.
Returns the loop damping factor.
Returns the taps in the derivative filter for a particular channel
Returns all of the taps of the derivative filter
Return the derivative filter taps as a formatted string for printing
Returns the loop bandwidth.
Returns all of the taps of the matched filter
Return the taps as a formatted string for printing
Set the loop gain alpha.
Set’s the loop filter’s alpha gain parameter.
This value should really only be set by adjusting the loop bandwidth and damping factor.
Set the loop gain beta.
Set’s the loop filter’s beta gain parameter.
This value should really only be set by adjusting the loop bandwidth and damping factor.
Set the loop damping factor.
Set the loop filter’s damping factor to . The damping factor should be sqrt(2)/2.0 for critically damped systems. Set it to anything else only if you know what you are doing. It must be a number between 0 and 1.
When a new damping factor is set, the gains, alpha and beta, of the loop are recalculated by a call to update_gains().
Set the loop bandwidth.
Set the loop filter’s bandwidth to . This should be between 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive number.
When a new damping factor is set, the gains, alpha and beta, of the loop are recalculated by a call to update_gains().
Set the maximum deviation from 0 d_rate can have
Resets the filterbank’s filter taps with the new prototype filter
Timing synchronizer using polyphase filterbanks.
This block performs timing synchronization for PAM signals by minimizing the derivative of the filtered signal, which in turn maximizes the SNR and minimizes ISI.
This approach works by setting up two filterbanks; one filterbank contains the signal’s pulse shaping matched filter (such as a root raised cosine filter), where each branch of the filterbank contains a different phase of the filter. The second filterbank contains the derivatives of the filters in the first filterbank. Thinking of this in the time domain, the first filterbank contains filters that have a sinc shape to them. We want to align the output signal to be sampled at exactly the peak of the sinc shape. The derivative of the sinc contains a zero at the maximum point of the sinc (sinc(0) = 1, sinc(0)’ = 0). Furthermore, the region around the zero point is relatively linear. We make use of this fact to generate the error signal.
If the signal out of the derivative filters is d_i[n] for the ith filter, and the output of the matched filter is x_i[n], we calculate the error as: e[n] = (Re{x_i[n]} * Re{d_i[n]} + Im{x_i[n]} * Im{d_i[n]}) / 2.0 This equation averages the error in the real and imaginary parts. There are two reasons we multiply by the signal itself. First, if the symbol could be positive or negative going, but we want the error term to always tell us to go in the same direction depending on which side of the zero point we are on. The sign of x_i[n] adjusts the error term to do this. Second, the magnitude of x_i[n] scales the error term depending on the symbol’s amplitude, so larger signals give us a stronger error term because we have more confidence in that symbol’s value. Using the magnitude of x_i[n] instead of just the sign is especially good for signals with low SNR.
The error signal, e[n], gives us a value proportional to how far away from the zero point we are in the derivative signal. We want to drive this value to zero, so we set up a second order loop. We have two variables for this loop; d_k is the filter number in the filterbank we are on and d_rate is the rate which we travel through the filters in the steady state. That is, due to the natural clock differences between the transmitter and receiver, d_rate represents that difference and would traverse the filter phase paths to keep the receiver locked. Thinking of this as a second-order PLL, the d_rate is the frequency and d_k is the phase. So we update d_rate and d_k using the standard loop equations based on two error signals, d_alpha and d_beta. We have these two values set based on each other for a critically damped system, so in the block constructor, we just ask for “gain,” which is d_alpha while d_beta is equal to (gain^2)/4.
The block’s parameters are:
Build the polyphase filterbank timing synchronizer.
Returns the taps of the matched filter
Returns the taps in the derivative filter
Print all of the filterbank taps of the derivative filter to screen.
Print all of the filterbank taps to screen.
Set the gain value alpha for the control loop
Set the gain value beta for the control loop
Set the maximum deviation from 0 d_rate can have
Resets the filterbank’s filter taps with the new prototype filter
Polyphase filterbank bandpass decimator with gr_complex input, gr_complex output and float taps.
This block takes in a signal stream and performs interger down- sampling (decimation) with a polyphase filterbank. The first input is the integer specifying how much to decimate by. The second input is a vector (Python list) of floating-point taps of the prototype filter. The third input specifies the channel to extract. By default, the zeroth channel is used, which is the baseband channel (first Nyquist zone).
The parameter specifies which channel to use since this class is capable of bandpass decimation. Given a complex input stream at a sampling rate of and a decimation rate of , the input frequency domain is split into channels that represent the Nyquist zones. Using the polyphase filterbank, we can select any one of these channels to decimate.
The output signal will be the basebanded and decimated signal from that channel. This concept is very similar to the PFB channelizer (see gr_pfb_channelizer_ccf) where only a single channel is extracted at a time.
The filter’s taps should be based on the sampling rate before decimation.
For example, using the GNU Radio’s firdes utility to building filters, we build a low-pass filter with a sampling rate of , a 3-dB bandwidth of and a transition bandwidth of . We can also specify the out-of-band attenuation to use, , and the filter window function (a Blackman-harris window in this case). The first input is the gain of the filter, which we specify here as unity.
The PFB decimator code takes the taps generated above and builds a set of filters. The set contains number of filters and each filter contains ceil(taps.size()/decim) number of taps. Each tap from the filter prototype is sequentially inserted into the next filter. When all of the input taps are used, the remaining filters in the filterbank are filled out with 0’s to make sure each filter has the same number of taps.
The theory behind this block can be found in Chapter 6 of the following book.
Build the polyphase filterbank decimator.
Resets the filterbank’s filter taps with the new prototype filter
Polyphase filterbank interpolator with gr_complex input, gr_complex output and float taps.
This block takes in a signal stream and performs interger up- sampling (interpolation) with a polyphase filterbank. The first input is the integer specifying how much to interpolate by. The second input is a vector (Python list) of floating-point taps of the prototype filter.
The filter’s taps should be based on the interpolation rate specified. That is, the bandwidth specified is relative to the bandwidth after interpolation.
For example, using the GNU Radio’s firdes utility to building filters, we build a low-pass filter with a sampling rate of , a 3-dB bandwidth of and a transition bandwidth of . We can also specify the out-of-band attenuation to use, ATT, and the filter window function (a Blackman-harris window in this case). The first input is the gain, which is also specified as the interpolation rate so that the output levels are the same as the input (this creates an overall increase in power).
The PFB interpolator code takes the taps generated above and builds a set of filters. The set contains number of filters and each filter contains ceil(taps.size()/interp) number of taps. Each tap from the filter prototype is sequentially inserted into the next filter. When all of the input taps are used, the remaining filters in the filterbank are filled out with 0’s to make sure each filter has the same number of taps.
The theory behind this block can be found in Chapter 7.1 of the following book.
Build the polyphase filterbank interpolator.
Print all of the filterbank taps to screen.
Resets the filterbank’s filter taps with the new prototype filter