def __init__(self, resampler_base, interpolation, decimation, taps=None, fractional_bw=None): """ Rational resampling polyphase FIR filter. Either taps or fractional_bw may be specified, but not both. If neither is specified, a reasonable default, 0.4, is used as the fractional_bw. Args: interpolation: interpolation factor (integer > 0) decimation: decimation factor (integer > 0) taps: optional filter coefficients (sequence) fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4) (float) """ if not isinstance(interpolation, int) or interpolation < 1: raise ValueError("interpolation must be an integer >= 1") if not isinstance(decimation, int) or decimation < 1: raise ValueError("decimation must be an integer >= 1") if taps is None and fractional_bw is None: fractional_bw = 0.4 d = gru.gcd(interpolation, decimation) # If we have user-provided taps and the interp and decim # values have a common divisor, we don't reduce these values # by the GCD but issue a warning to the user that this might # increase the complexity of the filter. if taps and (d > 1): gr.log.info( "Rational resampler has user-provided taps but interpolation ({0}) and decimation ({1}) have a GCD of {2}, which increases the complexity of the filterbank. Consider reducing these values by the GCD." .format(interpolation, decimation, d)) # If we don't have user-provided taps, reduce the interp and # decim values by the GCD (if there is one) and then define # the taps from these new values. if taps is None: interpolation = interpolation // d decimation = decimation // d taps = design_filter(interpolation, decimation, fractional_bw) self.resampler = resampler_base(interpolation, decimation, taps) gr.hier_block2.__init__( self, "rational_resampler", gr.io_signature( 1, 1, self.resampler.input_signature().sizeof_stream_item(0)), gr.io_signature( 1, 1, self.resampler.output_signature().sizeof_stream_item(0))) self.connect(self, self.resampler, self)
def __init__(self, resampler_base, interpolation, decimation, taps=None, fractional_bw=None): """ Rational resampling polyphase FIR filter. Either taps or fractional_bw may be specified, but not both. If neither is specified, a reasonable default, 0.4, is used as the fractional_bw. @param interpolation: interpolation factor @type interpolation: integer > 0 @param decimation: decimation factor @type decimation: integer > 0 @param taps: optional filter coefficients @type taps: sequence @param fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4) @type fractional_bw: float """ if not isinstance(interpolation, int) or interpolation < 1: raise ValueError, "interpolation must be an integer >= 1" if not isinstance(decimation, int) or decimation < 1: raise ValueError, "decimation must be an integer >= 1" if taps is None and fractional_bw is None: fractional_bw = 0.4 d = gru.gcd(interpolation, decimation) interpolation = interpolation // d decimation = decimation // d if taps is None: taps = design_filter(interpolation, decimation, fractional_bw) resampler = resampler_base(interpolation, decimation, taps) gr.hier_block2.__init__( self, "rational_resampler", gr.io_signature(1, 1, resampler.input_signature().sizeof_stream_item(0)), gr.io_signature( 1, 1, resampler.output_signature().sizeof_stream_item(0))) self.connect(self, resampler, self)
def __init__(self, resampler_base, interpolation, decimation, taps=None, fractional_bw=None): """ Rational resampling polyphase FIR filter. Either taps or fractional_bw may be specified, but not both. If neither is specified, a reasonable default, 0.4, is used as the fractional_bw. Args: interpolation: interpolation factor (integer > 0) decimation: decimation factor (integer > 0) taps: optional filter coefficients (sequence) fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4) (float) """ if not isinstance(interpolation, int) or interpolation < 1: raise ValueError, "interpolation must be an integer >= 1" if not isinstance(decimation, int) or decimation < 1: raise ValueError, "decimation must be an integer >= 1" if taps is None and fractional_bw is None: fractional_bw = 0.4 d = gru.gcd(interpolation, decimation) # If we have user-provided taps and the interp and decim # values have a common divisor, we don't reduce these values # by the GCD but issue a warning to the user that this might # increase the complexity of the filter. if taps and (d > 1): gr.log.info("Rational resampler has user-provided taps but interpolation ({0}) and decimation ({1}) have a GCD of {2}, which increases the complexity of the filterbank. Consider reducing these values by the GCD.".format(interpolation, decimation, d)) # If we don't have user-provided taps, reduce the interp and # decim values by the GCD (if there is one) and then define # the taps from these new values. if taps is None: interpolation = interpolation // d decimation = decimation // d taps = design_filter(interpolation, decimation, fractional_bw) self.resampler = resampler_base(interpolation, decimation, taps) gr.hier_block2.__init__(self, "rational_resampler", gr.io_signature(1, 1, self.resampler.input_signature().sizeof_stream_item(0)), gr.io_signature(1, 1, self.resampler.output_signature().sizeof_stream_item(0))) self.connect(self, self.resampler, self)
def __init__(self, resampler_base, interpolation, decimation, taps=None, fractional_bw=None): """ Rational resampling polyphase FIR filter. Either taps or fractional_bw may be specified, but not both. If neither is specified, a reasonable default, 0.4, is used as the fractional_bw. @param interpolation: interpolation factor @type interpolation: integer > 0 @param decimation: decimation factor @type decimation: integer > 0 @param taps: optional filter coefficients @type taps: sequence @param fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4) @type fractional_bw: float """ if not isinstance(interpolation, int) or interpolation < 1: raise ValueError, "interpolation must be an integer >= 1" if not isinstance(decimation, int) or decimation < 1: raise ValueError, "decimation must be an integer >= 1" if taps is None and fractional_bw is None: fractional_bw = 0.4 d = gru.gcd(interpolation, decimation) interpolation = interpolation // d decimation = decimation // d if taps is None: taps = design_filter(interpolation, decimation, fractional_bw) resampler = resampler_base(interpolation, decimation, taps) gr.hier_block2.__init__(self, "rational_resampler", gr.io_signature(1, 1, resampler.input_signature().sizeof_stream_item(0)), gr.io_signature(1, 1, resampler.output_signature().sizeof_stream_item(0))) self.connect(self, resampler, self)
def __init__(self, num_streams, fs_in, delta_f_in): gr.hier_block2.__init__( self, 'coh_stream_synth', gr.io_signature(num_streams, num_streams, gr.sizeof_gr_complex), gr.io_signature(2 * num_streams, 2 * num_streams, gr.sizeof_gr_complex)) assert (num_streams >= 2 and num_streams <= 6) fsr = delta_f_in factor = gru.gcd(fsr, fs_in) interp = fsr / factor decim = fs_in / factor self._align_streams = align_streams(num_streams, True) self._rotators = rotator_proxy(num_streams, fs_in, delta_f_in) self._taps_resampler = taps_resampler = filter.firdes.low_pass_2( gain=2 * interp, sampling_freq=2.0, cutoff_freq=0.5 / decim, transition_width=0.4 / decim, attenuation_dB=80.0, window=filter.firdes.WIN_BLACKMAN_HARRIS) self._rational_resamplers = [ filter.rational_resampler_ccc(interpolation=2 * interp, decimation=decim, taps=(taps_resampler), fractional_bw=None) for _ in range(num_streams) ] self._taps_pfb = taps_pfb = filter.firdes.low_pass_2( gain=4, sampling_freq=4 * fsr, cutoff_freq=0.5 * fsr, transition_width=0.2 * fsr, attenuation_dB=80.0, window=filter.firdes.WIN_BLACKMAN_HARRIS) self._pfb_synthesizer = filter.pfb_synthesizer_ccf(numchans=6, taps=(taps_pfb), twox=True) channel_map = [] if num_streams == 2: channel_map = [0, 1] if num_streams == 3: channel_map = [7, 0, 1] if num_streams == 4: channel_map = [7, 0, 1, 2] if num_streams == 5: channel_map = [10, 11, 0, 1, 2] if num_streams == 6: channel_map = [6, 7, 0, 1, 2, 3] self._pfb_synthesizer.set_channel_map(channel_map) self._poc = [ phase_offset_corrector(2 * delta_f_in) for _ in range(1, num_streams) ] for i in range(num_streams): self.connect((self, i), (self._align_streams, i), (self._rotators, i), (self._rotators.get(i)), (self._rational_resamplers[i])) ## the phase offset corrector are cascading: ## #0 ---------------------- 0 self.connect((self._rational_resamplers[0]), (self._pfb_synthesizer, 0)) ## (#0,#1) -> poc[0] ------- 1 self.connect((self._rational_resamplers[0]), (self._poc[0], 0)) self.connect((self._rational_resamplers[1]), (self._poc[0], 1)) self.connect((self._poc[0], 0), (self._pfb_synthesizer, 1)) ## (poc[0],#2) -> poc[1] --- 2 ## (poc[1],#3) -> poc[2] --- 3 ## ... for i in range(2, num_streams): self.connect((self._poc[i - 2], 0), (self._poc[i - 1], 0)) self.connect((self._rational_resamplers[i]), (self._poc[i - 1], 1)) self.connect((self._poc[i - 1], 0), (self._pfb_synthesizer, i)) ## resampled coherent input streams + rel. phase offsets self.connect((self._rational_resamplers[0]), (self, 1)) for i in range(1, num_streams): self.connect((self._poc[i - 1], 0), (self, 1 + i)) self.connect((self._poc[i - 1], 1), (self, num_streams + i)) ## combined IQ output stream ## out: 4*delta_f_in if num_streams <= 3 else 8*delta_f_in self._final_processing = final_processing(num_streams, delta_f_in) self.connect((self._pfb_synthesizer, 0), (self._final_processing), (self, 0)) ##self.msg_connect((self._align_streams.get_find_offsets(), 'fs'), (self._rotators, 'fs')) self.msg_connect((self._align_streams, 'fs'), (self._rotators, 'fs'))