def __init__(self, modulator, audio_rate, rf_rate, freq): modulator = IModulator(modulator) gr.hier_block2.__init__( self, 'SimulatedChannel', gr.io_signature(1, 1, gr.sizeof_float * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) self.__freq = freq self.__rf_rate = rf_rate self.__modulator = modulator modulator_input_type = modulator.get_input_type() if modulator_input_type.get_kind() == 'MONO': audio_resampler = make_resampler(audio_rate, modulator_input_type.get_sample_rate()) self.connect(self, audio_resampler, modulator) elif modulator_input_type.get_kind() == 'NONE': self.connect(self, blocks.null_sink(gr.sizeof_float)) else: raise Exception('don\'t know how to supply input of type %s' % modulator_input_type) rf_resampler = rational_resampler.rational_resampler_ccf( interpolation=int(rf_rate), decimation=int(modulator.get_output_type().get_sample_rate())) self.__rotator = blocks.rotator_cc(rotator_inc(rate=rf_rate, shift=freq)) self.__mult = blocks.multiply_const_cc(dB(-10)) self.connect(modulator, rf_resampler, self.__rotator, self.__mult, self)
def __init__(self, modulator, audio_rate, rf_rate, freq): modulator = IModulator(modulator) gr.hier_block2.__init__( self, 'SimulatedChannel', gr.io_signature(1, 1, gr.sizeof_float * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) self.__freq = freq self.__rf_rate = rf_rate self.__modulator = modulator modulator_input_type = modulator.get_input_type() if modulator_input_type.get_kind() == 'MONO': audio_resampler = make_resampler( audio_rate, modulator_input_type.get_sample_rate()) self.connect(self, audio_resampler, modulator) elif modulator_input_type.get_kind() == 'NONE': self.connect(self, blocks.null_sink(gr.sizeof_float)) else: raise Exception('don\'t know how to supply input of type %s' % modulator_input_type) rf_resampler = rational_resampler.rational_resampler_ccf( interpolation=int(rf_rate), decimation=int(modulator.get_output_type().get_sample_rate())) self.__rotator = blocks.rotator_cc( rotator_inc(rate=rf_rate, shift=freq)) self.__mult = blocks.multiply_const_cc(dB(-10)) self.connect(modulator, rf_resampler, self.__rotator, self.__mult, self)
def __init__(self, modulator, audio_rate, rf_rate, freq): modulator = IModulator(modulator) gr.hier_block2.__init__( self, 'SimulatedChannel', gr.io_signature(1, 1, gr.sizeof_float * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) self.__freq = freq self.__rf_rate = rf_rate self.modulator = modulator # exported audio_resampler = make_resampler(audio_rate, modulator.get_input_type().get_sample_rate()) rf_resampler = rational_resampler.rational_resampler_ccf( interpolation=int(rf_rate), decimation=int(modulator.get_output_type().get_sample_rate())) self.__rotator = blocks.rotator_cc(rotator_inc(rate=rf_rate, shift=freq)) self.__mult = blocks.multiply_const_cc(10.0 ** -1) self.connect(self, audio_resampler, modulator, rf_resampler, self.__rotator, self.__mult, self)
def __init__(self, name='Multistage Channel Filter', input_rate=0, output_rate=0, cutoff_freq=0, transition_width=0, center_freq=0): assert input_rate > 0 assert output_rate > 0 assert cutoff_freq > 0 assert transition_width > 0 # cf. firdes.sanity_check_1f (which is private) # TODO better errors for other cases if cutoff_freq > output_rate / 2: # early check for better errors since our cascaded filters might be cryptically nonsense raise ValueError( 'cutoff_freq (%s) is too high for output_rate (%s)' % (cutoff_freq, output_rate)) gr.hier_block2.__init__( self, name, gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) self.cutoff_freq = cutoff_freq self.transition_width = transition_width total_decimation = max(1, int(input_rate // output_rate)) using_rational_resampler = _use_rational_resampler and input_rate % 1 == 0 and output_rate % 1 == 0 if using_rational_resampler: # If using rational resampler, don't decimate to the point that we get a fractional rate, if possible. input_rate = int(input_rate) output_rate = int(output_rate) if input_rate > output_rate: total_decimation = input_rate // small_factor_at_least( input_rate, output_rate) # print input_rate / total_decimation, total_decimation, input_rate, output_rate, input_rate // gcd(input_rate, output_rate) # TODO: Don't re-factorize unnecessarily stage_decimations = factorize(total_decimation) stage_decimations.reverse() self.stages = [] # loop variables prev_block = self stage_input_rate = input_rate last_index = len(stage_decimations) - 1 if len(stage_decimations) == 0: # interpolation or nothing -- don't put it in the stages # TODO: consider using rotator block instead (has different API) self.freq_filter_block = grfilter.freq_xlating_fir_filter_ccc( 1, [1], center_freq, stage_input_rate) self.connect(prev_block, self.freq_filter_block) prev_block = self.freq_filter_block else: # decimation for i, stage_decimation in enumerate(stage_decimations): next_rate = stage_input_rate / stage_decimation if i == 0: stage_filter = grfilter.freq_xlating_fir_filter_ccc( stage_decimation, [0], # placeholder center_freq, stage_input_rate) self.freq_filter_block = stage_filter else: taps = self.__stage_taps(i == last_index, stage_input_rate, next_rate) if len(taps) > 10: stage_filter = grfilter.fft_filter_ccc( stage_decimation, taps, 1) else: stage_filter = grfilter.fir_filter_ccc( stage_decimation, taps) self.stages.append((stage_filter, stage_input_rate, next_rate)) self.connect(prev_block, stage_filter) prev_block = stage_filter stage_input_rate = next_rate # final connection and resampling if stage_input_rate == output_rate: # exact multiple, no fractional resampling needed self.connect(prev_block, self) self.__resampler_explanation = 'No final resampler stage.' else: # TODO: systematically combine resampler with final filter stage if using_rational_resampler: if stage_input_rate % 1 != 0: raise Exception("shouldn't happen", stage_input_rate) stage_input_rate = int( stage_input_rate) # because of float division above common = gcd(output_rate, stage_input_rate) interpolation = output_rate // common decimation = stage_input_rate // common self.__resampler_explanation = 'rational_resampler by %s/%s (stage rates %s/%s)' % ( interpolation, decimation, output_rate, stage_input_rate) resampler = rational_resampler.rational_resampler_ccf( interpolation=interpolation, decimation=decimation) else: # TODO: cache filter computation as optfir is used and takes a noticeable time self.__resampler_explanation = 'arb_resampler %s/%s = %s' % ( output_rate, stage_input_rate, float(output_rate) / stage_input_rate) resampler = pfb.arb_resampler_ccf( float(output_rate) / stage_input_rate) self.connect(prev_block, resampler, self) # TODO: Shouldn't be necessary since we compute the taps in the loop above... self.__do_taps()
def __init__(self, name='Multistage Channel Filter', input_rate=0, output_rate=0, cutoff_freq=0, transition_width=0, center_freq=0): assert input_rate > 0 assert output_rate > 0 assert cutoff_freq > 0 assert transition_width > 0 # cf. firdes.sanity_check_1f (which is private) # TODO better errors for other cases if cutoff_freq > output_rate / 2: # early check for better errors since our cascaded filters might be cryptically nonsense raise ValueError('cutoff_freq (%s) is too high for output_rate (%s)' % (cutoff_freq, output_rate)) gr.hier_block2.__init__( self, name, gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) self.cutoff_freq = cutoff_freq self.transition_width = transition_width total_decimation = max(1, int(input_rate // output_rate)) using_rational_resampler = _use_rational_resampler and input_rate % 1 == 0 and output_rate % 1 == 0 if using_rational_resampler: # If using rational resampler, don't decimate to the point that we get a fractional rate, if possible. input_rate = int(input_rate) output_rate = int(output_rate) if input_rate > output_rate: total_decimation = input_rate // small_factor_at_least(input_rate, output_rate) # print input_rate / total_decimation, total_decimation, input_rate, output_rate, input_rate // gcd(input_rate, output_rate) # TODO: Don't re-factorize unnecessarily stage_decimations = factorize(total_decimation) stage_decimations.reverse() self.stages = [] # loop variables prev_block = self stage_input_rate = input_rate last_index = len(stage_decimations) - 1 if len(stage_decimations) == 0: # interpolation or nothing -- don't put it in the stages # TODO: consider using rotator block instead (has different API) self.freq_filter_block = grfilter.freq_xlating_fir_filter_ccc( 1, [1], center_freq, stage_input_rate) self.connect(prev_block, self.freq_filter_block) prev_block = self.freq_filter_block else: # decimation for i, stage_decimation in enumerate(stage_decimations): next_rate = stage_input_rate / stage_decimation if i == 0: stage_filter = grfilter.freq_xlating_fir_filter_ccc( stage_decimation, [0], # placeholder center_freq, stage_input_rate) self.freq_filter_block = stage_filter else: taps = self.__stage_taps(i == last_index, stage_input_rate, next_rate) if len(taps) > 10: stage_filter = grfilter.fft_filter_ccc(stage_decimation, taps, 1) else: stage_filter = grfilter.fir_filter_ccc(stage_decimation, taps) self.stages.append((stage_filter, stage_input_rate, next_rate)) self.connect(prev_block, stage_filter) prev_block = stage_filter stage_input_rate = next_rate # final connection and resampling if stage_input_rate == output_rate: # exact multiple, no fractional resampling needed self.connect(prev_block, self) self.__resampler_explanation = 'No final resampler stage.' else: # TODO: systematically combine resampler with final filter stage if using_rational_resampler: if stage_input_rate % 1 != 0: raise Exception("shouldn't happen", stage_input_rate) stage_input_rate = int(stage_input_rate) # because of float division above common = gcd(output_rate, stage_input_rate) interpolation = output_rate // common decimation = stage_input_rate // common self.__resampler_explanation = 'rational_resampler by %s/%s (stage rates %s/%s)' % (interpolation, decimation, output_rate, stage_input_rate) resampler = rational_resampler.rational_resampler_ccf( interpolation=interpolation, decimation=decimation) else: # TODO: cache filter computation as optfir is used and takes a noticeable time self.__resampler_explanation = 'arb_resampler %s/%s = %s' % (output_rate, stage_input_rate, float(output_rate) / stage_input_rate) resampler = pfb.arb_resampler_ccf(float(output_rate) / stage_input_rate) self.connect( prev_block, resampler, self) # TODO: Shouldn't be necessary since we compute the taps in the loop above... self.__do_taps()