def __init__(self, sample_rate, symbol_rate): gr.hier_block2.__init__( self, "dvb_s_modulator_bc", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature samples_per_symbol = sample_rate / symbol_rate if samples_per_symbol < 2: raise TypeError, "Samples per symbol must be >= 2" # Form symbols with 2 bits per symbol self.pack = gr.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) self.reunpack = gr.packed_to_unpacked_bb(2, gr.GR_MSB_FIRST) self.mapper = gr.chunks_to_symbols_bc(mod_constellation) # Design FIR filter taps for square root raised cosine filter ntaps = 11 * int(samples_per_symbol * nfilts) rrc_taps = gr.firdes.root_raised_cosine(nfilts, nfilts, 1.0, dvb_swig.RRC_ROLLOFF_FACTOR, ntaps) # Baseband pulse shaping filter self.rrc_filter = gr.pfb_arb_resampler_ccf(samples_per_symbol, rrc_taps) self.connect(self, self.pack, self.reunpack, self.mapper, self.rrc_filter, self)
def __init__(self, rate, taps=None, flt_size=32, atten=100): gr.hier_block2.__init__(self, "pfb_arb_resampler_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._rate = rate self._size = flt_size if taps is not None: self._taps = taps else: # Create a filter that covers the full bandwidth of the input signal bw = 0.4 tb = 0.2 ripple = 0.1 #self._taps = gr.firdes.low_pass_2(self._size, self._size, bw, tb, atten) made = False while not made: try: self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten) made = True except RuntimeError: ripple += 0.01 made = False print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) # Build in an exit strategy; if we've come this far, it ain't working. if(ripple >= 1.0): raise RuntimeError("optfir could not generate an appropriate filter.") self.pfb = gr.pfb_arb_resampler_ccf(self._rate, self._taps, self._size) #print "PFB has %d taps\n" % (len(self._taps),) self.connect(self, self.pfb) self.connect(self.pfb, self)
def test01 (self): # Test BPSK sync excess_bw = 0.35 sps = 4 loop_bw = cmath.pi/100.0 nfilts = 32 init_phase = nfilts/2 max_rate_deviation = 1.5 osps = 1 ntaps = 11 * int(sps*nfilts) #taps = gr.firdes.root_raised_cosine(nfilts, nfilts*sps, # 1.0, excess_bw, ntaps) taps = pfb_clock_sync_taps.taps self.test = digital.pfb_clock_sync_ccf(sps, loop_bw, taps, nfilts, init_phase, max_rate_deviation, osps) data = 1000*[complex(1,0), complex(-1,0)] self.src = gr.vector_source_c(data, False) # pulse shaping interpolation filter #rrc_taps = gr.firdes.root_raised_cosine( # nfilts, # gain # nfilts, # sampling rate based on 32 filters in resampler # 1.0, # symbol rate # excess_bw, # excess bandwidth (roll-off factor) # ntaps) rrc_taps = pfb_clock_sync_taps.rrc_taps self.rrc_filter = gr.pfb_arb_resampler_ccf(sps, rrc_taps) self.snk = gr.vector_sink_c() self.tb.connect(self.src, self.rrc_filter, self.test, self.snk) self.tb.run() expected_result = 1000*[complex(-1,0), complex(1,0)] dst_data = self.snk.data() # Only compare last Ncmp samples Ncmp = 100 len_e = len(expected_result) len_d = len(dst_data) expected_result = expected_result[len_e - Ncmp:] dst_data = dst_data[len_d - Ncmp:] #for e,d in zip(expected_result, dst_data): # print e, d self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 1)
def test01(self): # Test BPSK sync excess_bw = 0.35 sps = 4 loop_bw = cmath.pi / 100.0 nfilts = 32 init_phase = nfilts / 2 max_rate_deviation = 1.5 osps = 1 ntaps = 11 * int(sps * nfilts) #taps = gr.firdes.root_raised_cosine(nfilts, nfilts*sps, # 1.0, excess_bw, ntaps) taps = pfb_clock_sync_taps.taps self.test = digital.pfb_clock_sync_ccf(sps, loop_bw, taps, nfilts, init_phase, max_rate_deviation, osps) data = 1000 * [complex(1, 0), complex(-1, 0)] self.src = gr.vector_source_c(data, False) # pulse shaping interpolation filter #rrc_taps = gr.firdes.root_raised_cosine( # nfilts, # gain # nfilts, # sampling rate based on 32 filters in resampler # 1.0, # symbol rate # excess_bw, # excess bandwidth (roll-off factor) # ntaps) rrc_taps = pfb_clock_sync_taps.rrc_taps self.rrc_filter = gr.pfb_arb_resampler_ccf(sps, rrc_taps) self.snk = gr.vector_sink_c() self.tb.connect(self.src, self.rrc_filter, self.test, self.snk) self.tb.run() expected_result = 1000 * [complex(-1, 0), complex(1, 0)] dst_data = self.snk.data() # Only compare last Ncmp samples Ncmp = 100 len_e = len(expected_result) len_d = len(dst_data) expected_result = expected_result[len_e - Ncmp:] dst_data = dst_data[len_d - Ncmp:] #for e,d in zip(expected_result, dst_data): # print e, d self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 1)
def __init__(self, rate, taps, flt_size=32): gr.hier_block2.__init__(self, "pfb_arb_resampler_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._rate = rate self._taps = taps self._size = flt_size self.pfb = gr.pfb_arb_resampler_ccf(self._rate, self._taps, self._size) self.connect(self, self.pfb) self.connect(self.pfb, self)
def __init__(self, sample_rate, symbol_rate): gr.hier_block2.__init__(self, "dvb_s_modulator_bc", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature samples_per_symbol = sample_rate / symbol_rate if samples_per_symbol < 2: raise TypeError, "Samples per symbol must be >= 2" # Form symbols with 2 bits per symbol self.pack = gr.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) self.reunpack = gr.packed_to_unpacked_bb(2, gr.GR_MSB_FIRST) self.mapper = gr.chunks_to_symbols_bc(mod_constellation) # Design FIR filter taps for square root raised cosine filter ntaps = 11 * int(samples_per_symbol * nfilts) rrc_taps = gr.firdes.root_raised_cosine(nfilts, nfilts, 1.0, dvb_swig.RRC_ROLLOFF_FACTOR, ntaps) # Baseband pulse shaping filter self.rrc_filter = gr.pfb_arb_resampler_ccf(samples_per_symbol, rrc_taps) self.connect(self, self.pack, self.reunpack, self.mapper, self.rrc_filter, self)
def __init__(self, constellation, samples_per_symbol=_def_samples_per_symbol, differential=_def_differential, excess_bw=_def_excess_bw, gray_coded=True, verbose=_def_verbose, log=_def_log): """ Hierarchical block for RRC-filtered differential generic modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. @param constellation: determines the modulation type @type constellation: gnuradio.digital.gr_constellation @param samples_per_symbol: samples per baud >= 2 @type samples_per_symbol: float @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float @param gray_coded: turn gray coding on/off @type gray_coded: bool @param verbose: Print information about modulator? @type verbose: bool @param log: Log modulation data to files? @type log: bool """ gr.hier_block2.__init__(self, "generic_mod", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._constellation = constellation.base() self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw self._differential = differential if self._samples_per_symbol < 2: raise TypeError, ("sbp must be >= 2, is %f" % self._samples_per_symbol) arity = pow(2,self.bits_per_symbol()) # turn bytes into k-bit vectors self.bytes2chunks = \ gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) if gray_coded == True: self.symbol_mapper = gr.map_bb(self._constellation.pre_diff_code()) if differential: self.diffenc = gr.diff_encoder_bb(arity) self.chunks2symbols = gr.chunks_to_symbols_bc(self._constellation.points()) # pulse shaping filter nfilts = 32 ntaps = nfilts * 11 * int(self._samples_per_symbol) # make nfilts filters of ntaps each self.rrc_taps = gr.firdes.root_raised_cosine( nfilts, # gain nfilts, # sampling rate based on 32 filters in resampler 1.0, # symbol rate self._excess_bw, # excess bandwidth (roll-off factor) ntaps) self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) # Connect blocks = [self, self.bytes2chunks] if gray_coded == True: blocks.append(self.symbol_mapper) if differential: blocks.append(self.diffenc) blocks += [self.chunks2symbols, self.rrc_filter, self] self.connect(*blocks) if verbose: self._print_verbage() if log: self._setup_logging()
def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, gray_code=_def_gray_code, verbose=_def_verbose, log=_def_log): """ Hierarchical block for RRC-filtered QPSK modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. @param samples_per_symbol: samples per symbol >= 2 @type samples_per_symbol: integer @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float @param gray_code: Tell modulator to Gray code the bits @type gray_code: bool @param verbose: Print information about modulator? @type verbose: bool @param debug: Print modualtion data to files? @type debug: bool """ gr.hier_block2.__init__( self, "dqpsk2_mod", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw self._gray_code = gray_code if samples_per_symbol < 2: raise TypeError, ("sbp must be >= 2, is %f" % samples_per_symbol) ntaps = 11 * samples_per_symbol arity = pow(2, self.bits_per_symbol()) # turn bytes into k-bit vectors self.bytes2chunks = \ gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) if self._gray_code: self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) else: self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) self.diffenc = gr.diff_encoder_bb(arity) rot = .707 + .707j rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) # pulse shaping filter nfilts = 32 ntaps = 11 * int( nfilts * self._samples_per_symbol) # make nfilts filters of ntaps each self.rrc_taps = gr.firdes.root_raised_cosine( nfilts, # gain nfilts, # sampling rate based on 32 filters in resampler 1.0, # symbol rate self._excess_bw, # excess bandwidth (roll-off factor) ntaps) self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) if verbose: self._print_verbage() if log: self._setup_logging() # Connect & Initialize base class self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, self.chunks2symbols, self.rrc_filter, self)
def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, gray_code=_def_gray_code, verbose=_def_verbose, log=_def_log): """ Hierarchical block for RRC-filtered differential BPSK modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. @param samples_per_symbol: samples per baud >= 2 @type samples_per_symbol: integer @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float @param gray_code: Tell modulator to Gray code the bits @type gray_code: bool @param verbose: Print information about modulator? @type verbose: bool @param log: Log modulation data to files? @type log: bool """ gr.hier_block2.__init__(self, "dbpsk_mod", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw self._gray_code = gray_code if self._samples_per_symbol < 2: raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol) arity = pow(2,self.bits_per_symbol()) # turn bytes into k-bit vectors self.bytes2chunks = \ gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) if self._gray_code: self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) else: self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) self.diffenc = gr.diff_encoder_bb(arity) self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[arity]) # pulse shaping filter nfilts = 32 ntaps = nfilts * 11 * int(self._samples_per_symbol) # make nfilts filters of ntaps each self.rrc_taps = gr.firdes.root_raised_cosine( nfilts, # gain nfilts, # sampling rate based on 32 filters in resampler 1.0, # symbol rate self._excess_bw, # excess bandwidth (roll-off factor) ntaps) self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) # Connect self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, self.chunks2symbols, self.rrc_filter, self) if verbose: self._print_verbage() if log: self._setup_logging()
def __init__(self, constellation, samples_per_symbol=_def_samples_per_symbol, differential=_def_differential, excess_bw=_def_excess_bw, gray_coded=True, verbose=_def_verbose, log=_def_log): """ Hierarchical block for RRC-filtered differential generic modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. @param constellation: determines the modulation type @type constellation: gnuradio.digital.gr_constellation @param samples_per_symbol: samples per baud >= 2 @type samples_per_symbol: float @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float @param gray_coded: turn gray coding on/off @type gray_coded: bool @param verbose: Print information about modulator? @type verbose: bool @param log: Log modulation data to files? @type log: bool """ gr.hier_block2.__init__( self, "generic_mod", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._constellation = constellation.base() self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw self._differential = differential if self._samples_per_symbol < 2: raise TypeError, ("sbp must be >= 2, is %f" % self._samples_per_symbol) arity = pow(2, self.bits_per_symbol()) # turn bytes into k-bit vectors self.bytes2chunks = \ gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) if gray_coded == True: self.symbol_mapper = digital.map_bb( self._constellation.pre_diff_code()) if differential: self.diffenc = digital.diff_encoder_bb(arity) self.chunks2symbols = digital.chunks_to_symbols_bc( self._constellation.points()) # pulse shaping filter nfilts = 32 ntaps = nfilts * 11 * int( self._samples_per_symbol) # make nfilts filters of ntaps each self.rrc_taps = gr.firdes.root_raised_cosine( nfilts, # gain nfilts, # sampling rate based on 32 filters in resampler 1.0, # symbol rate self._excess_bw, # excess bandwidth (roll-off factor) ntaps) self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) # Connect blocks = [self, self.bytes2chunks] if gray_coded == True: blocks.append(self.symbol_mapper) if differential: blocks.append(self.diffenc) blocks += [self.chunks2symbols, self.rrc_filter, self] self.connect(*blocks) if verbose: self._print_verbage() if log: self._setup_logging()
def __init__(self, options, input_filename): gr.top_block.__init__(self) gr.enable_realtime_scheduling() if options.real: sizeof_input_samples = gr.sizeof_float else: sizeof_input_samples = gr.sizeof_gr_complex self.src = gr.file_source(sizeof_input_samples, input_filename, repeat = options.loop) self.u = generic_usrp_sink_c(interface = options.interface, mac_addr = options.mac_addr, subdev_spec = options.tx_subdev_spec) print 'Using %s' % str(self.u) print 'Possible tx frequency range: %s - %s' % \ (n2s(self.u.freq_range()[0]), n2s(self.u.freq_range()[1])) # we need to find the closest decimation rate the USRP can handle # to the input file's sampling rate try: ideal_interp = self.u.dac_rate() / options.rate # pick the closest interpolation rate interp = [x for x in self.u.get_interp_rates() if x <= ideal_interp][-1] self.u.set_interp(interp) except IndexError: sys.stderr.write('Failed to set USRP interpolation rate\n') raise SystemExit, 1 output_rate = self.u.dac_rate() / interp resamp_ratio = output_rate / options.rate # since the input file sample rate may not be exactly what our # output rate of the USRP (as determined by the interpolation rate), # we need to resample our input to the output rate num_filters = 32 cutoff = 0.99 * options.rate / 2. transition = 0.1 * options.rate / 2. resamp_taps = gr.firdes_low_pass(num_filters * 1.0, num_filters * options.rate, cutoff, transition) self.resamp = gr.pfb_arb_resampler_ccf(resamp_ratio, resamp_taps, num_filters) if options.gain is None: # if no gain was specified, use the mid-point in dB g = self.u.gain_range() options.gain = float(g[0]+g[1])/2 self.u.set_gain(options.gain) res = self.u.set_center_freq(options.freq) if not res: sys.stderr.write('Failed to set frequency\n') raise SystemExit, 1 if options.real: # our samples are real # we need to convert them to complex without a hilbert filter self.hilbert = gr.hilbert_fc(64) self.connect(self.src, self.hilbert, self.resamp, self.u) else: # our samples are complex self.connect(self.src, self.resamp, self.u)