def __init__(self, vocoder, lo_freq, audio_rate, if_rate): gr.hier_block2.__init__(self, "pipeline", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature c4fm = op25_c4fm_mod.p25_mod_bf(output_sample_rate=audio_rate, log=False, verbose=True) interp_factor = if_rate / audio_rate low_pass = 2.88e3 interp_taps = gr.firdes.low_pass(1.0, if_rate, low_pass, low_pass * 0.1, gr.firdes.WIN_HANN) interpolator = gr.interp_fir_filter_fff (int(interp_factor), interp_taps) max_dev = 12.5e3 k = 2 * math.pi * max_dev / if_rate adjustment = 1.5 # adjust for proper c4fm deviation level modulator = gr.frequency_modulator_fc (k * adjustment) # Local oscillator lo = gr.sig_source_c (if_rate, # sample rate gr.GR_SIN_WAVE, # waveform type lo_freq, #frequency 1.0, # amplitude 0) # DC Offset mixer = gr.multiply_cc () self.connect (vocoder, c4fm, interpolator, modulator, (mixer, 0)) self.connect (lo, (mixer, 1)) self.connect (mixer, self)
def __init__(self, output_rate): gr.hier_block2.__init__(self, "p25_c4fm_mod_bf", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature symbol_rate = 4800 # P25 baseband symbol rate lcm = gru.lcm(symbol_rate, output_rate) self._interp_factor = int(lcm // symbol_rate) self._decimation = int(lcm // output_rate) self._excess_bw =0.2 mod_map = [1.0/3.0, 1.0, -(1.0/3.0), -1.0] self.C2S = gr.chunks_to_symbols_bf(mod_map) ntaps = 11 * self._interp_factor rrc_taps = gr.firdes.root_raised_cosine( self._interp_factor, # gain (since we're interpolating by sps) lcm, # sampling rate symbol_rate, self._excess_bw, # excess bandwidth (roll-off factor) ntaps) self.rrc_filter = gr.interp_fir_filter_fff(self._interp_factor, rrc_taps) # FM pre-emphasis filter shaping_coeffs = [-0.018, 0.0347, 0.0164, -0.0064, -0.0344, -0.0522, -0.0398, 0.0099, 0.0798, 0.1311, 0.121, 0.0322, -0.113, -0.2499, -0.3007, -0.2137, -0.0043, 0.2825, 0.514, 0.604, 0.514, 0.2825, -0.0043, -0.2137, -0.3007, -0.2499, -0.113, 0.0322, 0.121, 0.1311, 0.0798, 0.0099, -0.0398, -0.0522, -0.0344, -0.0064, 0.0164, 0.0347, -0.018] self.shaping_filter = gr.fir_filter_fff(1, shaping_coeffs) # generate output at appropriate rate self.decimator = blks2.rational_resampler_fff(1, self._decimation) self.connect(self, self.C2S, self.rrc_filter, self.shaping_filter, self.decimator, self)
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-a", "--audio-input", type="string", default="") parser.add_option("-A", "--audio-output", type="string", default="") parser.add_option("-f", "--factor", type="eng_float", default=1) parser.add_option("-i", "--do-interp", action="store_true", default=False, help="enable output interpolator") parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample rate") parser.add_option("-S", "--stretch", type="int", default=0, help="flex amt") parser.add_option("-y", "--symbol-rate", type="int", default=4800, help="input symbol rate") parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data") (options, args) = parser.parse_args() sample_rate = options.sample_rate symbol_rate = options.symbol_rate IN = audio.source(sample_rate, options.audio_input) audio_output_rate = 8000 if options.do_interp: audio_output_rate = 48000 OUT = audio.sink(audio_output_rate, options.audio_output) symbol_decim = 1 symbol_coeffs = gr.firdes.root_raised_cosine(1.0, # gain sample_rate , # sampling rate symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type SYMBOL_FILTER = gr.fir_filter_fff (symbol_decim, symbol_coeffs) AMP = gr.multiply_const_ff(options.factor) msgq = gr.msg_queue(2) FSK4 = op25.fsk4_demod_ff(msgq, sample_rate, symbol_rate) levels = levels = [-2.0, 0.0, 2.0, 4.0] SLICER = repeater.fsk4_slicer_fb(levels) framer_msgq = gr.msg_queue(2) DECODE = repeater.p25_frame_assembler('', # udp hostname 0, # udp port no. options.verbose, #debug True, # do_imbe True, # do_output False, # do_msgq framer_msgq) IMBE = repeater.vocoder(False, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors CVT = gr.short_to_float() if options.do_interp: interp_taps = gr.firdes.low_pass(1.0, 48000, 4000, 4000 * 0.1, gr.firdes.WIN_HANN) INTERP = gr.interp_fir_filter_fff(48000 // 8000, interp_taps) AMP2 = gr.multiply_const_ff(1.0 / 32767.0) self.connect(IN, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODE, IMBE, CVT, AMP2) if options.do_interp: self.connect(AMP2, INTERP, OUT) else: self.connect(AMP2, OUT)
def test_00(self): expected_result = ( 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff) # Filter taps to expand the data to oversample by 8 # Just using a RRC for some basic filter shape taps = gr.firdes.root_raised_cosine(8, 8, 1.0, 0.5, 21) src = gr.vector_source_b(expected_result) frame = digital.simple_framer(4) unpack = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) expand = gr.interp_fir_filter_fff(8, taps) b2f = gr.char_to_float() mult2 = gr.multiply_const_ff(2) sub1 = gr.add_const_ff(-1) op = digital.simple_correlator(4) dst = gr.vector_sink_b() self.tb.connect(src, frame, unpack, b2f, mult2, sub1, expand) self.tb.connect(expand, op, dst) self.tb.run() result_data = dst.data() self.assertEqual(expected_result, result_data)
def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=5e3): """ Narrow Band FM Transmitter. Takes a single float input stream of audio samples in the range [-1,+1] and produces a single FM modulated complex baseband output. @param audio_rate: sample rate of audio stream, >= 16k @type audio_rate: integer @param quad_rate: sample rate of output stream @type quad_rate: integer @param tau: preemphasis time constant (default 75e-6) @type tau: float @param max_dev: maximum deviation in Hz (default 5e3) @type max_dev: float quad_rate must be an integer multiple of audio_rate. """ gr.hier_block2.__init__( self, "nbfm_tx", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature # FIXME audio_rate and quad_rate ought to be exact rationals audio_rate = int(audio_rate) quad_rate = int(quad_rate) if quad_rate % audio_rate != 0: raise ValueError, "quad_rate is not an integer multiple of audio_rate" do_interp = audio_rate != quad_rate if do_interp: interp_factor = quad_rate / audio_rate interp_taps = optfir.low_pass( interp_factor, # gain quad_rate, # Fs 4500, # passband cutoff 7000, # stopband cutoff 0.1, # passband ripple dB 40) # stopband atten dB #print "len(interp_taps) =", len(interp_taps) self.interpolator = gr.interp_fir_filter_fff( interp_factor, interp_taps) self.preemph = fm_preemph(quad_rate, tau=tau) k = 2 * math.pi * max_dev / quad_rate self.modulator = gr.frequency_modulator_fc(k) if do_interp: self.connect(self, self.interpolator, self.preemph, self.modulator, self) else: self.connect(self, self.preemph, self.modulator, self)
def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=75e3): """ Wide Band FM Transmitter. Takes a single float input stream of audio samples in the range [-1,+1] and produces a single FM modulated complex baseband output. @param audio_rate: sample rate of audio stream, >= 16k @type audio_rate: integer @param quad_rate: sample rate of output stream @type quad_rate: integer @param tau: preemphasis time constant (default 75e-6) @type tau: float @param max_dev: maximum deviation in Hz (default 75e3) @type max_dev: float quad_rate must be an integer multiple of audio_rate. """ gr.hier_block2.__init__( self, "wfm_tx", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature # FIXME audio_rate and quad_rate ought to be exact rationals audio_rate = int(audio_rate) quad_rate = int(quad_rate) if quad_rate % audio_rate != 0: raise ValueError, "quad_rate is not an integer multiple of audio_rate" do_interp = audio_rate != quad_rate if do_interp: interp_factor = quad_rate / audio_rate interp_taps = optfir.low_pass( interp_factor, # gain quad_rate, # Fs 16000, # passband cutoff 18000, # stopband cutoff 0.1, # passband ripple dB 40) # stopband atten dB print "len(interp_taps) =", len(interp_taps) self.interpolator = gr.interp_fir_filter_fff( interp_factor, interp_taps) self.preemph = fm_preemph(quad_rate, tau=tau) k = 2 * math.pi * max_dev / quad_rate self.modulator = gr.frequency_modulator_fc(k) if do_interp: self.connect(self, self.interpolator, self.preemph, self.modulator, self) else: self.connect(self, self.preemph, self.modulator, self)
def __init__(self, subdev_spec, freq, subdev_gain, filename, delay): gr.top_block.__init__(self) # data sink and sink rate u = usrp.sink_c() # important vars (to be calculated from USRP when available dac_rate = u.dac_rate() usrp_rate = 320e3 usrp_interp = int(dac_rate // usrp_rate) channel_rate = 32e3 interp_factor = int(usrp_rate // channel_rate) # open the pcap source pcap = op25.pcap_source_b(filename, delay) # pcap = gr.glfsr_source_b(16) # convert octets into dibits bits_per_symbol = 2 unpack = gr.packed_to_unpacked_bb(bits_per_symbol, gr.GR_MSB_FIRST) # modulator c4fm = p25_mod_bf(output_rate=channel_rate) # setup low pass filter + interpolator low_pass = 2.88e3 interp_taps = gr.firdes.low_pass(1.0, channel_rate, low_pass, low_pass * 0.1, gr.firdes.WIN_HANN) interpolator = gr.interp_fir_filter_fff(int(interp_factor), interp_taps) # frequency modulator max_dev = 12.5e3 k = 2 * math.pi * max_dev / usrp_rate adjustment = 1.5 # adjust for proper c4fm deviation level fm = gr.frequency_modulator_fc(k * adjustment) # signal gain gain = gr.multiply_const_cc(4000) # configure USRP if subdev_spec is None: subdev_spec = usrp.pick_tx_subdevice(u) u.set_mux(usrp.determine_tx_mux_value(u, subdev_spec)) self.db = usrp.selected_subdev(u, subdev_spec) print "Using TX d'board %s" % (self.db.side_and_name(), ) u.set_interp_rate(usrp_interp) if gain is None: g = self.db.gain_range() gain = float(g[0] + g[1]) / 2 self.db.set_gain(self.db.gain_range()[0]) u.tune(self.db.which(), self.db, freq) self.db.set_enable(True) self.connect(pcap, unpack, c4fm, interpolator, fm, gain, u)
def reference_interp_filter(src_data, interp, taps): tb = gr.top_block() src = gr.vector_source_f(src_data) op = gr.interp_fir_filter_fff(interp, taps) dst = gr.vector_sink_f() tb.connect(src, op, dst) tb.run() result_data = dst.data() tb = None return result_data
def reference_interp_filter(src_data, interp, taps): fg = gr.flow_graph() src = gr.vector_source_f(src_data) op = gr.interp_fir_filter_fff(interp, taps) dst = gr.vector_sink_f() fg.connect(src, op, dst) fg.run() result_data = dst.data() fg = None return result_data
def __init__(self, subdev_spec, freq, subdev_gain, filename, delay): gr.top_block.__init__ (self) # data sink and sink rate u = usrp.sink_c() # important vars (to be calculated from USRP when available dac_rate = u.dac_rate() usrp_rate = 320e3 usrp_interp = int(dac_rate // usrp_rate) channel_rate = 32e3 interp_factor = int(usrp_rate // channel_rate) # open the pcap source pcap = op25.pcap_source_b(filename, delay) # pcap = gr.glfsr_source_b(16) # convert octets into dibits bits_per_symbol = 2 unpack = gr.packed_to_unpacked_bb(bits_per_symbol, gr.GR_MSB_FIRST) # modulator c4fm = p25_mod_bf(output_rate=channel_rate) # setup low pass filter + interpolator low_pass = 2.88e3 interp_taps = gr.firdes.low_pass(1.0, channel_rate, low_pass, low_pass * 0.1, gr.firdes.WIN_HANN) interpolator = gr.interp_fir_filter_fff (int(interp_factor), interp_taps) # frequency modulator max_dev = 12.5e3 k = 2 * math.pi * max_dev / usrp_rate adjustment = 1.5 # adjust for proper c4fm deviation level fm = gr.frequency_modulator_fc(k * adjustment) # signal gain gain = gr.multiply_const_cc(4000) # configure USRP if subdev_spec is None: subdev_spec = usrp.pick_tx_subdevice(u) u.set_mux(usrp.determine_tx_mux_value(u, subdev_spec)) self.db = usrp.selected_subdev(u, subdev_spec) print "Using TX d'board %s" % (self.db.side_and_name(),) u.set_interp_rate(usrp_interp) if gain is None: g = self.db.gain_range() gain = float(g[0] + g[1]) / 2 self.db.set_gain(self.db.gain_range()[0]) u.tune(self.db.which(), self.db, freq) self.db.set_enable(True) self.connect(pcap, unpack, c4fm, interpolator, fm, gain, u)
def reference_interp_dec_filter(src_data, interp, decim, taps): tb = gr.top_block() src = gr.vector_source_f(src_data) up = gr.interp_fir_filter_fff(interp, (1,)) dn = gr.fir_filter_fff(decim, taps) dst = gr.vector_sink_f() tb.connect(src, up, dn, dst) tb.run() result_data = dst.data() tb = None return result_data
def reference_interp_dec_filter(src_data, interp, decim, taps): fg = gr.flow_graph() src = gr.vector_source_f(src_data) up = gr.interp_fir_filter_fff(interp, (1,)) dn = gr.fir_filter_fff(decim, taps) dst = gr.vector_sink_f() fg.connect(src, up, dn, dst) fg.run() result_data = dst.data() fg = None return result_data
def test_fff (self): taps = [1, 10, 100, 1000, 10000] src_data = (0, 2, 3, 5, 7, 11, 13, 17) interpolation = 3 xr = (0,0,0,0,2,20,200,2003,20030,300,3005,30050,500,5007,50070,700,7011,70110,1100,11013,110130,1300,13017,130170) expected_result = tuple ([float (x) for x in xr]) src = gr.vector_source_f (src_data) op = gr.interp_fir_filter_fff (interpolation, taps) dst = gr.vector_sink_f () self.tb.connect (src, op) self.tb.connect (op, dst) self.tb.run () result_data = dst.data () L = min(len(result_data), len(expected_result)) self.assertEqual (expected_result[0:L], result_data[0:L])
def __init__(self, options, queue): gr.top_block.__init__(self, "mhp") sample_rate = options.sample_rate arity = 2 IN = gr.file_source(gr.sizeof_char, options.input_file, options.repeat) B2C = gr.packed_to_unpacked_bb(arity, gr.GR_MSB_FIRST) mod_map = [1.0, 3.0, -1.0, -3.0] C2S = gr.chunks_to_symbols_bf(mod_map) if options.reverse: polarity = gr.multiply_const_ff(-1) else: polarity = gr.multiply_const_ff( 1) symbol_rate = 4800 samples_per_symbol = sample_rate // symbol_rate excess_bw = 0.1 ntaps = 11 * samples_per_symbol rrc_taps = gr.firdes.root_raised_cosine( samples_per_symbol, # gain (sps since we're interpolating by sps samples_per_symbol, # sampling rate 1.0, # symbol rate excess_bw, # excess bandwidth (roll-off factor) ntaps) rrc_filter = gr.interp_fir_filter_fff(samples_per_symbol, rrc_taps) rrc_coeffs = [0, -0.003, -0.006, -0.009, -0.012, -0.014, -0.014, -0.013, -0.01, -0.006, 0, 0.007, 0.014, 0.02, 0.026, 0.029, 0.029, 0.027, 0.021, 0.012, 0, -0.013, -0.027, -0.039, -0.049, -0.054, -0.055, -0.049, -0.038, -0.021, 0, 0.024, 0.048, 0.071, 0.088, 0.098, 0.099, 0.09, 0.07, 0.039, 0, -0.045, -0.091, -0.134, -0.17, -0.193, -0.199, -0.184, -0.147, -0.085, 0, 0.105, 0.227, 0.36, 0.496, 0.629, 0.751, 0.854, 0.933, 0.983, 1, 0.983, 0.933, 0.854, 0.751, 0.629, 0.496, 0.36, 0.227, 0.105, 0, -0.085, -0.147, -0.184, -0.199, -0.193, -0.17, -0.134, -0.091, -0.045, 0, 0.039, 0.07, 0.09, 0.099, 0.098, 0.088, 0.071, 0.048, 0.024, 0, -0.021, -0.038, -0.049, -0.055, -0.054, -0.049, -0.039, -0.027, -0.013, 0, 0.012, 0.021, 0.027, 0.029, 0.029, 0.026, 0.02, 0.014, 0.007, 0, -0.006, -0.01, -0.013, -0.014, -0.014, -0.012, -0.009, -0.006, -0.003, 0] # rrc_coeffs work slightly differently: each input sample # (from mod_map above) at 4800 rate, then 9 zeros are inserted # to bring to a 48000 rate, then this filter is applied: # rrc_filter = gr.fir_filter_fff(1, rrc_coeffs) # FIXME: how to insert the 9 zero samples using gr ? # FM pre-emphasis filter shaping_coeffs = [-0.018, 0.0347, 0.0164, -0.0064, -0.0344, -0.0522, -0.0398, 0.0099, 0.0798, 0.1311, 0.121, 0.0322, -0.113, -0.2499, -0.3007, -0.2137, -0.0043, 0.2825, 0.514, 0.604, 0.514, 0.2825, -0.0043, -0.2137, -0.3007, -0.2499, -0.113, 0.0322, 0.121, 0.1311, 0.0798, 0.0099, -0.0398, -0.0522, -0.0344, -0.0064, 0.0164, 0.0347, -0.018] shaping_filter = gr.fir_filter_fff(1, shaping_coeffs) OUT = audio.sink(sample_rate, options.audio_output) amp = gr.multiply_const_ff(options.factor) self.connect(IN, B2C, C2S, polarity, rrc_filter, shaping_filter, amp) # output to both L and R channels self.connect(amp, (OUT,0) ) self.connect(amp, (OUT,1) )
def test_fff(self): taps = [1, 10, 100, 1000, 10000] src_data = (0, 2, 3, 5, 7, 11, 13, 17) interpolation = 3 xr = (0, 0, 0, 0, 2, 20, 200, 2003, 20030, 300, 3005, 30050, 500, 5007, 50070, 700, 7011, 70110, 1100, 11013, 110130, 1300, 13017, 130170) expected_result = tuple([float(x) for x in xr]) src = gr.vector_source_f(src_data) op = gr.interp_fir_filter_fff(interpolation, taps) dst = gr.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) self.tb.run() result_data = dst.data() L = min(len(result_data), len(expected_result)) self.assertEqual(expected_result[0:L], result_data[0:L])
def __init__(self, output_rate): gr.hier_block2.__init__( self, "p25_c4fm_mod_bf", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature symbol_rate = 4800 # P25 baseband symbol rate lcm = gru.lcm(symbol_rate, output_rate) self._interp_factor = int(lcm // symbol_rate) self._decimation = int(lcm // output_rate) self._excess_bw = 0.2 mod_map = [1.0 / 3.0, 1.0, -(1.0 / 3.0), -1.0] self.C2S = gr.chunks_to_symbols_bf(mod_map) ntaps = 11 * self._interp_factor rrc_taps = gr.firdes.root_raised_cosine( self._interp_factor, # gain (since we're interpolating by sps) lcm, # sampling rate symbol_rate, self._excess_bw, # excess bandwidth (roll-off factor) ntaps) self.rrc_filter = gr.interp_fir_filter_fff(self._interp_factor, rrc_taps) # FM pre-emphasis filter shaping_coeffs = [ -0.018, 0.0347, 0.0164, -0.0064, -0.0344, -0.0522, -0.0398, 0.0099, 0.0798, 0.1311, 0.121, 0.0322, -0.113, -0.2499, -0.3007, -0.2137, -0.0043, 0.2825, 0.514, 0.604, 0.514, 0.2825, -0.0043, -0.2137, -0.3007, -0.2499, -0.113, 0.0322, 0.121, 0.1311, 0.0798, 0.0099, -0.0398, -0.0522, -0.0344, -0.0064, 0.0164, 0.0347, -0.018 ] self.shaping_filter = gr.fir_filter_fff(1, shaping_coeffs) # generate output at appropriate rate self.decimator = blks2.rational_resampler_fff(1, self._decimation) self.connect(self, self.C2S, self.rrc_filter, self.shaping_filter, self.decimator, self)
def __init__(self, resample=8, bw=0.5): ''' When using the CVSD vocoder, appropriate sampling rates are from 8k to 64k with resampling rates from 1 to 8. A rate of 8k with a resampling rate of 8 provides a good quality signal. ''' gr.hier_block2.__init__(self, "cvsd_encode", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature scale_factor = 32000.0 self.interp = resample src_scale = gr.multiply_const_ff(scale_factor) taps = gr.firdes.low_pass(self.interp, self.interp, bw, 2*bw) interp = gr.interp_fir_filter_fff(self.interp, taps) f2s = gr.float_to_short() enc = vocoder_swig.cvsd_encode_sb() self.connect(self, src_scale, interp, f2s, enc, self)
def __init__(self, vlen): gr.hier_block2.__init__(self, "vector_equalizer", gr.io_signature(1,1,gr.sizeof_gr_complex*vlen), gr.io_signature(1,1,gr.sizeof_gr_complex*vlen)) self.input=gr.add_const_vcc([0.0]*vlen) self.connect(self, self.input) c2mag = gr.complex_to_mag(vlen) max_v = gr.max_ff(vlen) interpolator = gr.interp_fir_filter_fff(vlen,[1.0]*vlen) f2c = gr.float_to_complex() v2s = gr.vector_to_stream(gr.sizeof_gr_complex, vlen) normalizer = gr.divide_cc() s2v = gr.stream_to_vector(gr.sizeof_gr_complex, vlen) self.connect(self.input, v2s, (normalizer,0)) self.connect(self.input, c2mag, max_v, interpolator, f2c, (normalizer,1)) self.connect(normalizer, s2v) self.connect(s2v, self)
def __init__(self, vocoder, lo_freq, audio_rate, if_rate): gr.hier_block2.__init__( self, "pipeline", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature c4fm = op25_c4fm_mod.p25_mod_bf(output_sample_rate=audio_rate, log=False, verbose=True) interp_factor = if_rate / audio_rate low_pass = 2.88e3 interp_taps = gr.firdes.low_pass(1.0, if_rate, low_pass, low_pass * 0.1, gr.firdes.WIN_HANN) interpolator = gr.interp_fir_filter_fff(int(interp_factor), interp_taps) max_dev = 12.5e3 k = 2 * math.pi * max_dev / if_rate adjustment = 1.5 # adjust for proper c4fm deviation level modulator = gr.frequency_modulator_fc(k * adjustment) # Local oscillator lo = gr.sig_source_c( if_rate, # sample rate gr.GR_SIN_WAVE, # waveform type lo_freq, #frequency 1.0, # amplitude 0) # DC Offset mixer = gr.multiply_cc() self.connect(vocoder, c4fm, interpolator, modulator, (mixer, 0)) self.connect(lo, (mixer, 1)) self.connect(mixer, self)
def __init__(self, vlen): gr.hier_block2.__init__( self, "vector_equalizer", gr.io_signature(1, 1, gr.sizeof_gr_complex * vlen), gr.io_signature(1, 1, gr.sizeof_gr_complex * vlen)) self.input = gr.add_const_vcc([0.0] * vlen) self.connect(self, self.input) c2mag = gr.complex_to_mag(vlen) max_v = gr.max_ff(vlen) interpolator = gr.interp_fir_filter_fff(vlen, [1.0] * vlen) f2c = gr.float_to_complex() v2s = gr.vector_to_stream(gr.sizeof_gr_complex, vlen) normalizer = gr.divide_cc() s2v = gr.stream_to_vector(gr.sizeof_gr_complex, vlen) self.connect(self.input, v2s, (normalizer, 0)) self.connect(self.input, c2mag, max_v, interpolator, f2c, (normalizer, 1)) self.connect(normalizer, s2v) self.connect(s2v, self)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Scrambler") _icon_path = "/home/pfb/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 32000 ################################################## # Blocks ################################################## self.gr_add_xx_0 = gr.add_vff(1) self.gr_char_to_float_0 = gr.char_to_float() self.gr_interp_fir_filter_xxx_0 = gr.interp_fir_filter_fff(4, (24, )) self.gr_multiply_xx_0 = gr.multiply_vff(1) self.gr_scrambler_bb_0 = gr.scrambler_bb(0x8A, 0x7F, 7) self.gr_throttle_0 = gr.throttle(gr.sizeof_char*1, samp_rate) self.gr_vector_source_x_0 = gr.vector_source_b((0, 0, 0), True, 1) self.gr_vector_source_x_0_0 = gr.vector_source_f((-0.5, ), True, 1) self.gr_vector_source_x_0_0_0 = gr.vector_source_f((2.0, ), True, 1) self.wxgui_fftsink2_0 = fftsink2.fft_sink_f( self.GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=50, ref_scale=2.0, sample_rate=samp_rate * 2, fft_size=4096, fft_rate=30, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.GetWin(), title="Scope Plot", sample_rate=samp_rate, v_scale=1, v_offset=0, t_scale=.0005, ac_couple=False, xy_mode=False, num_inputs=1, ) self.Add(self.wxgui_scopesink2_0.win) ################################################## # Connections ################################################## self.connect((self.gr_scrambler_bb_0, 0), (self.gr_char_to_float_0, 0)) self.connect((self.gr_vector_source_x_0, 0), (self.gr_throttle_0, 0)) self.connect((self.gr_throttle_0, 0), (self.gr_scrambler_bb_0, 0)) self.connect((self.gr_char_to_float_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.gr_add_xx_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_vector_source_x_0_0, 0), (self.gr_add_xx_0, 0)) self.connect((self.gr_vector_source_x_0_0_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.gr_interp_fir_filter_xxx_0, 0)) self.connect((self.gr_interp_fir_filter_xxx_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.gr_interp_fir_filter_xxx_0, 0), (self.wxgui_scopesink2_0, 0))
def __init__(self, freq, subdev_spec, which_USRP, audio_input, debug): #gr.hier_block2.__init__(self, "analog_transmit_path", # gr.io_signature(0, 0, 0), #input signature # gr.io_signature(0, 0, 0)) #output signature gr.top_block.__init__(self) self.DEBUG = debug self.freq = freq #self.freq = 462562500 # audio_input="hw:0" #Formerly from XML self.tx_usrp_pga_gain_scaling = 1.0 self.tx_power = 1 self.tx_mod_type = 'fm' self.tx_freq_deviation = 2.5e3 self.tx_base_band_bw = 5e3 ################## USRP settings ################### r = gr.enable_realtime_scheduling() # acquire USRP via USB 2.0 #self.u = usrp.sink_c(fusb_block_size=1024, # fusb_nblocks=4, # which=which_USRP) self.u = uhd.single_usrp_sink( device_addr="", io_type=uhd.io_type_t.COMPLEX_FLOAT32, num_channels=1, ) # get D/A converter sampling rate #self.dac_rate = self.u.dac_rate() #128 MS/s self.dac_rate = 128e6 #128 MS/s if self.DEBUG: print " Tx Path DAC rate: %d" % (self.dac_rate) #System digital sample rate setting self.audio_rate = 16e3 self._gr_interp = 16 self.max_gr_interp_rate = 40 self._usrp_interp = 500 self.gr_rate = self.dac_rate / self._usrp_interp self._gr_decim = 1 if self.DEBUG: print " usrp interp: ", self._usrp_interp print " gr interp: ", self._gr_interp print " gr rate1: ", self.gr_rate print " gr decim: ", self._gr_decim print " audio rate: ", self.audio_rate # set USRP interplation ratio #self.u.set_interp_rate(self._usrp_interp) self.u.set_samp_rate(self.gr_rate) # set USRP daughterboard subdevice #if subdev_spec is None: # subdev_spec = usrp.pick_tx_subdevice(self.u) #self.u.set_mux(usrp.determine_tx_mux_value(self.u, subdev_spec)) #self.subdev = usrp.selected_subdev(self.u, subdev_spec) self.u.set_antenna("TX/RX") #if self.DEBUG: # print " TX Path use daughterboard: %s" % (self.subdev.side_and_name()) # Set center frequency of USRP """ Set the center frequency we're interested in. Tuning is a two step process. First we ask the front-end to tune as close to the desired frequency as it can. Then we use the result of that operation and our target_frequency to determine the value for the digital up converter. """ assert (self.freq != None) #r = self.u.tune(self.subdev.which(), self.subdev, self.freq) r = self.u.set_center_freq(self.freq, 0) if self.DEBUG: if r: print " Tx Frequency: %s" % (eng_notation.num_to_str( self.freq)) else: print "----Failed to set Tx frequency to %s" % ( eng_notation.num_to_str(self.freq), ) raise ValueError # Set the USRP Tx PGA gain, (Note that on the RFX cards this is a nop.) # subdev.set_gain(subdev.gain_range()[1]) # set max Tx gain #g = self.subdev.gain_range() g = self.u.get_gain_range(0) #_tx_usrp_gain_range = g[1]-g[0] _tx_usrp_gain_range = g #_tx_usrp_gain = g[0] + _tx_usrp_gain_range * self.tx_usrp_pga_gain_scaling #_tx_usrp_gain = g + _tx_usrp_gain_range * self.tx_usrp_pga_gain_scaling #self.subdev.set_gain(_tx_usrp_gain) #self.u.set_gain(_tx_usrp_gain, 0) self.u.set_gain(10, 0) #if self.DEBUG: # print " USRP Tx PGA Gain Range: min = %g, max = %g, step size = %g" \ # %(g[0], g[1], g[2]) # print " USRP Tx PGA gain set to: %g" %(_tx_usrp_gain) # Set the transmit amplitude sent to the USRP (param: ampl 0 <= ampl < 16384.) """ Convert tx_power(mW) in waveform.xml to amplitude in gnu radio """ ampl = 1638.3 * pow(self.tx_power, 0.5) self.tx_amplitude = max(0.0, min(ampl, 16383.0)) if self.DEBUG: print "tx amplitude:", self.tx_amplitude #gr digital amplifier self.tx_amplitude = 1.0 self.gr_amp = gr.multiply_const_cc(int( self.tx_amplitude)) # software amplifier (scaler) print "GR amp= ", int(self.tx_amplitude) if self.DEBUG: print " Tx power acquired from waveform configuration XML file is: %f between (0, 100.0mW)" % ( self.tx_power) print " Tx Path initial software signal amplitude to USRP: %f / 16383.0" % ( ampl) print " Tx Path actual software signal amplitude to USRP: %f / 16383.0" % ( self.tx_amplitude) ################## Choose the corresponding analog modem ################### if self.DEBUG: print "----Tx path modulation: %s" % (self.tx_mod_type) chan_filter_coeffs_fixed = ( 0.000457763671875, 0.000946044921875, 0.00067138671875, 0.001068115234375, 0.00091552734375, 0.0008544921875, 0.000518798828125, 0.0001220703125, -0.000396728515625, -0.0008544921875, -0.00128173828125, -0.00146484375, -0.001434326171875, -0.0010986328125, -0.000518798828125, 0.000274658203125, 0.001129150390625, 0.00189208984375, 0.00238037109375, 0.00250244140625, 0.002166748046875, 0.0013427734375, 0.000152587890625, -0.001220703125, -0.002532958984375, -0.0035400390625, -0.003997802734375, -0.003753662109375, -0.002777099609375, -0.0010986328125, 0.000946044921875, 0.00311279296875, 0.00494384765625, 0.00604248046875, 0.006103515625, 0.005035400390625, 0.00286865234375, -0.0001220703125, -0.00347900390625, -0.006561279296875, -0.008758544921875, -0.00958251953125, -0.008636474609375, -0.005950927734375, -0.001739501953125, 0.00335693359375, 0.00848388671875, 0.0126953125, 0.01507568359375, 0.014862060546875, 0.01171875, 0.00579833984375, -0.002227783203125, -0.01123046875, -0.0196533203125, -0.02587890625, -0.028228759765625, -0.025421142578125, -0.016754150390625, -0.002166748046875, 0.017608642578125, 0.041015625, 0.0660400390625, 0.090240478515625, 0.111083984375, 0.12640380859375, 0.134490966796875, 0.134490966796875, 0.12640380859375, 0.111083984375, 0.090240478515625, 0.0660400390625, 0.041015625, 0.017608642578125, -0.002166748046875, -0.016754150390625, -0.025421142578125, -0.028228759765625, -0.02587890625, -0.0196533203125, -0.01123046875, -0.002227783203125, 0.00579833984375, 0.01171875, 0.014862060546875, 0.01507568359375, 0.0126953125, 0.00848388671875, 0.00335693359375, -0.001739501953125, -0.005950927734375, -0.008636474609375, -0.00958251953125, -0.008758544921875, -0.006561279296875, -0.00347900390625, -0.0001220703125, 0.00286865234375, 0.005035400390625, 0.006103515625, 0.00604248046875, 0.00494384765625, 0.00311279296875, 0.000946044921875, -0.0010986328125, -0.002777099609375, -0.003753662109375, -0.003997802734375, -0.0035400390625, -0.002532958984375, -0.001220703125, 0.000152587890625, 0.0013427734375, 0.002166748046875, 0.00250244140625, 0.00238037109375, 0.00189208984375, 0.001129150390625, 0.000274658203125, -0.000518798828125, -0.0010986328125, -0.001434326171875, -0.00146484375, -0.00128173828125, -0.0008544921875, -0.000396728515625, 0.0001220703125, 0.000518798828125, 0.0008544921875, 0.00091552734375, 0.001068115234375, 0.00067138671875, 0.000946044921875, 0.000457763671875) #chan_filter = gr.interp_fir_filter_ccf(self._gr_interp, chan_filter_coeffs_fixed) #chan_filter_dsp = gr.dsp_fir_ccf (chan_filter_coeffs_fixed, 14, self._gr_interp, 0, 0, 0, 1) #r = gr.enable_realtime_scheduling () if self.DEBUG: print "interpolation rate = ", self._gr_interp # FM modulator k = 2 * math.pi * self.tx_freq_deviation / self.gr_rate modulator = gr.frequency_modulator_fc(k) # Pre-emphasis for FM modulation """ tau is preemphasis time constant, inverse proportional to channel bandwidth """ chan_bw = 2.0*(self.tx_base_band_bw + \ self.tx_freq_deviation)# Carson's rule of FM channel bandwidth tau = 1 / (chan_bw * 0.5) if self.DEBUG: print " channel bandwidth: ", chan_bw print " tau: ", tau preemph = fm_preemph(self.gr_rate, tau) # audio_coeffs = ( # 0.00058729130373770002, # 0.0016584444738215582, # 0.0015819269921330031, # 0.0014607862142637573, # 0.00020681278261230754, #-0.0013001097961560814, #-0.00249802658603143, #-0.0024276134129972843, #-0.00083069749014258953, # 0.0017562878158492619, # 0.003963761120687582, # 0.0043075911442784871, # 0.0020710872871114866, #-0.0020172640629268932, #-0.005882026963765212, #-0.0070692053073845166, #-0.0041954626649490937, # 0.0019311082705710714, # 0.0082980827342646387, # 0.011045923787287403, # 0.0076530405054369872, #-0.0012102332109476402, #-0.011372099802214802, #-0.016910189774436514, #-0.013347352799620162, #-0.00068013535845177706, # 0.015578754320259895, # 0.026379517186832846, # 0.023618496101893545, # 0.0051085800414948012, #-0.022608534445133374, #-0.045529642916534545, #-0.047580556152787695, #-0.018048092177406189, # 0.042354392363985506, # 0.11988807809069109, # 0.19189052073753335, # 0.2351677633079737, # 0.2351677633079737, # 0.19189052073753335, # 0.11988807809069109, # 0.042354392363985506, #-0.018048092177406189, #-0.047580556152787695, #-0.045529642916534545, #-0.022608534445133374, # 0.0051085800414948012, # 0.023618496101893545, # 0.026379517186832846, # 0.015578754320259895, #-0.00068013535845177706, #-0.013347352799620162, #-0.016910189774436514, #-0.011372099802214802, #-0.0012102332109476402, # 0.0076530405054369872, # 0.011045923787287403, # 0.0082980827342646387, # 0.0019311082705710714, #-0.0041954626649490937, #-0.0070692053073845166, #-0.005882026963765212, #-0.0020172640629268932, # 0.0020710872871114866, # 0.0043075911442784871, # 0.003963761120687582, # 0.0017562878158492619, #-0.00083069749014258953, #-0.0024276134129972843, #-0.00249802658603143, #-0.0013001097961560814, # 0.00020681278261230754, # 0.0014607862142637573, # 0.0015819269921330031, # 0.0016584444738215582, # 0.00058729130373770002) audio_coeffs = (-0.021392822265625, -0.0194091796875, 0.02972412109375, -0.018341064453125, -0.025299072265625, 0.07745361328125, -0.08251953125, -0.033905029296875, 0.56634521484375, 0.56634521484375, -0.033905029296875, -0.08251953125, 0.07745361328125, -0.025299072265625, -0.018341064453125, 0.02972412109375, -0.0194091796875, -0.021392822265625) #audio_coeffs = ( # -0.21392822265625, # -0.194091796875, # 0.2972412109375, # -0.18341064453125, # -0.25299072265625, # 0.7745361328125, # -0.8251953125, # -0.33905029296875, # 5.6634521484375, # 5.6634521484375, # -0.33905029296875, # -0.8251953125, # 0.7745361328125, # -0.25299072265625, # -0.18341064453125, # 0.2972412109375, # -0.194091796875, # -0.21392822265625) self.audio_filter = gr.interp_fir_filter_fff(self._gr_interp, audio_coeffs) #Source audio Low-pass Filter #self.audio_throt = gr.multiply_const_ff(50) self.audio_throt = gr.multiply_const_ff(5) if self.DEBUG: print "audio decim FIR filter tap length:", len(audio_coeffs) # Setup audio source src = audio.source(int(self.audio_rate), audio_input) # Wiring up #self.connect(src, self.audio_throt, interpolator, preemph, modulator, chan_filter_dsp, self.gr_amp, self.u) self.connect(src, self.audio_throt, self.audio_filter, modulator, self.gr_amp, self.u)
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) parser = OptionParser(option_class=eng_option) parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, help="select USRP Tx side A or B") parser.add_option("-f", "--freq", type="eng_float", default=107.2e6, help="set Tx frequency to FREQ [required]", metavar="FREQ") parser.add_option("--wavfile", type="string", default="", help="read input from FILE") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.usrp_interp = 200 self.u = usrp.sink_c(0, self.usrp_interp) print "USRP Serial: ", self.u.serial_number() self.dac_rate = self.u.dac_rate() # 128 MS/s self.usrp_rate = self.dac_rate / self.usrp_interp # 640 kS/s self.sw_interp = 5 self.audio_rate = self.usrp_rate / self.sw_interp # 128 kS/s # determine the daughterboard subdevice we're using if options.tx_subdev_spec is None: options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u) self.u.set_mux( usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec)) self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec) print "Using d'board: ", self.subdev.side_and_name() # set max Tx gain, tune frequency and enable transmitter self.subdev.set_gain(self.subdev.gain_range()[1]) if self.u.tune(self.subdev.which(), self.subdev, options.freq): print "Tuned to", options.freq / 1e6, "MHz" else: sys.exit(1) self.subdev.set_enable(True) # open wav file containing floats in the [-1, 1] range, repeat if options.wavfile is None: print "Please provide a wavfile to transmit! Exiting\n" sys.exit(1) self.src = gr.wavfile_source(options.wavfile, True) nchans = self.src.channels() sample_rate = self.src.sample_rate() bits_per_sample = self.src.bits_per_sample() print nchans, "channels,", sample_rate, "kS/s,", bits_per_sample, "bits/sample" # resample to 128kS/s if sample_rate == 44100: self.resample_left = blks2.rational_resampler_fff(32, 11) self.resample_right = blks2.rational_resampler_fff(32, 11) elif sample_rate == 48000: self.resample_left == blks2.rational_resampler_fff(8, 3) self.resample_right == blks2.rational_resampler_fff(8, 3) elif sample_rate == 8000: self.resample_left == blks2.rational_resampler_fff(16, 1) self.resample_right == blks2.rational_resampler_fff(16, 1) else: print sample_rate, "is an unsupported sample rate" sys.exit(1) self.connect((self.src, 0), self.resample_left) self.connect((self.src, 1), self.resample_right) # create L+R (mono) and L-R (stereo) self.audio_lpr = gr.add_ff() self.audio_lmr = gr.sub_ff() self.connect(self.resample_left, (self.audio_lpr, 0)) self.connect(self.resample_left, (self.audio_lmr, 0)) self.connect(self.resample_right, (self.audio_lpr, 1)) self.connect(self.resample_right, (self.audio_lmr, 1)) # low-pass filter for L+R audio_lpr_taps = gr.firdes.low_pass( 0.3, # gain self.audio_rate, # sampling rate 15e3, # passband cutoff 2e3, # transition width gr.firdes.WIN_HANN) self.audio_lpr_filter = gr.fir_filter_fff(1, audio_lpr_taps) self.connect(self.audio_lpr, self.audio_lpr_filter) # create pilot tone at 19 kHz self.pilot = gr.sig_source_f( self.audio_rate, # sampling freq gr.GR_SIN_WAVE, # waveform 19e3, # frequency 3e-2) # amplitude # create the L-R signal carrier at 38 kHz, high-pass to remove 0Hz tone self.stereo_carrier = gr.multiply_ff() self.connect(self.pilot, (self.stereo_carrier, 0)) self.connect(self.pilot, (self.stereo_carrier, 1)) stereo_carrier_taps = gr.firdes.high_pass( 1, # gain self.audio_rate, # sampling rate 1e4, # cutoff freq 2e3, # transition width gr.firdes.WIN_HANN) self.stereo_carrier_filter = gr.fir_filter_fff(1, stereo_carrier_taps) self.connect(self.stereo_carrier, self.stereo_carrier_filter) # upconvert L-R to 23-53 kHz and band-pass self.mix_stereo = gr.multiply_ff() audio_lmr_taps = gr.firdes.band_pass( 3e3, # gain self.audio_rate, # sampling rate 23e3, # low cutoff 53e3, # high cuttof 2e3, # transition width gr.firdes.WIN_HANN) self.audio_lmr_filter = gr.fir_filter_fff(1, audio_lmr_taps) self.connect(self.audio_lmr, (self.mix_stereo, 0)) self.connect(self.stereo_carrier_filter, (self.mix_stereo, 1)) self.connect(self.mix_stereo, self.audio_lmr_filter) # mix L+R, pilot and L-R self.mixer = gr.add_ff() self.connect(self.audio_lpr_filter, (self.mixer, 0)) self.connect(self.pilot, (self.mixer, 1)) self.connect(self.audio_lmr_filter, (self.mixer, 2)) # interpolation & pre-emphasis interp_taps = gr.firdes.low_pass( self.sw_interp, # gain self.audio_rate, # Fs 60e3, # cutoff freq 5e3, # transition width gr.firdes.WIN_HAMMING) self.interpolator = gr.interp_fir_filter_fff(self.sw_interp, interp_taps) self.pre_emph = blks2.fm_preemph(self.usrp_rate, tau=50e-6) self.connect(self.mixer, self.interpolator, self.pre_emph) # fm modulation, gain & TX max_dev = 100e3 k = 2 * math.pi * max_dev / self.usrp_rate # modulator sensitivity self.modulator = gr.frequency_modulator_fc(k) self.gain = gr.multiply_const_cc(1e3) self.connect(self.pre_emph, self.modulator, self.gain, self.u) # plot an FFT to verify we are sending what we want pre_mod = fftsink2.fft_sink_f(panel, title="Before Interpolation", fft_size=512, sample_rate=self.audio_rate, y_per_div=20, ref_level=20) self.connect(self.mixer, pre_mod) vbox.Add(pre_mod.win, 1, wx.EXPAND)
def __init__(self, options, queue): gr.top_block.__init__(self, "mhp") sample_rate = options.sample_rate arity = 2 IN = gr.file_source(gr.sizeof_char, options.input_file, options.repeat) B2C = gr.packed_to_unpacked_bb(arity, gr.GR_MSB_FIRST) mod_map = [1.0, 3.0, -1.0, -3.0] C2S = gr.chunks_to_symbols_bf(mod_map) if options.reverse: polarity = gr.multiply_const_ff(-1) else: polarity = gr.multiply_const_ff(1) symbol_rate = 4800 samples_per_symbol = sample_rate // symbol_rate excess_bw = 0.1 ntaps = 11 * samples_per_symbol rrc_taps = gr.firdes.root_raised_cosine( samples_per_symbol, # gain (sps since we're interpolating by sps samples_per_symbol, # sampling rate 1.0, # symbol rate excess_bw, # excess bandwidth (roll-off factor) ntaps) rrc_filter = gr.interp_fir_filter_fff(samples_per_symbol, rrc_taps) rrc_coeffs = [ 0, -0.003, -0.006, -0.009, -0.012, -0.014, -0.014, -0.013, -0.01, -0.006, 0, 0.007, 0.014, 0.02, 0.026, 0.029, 0.029, 0.027, 0.021, 0.012, 0, -0.013, -0.027, -0.039, -0.049, -0.054, -0.055, -0.049, -0.038, -0.021, 0, 0.024, 0.048, 0.071, 0.088, 0.098, 0.099, 0.09, 0.07, 0.039, 0, -0.045, -0.091, -0.134, -0.17, -0.193, -0.199, -0.184, -0.147, -0.085, 0, 0.105, 0.227, 0.36, 0.496, 0.629, 0.751, 0.854, 0.933, 0.983, 1, 0.983, 0.933, 0.854, 0.751, 0.629, 0.496, 0.36, 0.227, 0.105, 0, -0.085, -0.147, -0.184, -0.199, -0.193, -0.17, -0.134, -0.091, -0.045, 0, 0.039, 0.07, 0.09, 0.099, 0.098, 0.088, 0.071, 0.048, 0.024, 0, -0.021, -0.038, -0.049, -0.055, -0.054, -0.049, -0.039, -0.027, -0.013, 0, 0.012, 0.021, 0.027, 0.029, 0.029, 0.026, 0.02, 0.014, 0.007, 0, -0.006, -0.01, -0.013, -0.014, -0.014, -0.012, -0.009, -0.006, -0.003, 0 ] # rrc_coeffs work slightly differently: each input sample # (from mod_map above) at 4800 rate, then 9 zeros are inserted # to bring to a 48000 rate, then this filter is applied: # rrc_filter = gr.fir_filter_fff(1, rrc_coeffs) # FIXME: how to insert the 9 zero samples using gr ? # FM pre-emphasis filter shaping_coeffs = [ -0.018, 0.0347, 0.0164, -0.0064, -0.0344, -0.0522, -0.0398, 0.0099, 0.0798, 0.1311, 0.121, 0.0322, -0.113, -0.2499, -0.3007, -0.2137, -0.0043, 0.2825, 0.514, 0.604, 0.514, 0.2825, -0.0043, -0.2137, -0.3007, -0.2499, -0.113, 0.0322, 0.121, 0.1311, 0.0798, 0.0099, -0.0398, -0.0522, -0.0344, -0.0064, 0.0164, 0.0347, -0.018 ] shaping_filter = gr.fir_filter_fff(1, shaping_coeffs) OUT = audio.sink(sample_rate, options.audio_output) amp = gr.multiply_const_ff(options.factor) self.connect(IN, B2C, C2S, polarity, rrc_filter, shaping_filter, amp) # output to both L and R channels self.connect(amp, (OUT, 0)) self.connect(amp, (OUT, 1))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Rds Tx") _icon_path = "/home/azimout/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.usrp_interp = usrp_interp = 500 self.dac_rate = dac_rate = 128e6 self.wav_rate = wav_rate = 44100 self.usrp_rate = usrp_rate = int(dac_rate / usrp_interp) self.fm_max_dev = fm_max_dev = 120e3 ################################################## # Blocks ################################################## self.band_pass_filter_0 = gr.interp_fir_filter_fff( 1, firdes.band_pass(1, usrp_rate, 54e3, 60e3, 3e3, firdes.WIN_HAMMING, 6.76)) self.band_pass_filter_1 = gr.interp_fir_filter_fff( 1, firdes.band_pass(1, usrp_rate, 23e3, 53e3, 2e3, firdes.WIN_HAMMING, 6.76)) self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_fff( interpolation=usrp_rate, decimation=wav_rate, taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_1_0 = blks2.rational_resampler_fff( interpolation=usrp_rate, decimation=wav_rate, taps=None, fractional_bw=None, ) self.gr_add_xx_0 = gr.add_vff(1) self.gr_add_xx_1 = gr.add_vff(1) self.gr_char_to_float_0 = gr.char_to_float() self.gr_diff_encoder_bb_0 = gr.diff_encoder_bb(2) self.gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc( 2 * math.pi * fm_max_dev / usrp_rate) self.gr_map_bb_0 = gr.map_bb(([-1, 1])) self.gr_map_bb_1 = gr.map_bb(([1, 2])) self.gr_multiply_xx_0 = gr.multiply_vff(1) self.gr_multiply_xx_1 = gr.multiply_vff(1) self.gr_rds_data_encoder_0 = rds.data_encoder( "/media/dimitris/mywork/gr/dimitris/rds/trunk/src/test/rds_data.xml" ) self.gr_rds_rate_enforcer_0 = rds.rate_enforcer(256000) self.gr_sig_source_x_0 = gr.sig_source_f(usrp_rate, gr.GR_COS_WAVE, 19e3, 0.3, 0) self.gr_sub_xx_0 = gr.sub_ff(1) self.gr_unpack_k_bits_bb_0 = gr.unpack_k_bits_bb(2) self.gr_wavfile_source_0 = gr.wavfile_source( "/media/dimitris/mywork/gr/dimitris/rds/trunk/src/python/limmenso_stereo.wav", True) self.low_pass_filter_0 = gr.interp_fir_filter_fff( 1, firdes.low_pass(1, usrp_rate, 1.5e3, 2e3, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0_0 = gr.interp_fir_filter_fff( 1, firdes.low_pass(1, usrp_rate, 15e3, 2e3, firdes.WIN_HAMMING, 6.76)) self.usrp_simple_sink_x_0 = grc_usrp.simple_sink_c(which=0, side="A") self.usrp_simple_sink_x_0.set_interp_rate(500) self.usrp_simple_sink_x_0.set_frequency(107.2e6, verbose=True) self.usrp_simple_sink_x_0.set_gain(0) self.usrp_simple_sink_x_0.set_enable(True) self.usrp_simple_sink_x_0.set_auto_tr(True) self.wxgui_fftsink2_0 = fftsink2.fft_sink_f( self.GetWin(), baseband_freq=0, y_per_div=20, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=usrp_rate, fft_size=1024, fft_rate=30, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) ################################################## # Connections ################################################## self.connect((self.gr_sig_source_x_0, 0), (self.gr_rds_rate_enforcer_0, 1)) self.connect((self.gr_char_to_float_0, 0), (self.gr_rds_rate_enforcer_0, 0)) self.connect((self.gr_map_bb_0, 0), (self.gr_char_to_float_0, 0)) self.connect((self.gr_frequency_modulator_fc_0, 0), (self.usrp_simple_sink_x_0, 0)) self.connect((self.gr_add_xx_1, 0), (self.gr_frequency_modulator_fc_0, 0)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_add_xx_1, 1)) self.connect((self.gr_sub_xx_0, 0), (self.gr_multiply_xx_1, 2)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_1, 1)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_1, 0)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 3)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 2)) self.connect((self.blks2_rational_resampler_xxx_1_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_add_xx_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1_0, 0), (self.gr_sub_xx_0, 1)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_sub_xx_0, 0)) self.connect((self.gr_wavfile_source_0, 1), (self.blks2_rational_resampler_xxx_1_0, 0)) self.connect((self.gr_wavfile_source_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) self.connect((self.gr_rds_data_encoder_0, 0), (self.gr_diff_encoder_bb_0, 0)) self.connect((self.gr_diff_encoder_bb_0, 0), (self.gr_map_bb_1, 0)) self.connect((self.gr_map_bb_1, 0), (self.gr_unpack_k_bits_bb_0, 0)) self.connect((self.gr_unpack_k_bits_bb_0, 0), (self.gr_map_bb_0, 0)) self.connect((self.gr_rds_rate_enforcer_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.band_pass_filter_0, 0), (self.gr_add_xx_1, 0)) self.connect((self.gr_multiply_xx_1, 0), (self.band_pass_filter_1, 0)) self.connect((self.band_pass_filter_1, 0), (self.gr_add_xx_1, 3)) self.connect((self.gr_add_xx_1, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_add_xx_0, 0), (self.low_pass_filter_0_0, 0)) self.connect((self.low_pass_filter_0_0, 0), (self.gr_add_xx_1, 2))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Rds Tx") _icon_path = "/home/azimout/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.usrp_interp = usrp_interp = 500 self.dac_rate = dac_rate = 128e6 self.wav_rate = wav_rate = 44100 self.usrp_rate = usrp_rate = int(dac_rate/usrp_interp) self.fm_max_dev = fm_max_dev = 120e3 ################################################## # Blocks ################################################## self.band_pass_filter_0 = gr.interp_fir_filter_fff(1, firdes.band_pass( 1, usrp_rate, 54e3, 60e3, 3e3, firdes.WIN_HAMMING, 6.76)) self.band_pass_filter_1 = gr.interp_fir_filter_fff(1, firdes.band_pass( 1, usrp_rate, 23e3, 53e3, 2e3, firdes.WIN_HAMMING, 6.76)) self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_fff( interpolation=usrp_rate, decimation=wav_rate, taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_1_0 = blks2.rational_resampler_fff( interpolation=usrp_rate, decimation=wav_rate, taps=None, fractional_bw=None, ) self.gr_add_xx_0 = gr.add_vff(1) self.gr_add_xx_1 = gr.add_vff(1) self.gr_char_to_float_0 = gr.char_to_float() self.gr_diff_encoder_bb_0 = gr.diff_encoder_bb(2) self.gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(2*math.pi*fm_max_dev/usrp_rate) self.gr_map_bb_0 = gr.map_bb(([-1,1])) self.gr_map_bb_1 = gr.map_bb(([1,2])) self.gr_multiply_xx_0 = gr.multiply_vff(1) self.gr_multiply_xx_1 = gr.multiply_vff(1) self.gr_rds_data_encoder_0 = rds.data_encoder("/media/dimitris/mywork/gr/dimitris/rds/trunk/src/test/rds_data.xml") self.gr_rds_rate_enforcer_0 = rds.rate_enforcer(256000) self.gr_sig_source_x_0 = gr.sig_source_f(usrp_rate, gr.GR_COS_WAVE, 19e3, 0.3, 0) self.gr_sub_xx_0 = gr.sub_ff(1) self.gr_unpack_k_bits_bb_0 = gr.unpack_k_bits_bb(2) self.gr_wavfile_source_0 = gr.wavfile_source("/media/dimitris/mywork/gr/dimitris/rds/trunk/src/python/limmenso_stereo.wav", True) self.low_pass_filter_0 = gr.interp_fir_filter_fff(1, firdes.low_pass( 1, usrp_rate, 1.5e3, 2e3, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0_0 = gr.interp_fir_filter_fff(1, firdes.low_pass( 1, usrp_rate, 15e3, 2e3, firdes.WIN_HAMMING, 6.76)) self.usrp_simple_sink_x_0 = grc_usrp.simple_sink_c(which=0, side="A") self.usrp_simple_sink_x_0.set_interp_rate(500) self.usrp_simple_sink_x_0.set_frequency(107.2e6, verbose=True) self.usrp_simple_sink_x_0.set_gain(0) self.usrp_simple_sink_x_0.set_enable(True) self.usrp_simple_sink_x_0.set_auto_tr(True) self.wxgui_fftsink2_0 = fftsink2.fft_sink_f( self.GetWin(), baseband_freq=0, y_per_div=20, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=usrp_rate, fft_size=1024, fft_rate=30, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) ################################################## # Connections ################################################## self.connect((self.gr_sig_source_x_0, 0), (self.gr_rds_rate_enforcer_0, 1)) self.connect((self.gr_char_to_float_0, 0), (self.gr_rds_rate_enforcer_0, 0)) self.connect((self.gr_map_bb_0, 0), (self.gr_char_to_float_0, 0)) self.connect((self.gr_frequency_modulator_fc_0, 0), (self.usrp_simple_sink_x_0, 0)) self.connect((self.gr_add_xx_1, 0), (self.gr_frequency_modulator_fc_0, 0)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_add_xx_1, 1)) self.connect((self.gr_sub_xx_0, 0), (self.gr_multiply_xx_1, 2)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_1, 1)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_1, 0)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 3)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 2)) self.connect((self.blks2_rational_resampler_xxx_1_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_add_xx_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1_0, 0), (self.gr_sub_xx_0, 1)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_sub_xx_0, 0)) self.connect((self.gr_wavfile_source_0, 1), (self.blks2_rational_resampler_xxx_1_0, 0)) self.connect((self.gr_wavfile_source_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) self.connect((self.gr_rds_data_encoder_0, 0), (self.gr_diff_encoder_bb_0, 0)) self.connect((self.gr_diff_encoder_bb_0, 0), (self.gr_map_bb_1, 0)) self.connect((self.gr_map_bb_1, 0), (self.gr_unpack_k_bits_bb_0, 0)) self.connect((self.gr_unpack_k_bits_bb_0, 0), (self.gr_map_bb_0, 0)) self.connect((self.gr_rds_rate_enforcer_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.band_pass_filter_0, 0), (self.gr_add_xx_1, 0)) self.connect((self.gr_multiply_xx_1, 0), (self.band_pass_filter_1, 0)) self.connect((self.band_pass_filter_1, 0), (self.gr_add_xx_1, 3)) self.connect((self.gr_add_xx_1, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_add_xx_0, 0), (self.low_pass_filter_0_0, 0)) self.connect((self.low_pass_filter_0_0, 0), (self.gr_add_xx_1, 2))
def __init__(self, output_sample_rate=_def_output_sample_rate, excess_bw=_def_excess_bw, reverse=_def_reverse, verbose=_def_verbose, log=_def_log): """ Hierarchical block for RRC-filtered P25 FM modulation. The input is a dibit (P25 symbol) stream (char, not packed) and the output is the float "C4FM" signal at baseband, suitable for application to an FM modulator stage Input is at the base symbol rate (4800), output sample rate is typically either 32000 (USRP TX chain) or 48000 (sound card) @param output_sample_rate: output sample rate @type output_sample_rate: integer @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float @param reverse: reverse polarity flag @type reverse: bool @param verbose: Print information about modulator? @type verbose: bool @param debug: Print modulation data to files? @type debug: bool """ gr.hier_block2.__init__( self, "p25_c4fm_mod_bf", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature input_sample_rate = 4800 # P25 baseband symbol rate lcm = gru.lcm(input_sample_rate, output_sample_rate) self._interp_factor = int(lcm // input_sample_rate) self._decimation = int(lcm // output_sample_rate) self._excess_bw = excess_bw mod_map = [1.0 / 3.0, 1.0, -(1.0 / 3.0), -1.0] self.C2S = gr.chunks_to_symbols_bf(mod_map) if reverse: self.polarity = gr.multiply_const_ff(-1) else: self.polarity = gr.multiply_const_ff(1) ntaps = 11 * self._interp_factor rrc_taps = gr.firdes.root_raised_cosine( self._interp_factor, # gain (since we're interpolating by sps) lcm, # sampling rate input_sample_rate, # symbol rate self._excess_bw, # excess bandwidth (roll-off factor) ntaps) # rrc_coeffs work slightly differently: each input sample # (from mod_map above) at 4800 rate, then 9 zeros are inserted # to bring to 48000 rate, then this filter is applied: # rrc_filter = gr.fir_filter_fff(1, rrc_coeffs) # FIXME: how to insert the 9 zero samples using gr ? # rrc_coeffs = [0, -0.003, -0.006, -0.009, -0.012, -0.014, -0.014, -0.013, -0.01, -0.006, 0, 0.007, 0.014, 0.02, 0.026, 0.029, 0.029, 0.027, 0.021, 0.012, 0, -0.013, -0.027, -0.039, -0.049, -0.054, -0.055, -0.049, -0.038, -0.021, 0, 0.024, 0.048, 0.071, 0.088, 0.098, 0.099, 0.09, 0.07, 0.039, 0, -0.045, -0.091, -0.134, -0.17, -0.193, -0.199, -0.184, -0.147, -0.085, 0, 0.105, 0.227, 0.36, 0.496, 0.629, 0.751, 0.854, 0.933, 0.983, 1, 0.983, 0.933, 0.854, 0.751, 0.629, 0.496, 0.36, 0.227, 0.105, 0, -0.085, -0.147, -0.184, -0.199, -0.193, -0.17, -0.134, -0.091, -0.045, 0, 0.039, 0.07, 0.09, 0.099, 0.098, 0.088, 0.071, 0.048, 0.024, 0, -0.021, -0.038, -0.049, -0.055, -0.054, -0.049, -0.039, -0.027, -0.013, 0, 0.012, 0.021, 0.027, 0.029, 0.029, 0.026, 0.02, 0.014, 0.007, 0, -0.006, -0.01, -0.013, -0.014, -0.014, -0.012, -0.009, -0.006, -0.003, 0] self.rrc_filter = gr.interp_fir_filter_fff(self._interp_factor, rrc_taps) # FM pre-emphasis filter shaping_coeffs = [ -0.018, 0.0347, 0.0164, -0.0064, -0.0344, -0.0522, -0.0398, 0.0099, 0.0798, 0.1311, 0.121, 0.0322, -0.113, -0.2499, -0.3007, -0.2137, -0.0043, 0.2825, 0.514, 0.604, 0.514, 0.2825, -0.0043, -0.2137, -0.3007, -0.2499, -0.113, 0.0322, 0.121, 0.1311, 0.0798, 0.0099, -0.0398, -0.0522, -0.0344, -0.0064, 0.0164, 0.0347, -0.018 ] self.shaping_filter = gr.fir_filter_fff(1, shaping_coeffs) if verbose: self._print_verbage() if log: self._setup_logging() self.connect(self, self.C2S, self.polarity, self.rrc_filter, self.shaping_filter) if (self._decimation > 1): self.decimator = blks2.rational_resampler_fff(1, self._decimation) self.connect(self.shaping_filter, self.decimator, self) else: self.connect(self.shaping_filter, self)
def __init__(self, samples_per_symbol=_def_samples_per_symbol, bits_per_symbol=_def_bits_per_symbol, h_numerator=_def_h_numerator, h_denominator=_def_h_denominator, cpm_type=_def_cpm_type, bt=_def_bt, symbols_per_pulse=_def_symbols_per_pulse, generic_taps=_def_generic_taps, verbose=_def_verbose, log=_def_log): """ Hierarchical block for Continuous Phase modulation. The input is a byte stream (unsigned char) representing packed bits and the output is the complex modulated signal at baseband. See Proakis for definition of generic CPM signals: s(t)=exp(j phi(t)) phi(t)= 2 pi h int_0^t f(t') dt' f(t)=sum_k a_k g(t-kT) (normalizing assumption: int_0^infty g(t) dt = 1/2) @param samples_per_symbol: samples per baud >= 2 @type samples_per_symbol: integer @param bits_per_symbol: bits per symbol @type bits_per_symbol: integer @param h_numerator: numerator of modulation index @type h_numerator: integer @param h_denominator: denominator of modulation index (numerator and denominator must be relative primes) @type h_denominator: integer @param cpm_type: supported types are: 0=CPFSK, 1=GMSK, 2=RC, 3=GENERAL @type cpm_type: integer @param bt: bandwidth symbol time product for GMSK @type bt: float @param symbols_per_pulse: shaping pulse duration in symbols @type symbols_per_pulse: integer @param generic_taps: define a generic CPM pulse shape (sum = samples_per_symbol/2) @type generic_taps: array of floats @param verbose: Print information about modulator? @type verbose: bool @param debug: Print modulation data to files? @type debug: bool """ gr.hier_block2.__init__("cpm_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._bits_per_symbol = bits_per_symbol self._h_numerator = h_numerator self._h_denominator = h_denominator self._cpm_type = cpm_type self._bt=bt if cpm_type == 0 or cpm_type == 2 or cpm_type == 3: # CPFSK, RC, Generic self._symbols_per_pulse = symbols_per_pulse elif cpm_type == 1: # GMSK self._symbols_per_pulse = 4 else: raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,)) self._generic_taps=numpy.array(generic_taps) if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol,)) self.nsymbols = 2**bits_per_symbol self.sym_alphabet=numpy.arange(-(self.nsymbols-1),self.nsymbols,2) self.ntaps = self._symbols_per_pulse * samples_per_symbol sensitivity = 2 * pi * h_numerator / h_denominator / samples_per_symbol # Unpack Bytes into bits_per_symbol groups self.B2s = gr.packed_to_unpacked_bb(bits_per_symbol,gr.GR_MSB_FIRST) # Turn it into symmetric PAM data. self.pam = gr.chunks_to_symbols_bf(self.sym_alphabet,1) # Generate pulse (sum of taps = samples_per_symbol/2) if cpm_type == 0: # CPFSK self.taps= (1.0/self._symbols_per_pulse/2,) * self.ntaps elif cpm_type == 1: # GMSK gaussian_taps = gr.firdes.gaussian( 1.0/2, # gain samples_per_symbol, # symbol_rate bt, # bandwidth * symbol time self.ntaps # number of taps ) sqwave = (1,) * samples_per_symbol # rectangular window self.taps = numpy.convolve(numpy.array(gaussian_taps),numpy.array(sqwave)) elif cpm_type == 2: # Raised Cosine # generalize it for arbitrary roll-off factor self.taps = (1-numpy.cos(2*pi*numpy.arange(0,self.ntaps)/samples_per_symbol/self._symbols_per_pulse))/(2*self._symbols_per_pulse) elif cpm_type == 3: # Generic CPM self.taps = generic_taps else: raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,)) self.filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) # FM modulation self.fmmod = gr.frequency_modulator_fc(sensitivity) if verbose: self._print_verbage() if log: self._setup_logging() # Connect self.connect(self, self.B2s, self.pam, self.filter, self.fmmod, self)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Scrambler") _icon_path = "/home/pfb/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 32000 ################################################## # Blocks ################################################## self.gr_add_xx_0 = gr.add_vff(1) self.gr_char_to_float_0 = gr.char_to_float() self.gr_interp_fir_filter_xxx_0 = gr.interp_fir_filter_fff(4, (24, )) self.gr_multiply_xx_0 = gr.multiply_vff(1) self.gr_scrambler_bb_0 = gr.scrambler_bb(0x8A, 0x7F, 7) self.gr_throttle_0 = gr.throttle(gr.sizeof_char * 1, samp_rate) self.gr_vector_source_x_0 = gr.vector_source_b((0, 0, 0), True, 1) self.gr_vector_source_x_0_0 = gr.vector_source_f((-0.5, ), True, 1) self.gr_vector_source_x_0_0_0 = gr.vector_source_f((2.0, ), True, 1) self.wxgui_fftsink2_0 = fftsink2.fft_sink_f( self.GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=50, ref_scale=2.0, sample_rate=samp_rate * 2, fft_size=4096, fft_rate=30, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.GetWin(), title="Scope Plot", sample_rate=samp_rate, v_scale=1, v_offset=0, t_scale=.0005, ac_couple=False, xy_mode=False, num_inputs=1, ) self.Add(self.wxgui_scopesink2_0.win) ################################################## # Connections ################################################## self.connect((self.gr_scrambler_bb_0, 0), (self.gr_char_to_float_0, 0)) self.connect((self.gr_vector_source_x_0, 0), (self.gr_throttle_0, 0)) self.connect((self.gr_throttle_0, 0), (self.gr_scrambler_bb_0, 0)) self.connect((self.gr_char_to_float_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.gr_add_xx_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_vector_source_x_0_0, 0), (self.gr_add_xx_0, 0)) self.connect((self.gr_vector_source_x_0_0_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.gr_interp_fir_filter_xxx_0, 0)) self.connect((self.gr_interp_fir_filter_xxx_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.gr_interp_fir_filter_xxx_0, 0), (self.wxgui_scopesink2_0, 0))
def main(): parser = OptionParser(option_class=eng_option) parser.add_option("-f", "--freq", type="eng_float", default=144.800e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-m", "--message", type="string", default=":ALL :this is a test", help="message to send", metavar="MESSAGE") parser.add_option("-c", "--mycall", type="string", default="MYCALL", help="source callsign", metavar="CALL") parser.add_option("-t", "--tocall", type="string", default="CQ", help="recipient callsign", metavar="CALL") parser.add_option("-v", "--via", type="string", default="RELAY", help="digipeater callsign", metavar="CALL") parser.add_option("-d", "--do-logging", action="store_true", default=False, help="enable logging on datafiles") parser.add_option("-s", "--use-datafile", action="store_true", default=False, help="use usrp.dat (256kbps) as output") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) bitrate = 9600 dac_rate = 128e6 usrp_interp = 500 cordic_freq = options.freq - dac_rate sf = 153600 syminterp = sf / bitrate #16 nbfmdev = 3e3 fmsens = 2 * pi * nbfmdev / (sf * 5 / 3) bit_oversampling = 8 sw_interp = int(sf / bitrate / bit_oversampling) #2 fg = gr.flow_graph() p = buildpacket(options.mycall, 0, options.tocall, 0, options.via, 0, 0x03, 0xf0, options.message) if options.do_logging: dumppackettofile(p, "packet.dat") v = bits2syms(nrziencode(scrambler(hdlcpacket(p, 100, 1000)))) src = gr.vector_source_f(v) gaussian_taps = gr.firdes.gaussian( 1, # gain bit_oversampling, # symbol_rate 0.3, # bandwidth * symbol time 4 * bit_oversampling # number of taps ) sqwave = (1, ) * syminterp #rectangular window taps = Numeric.convolve(Numeric.array(gaussian_taps), Numeric.array(sqwave)) gaussian = gr.interp_fir_filter_fff(syminterp, taps) #9600*16=153600 res_taps = blks.design_filter(5, 3, 0.4) res = blks.rational_resampler_fff(fg, 5, 3, res_taps) #153600*5/3=256000 fmmod = gr.frequency_modulator_fc(fmsens) amp = gr.multiply_const_cc(32000) if options.use_datafile: dst = gr.file_sink(gr.sizeof_gr_complex, "usrp.dat") else: u = usrp.sink_c(0, usrp_interp) #256000*500=128000000 tx_subdev_spec = usrp.pick_tx_subdevice(u) m = usrp.determine_tx_mux_value(u, tx_subdev_spec) print "mux = %#04x" % (m, ) u.set_mux(m) subdev = usrp.selected_subdev(u, tx_subdev_spec) print "Using TX d'board %s" % (subdev.side_and_name(), ) u.set_tx_freq(0, cordic_freq) u.set_pga(0, 0) print "Actual frequency: ", u.tx_freq(0) dst = u fg.connect(src, gaussian, res, fmmod, amp, dst) fg.start() fg.wait()
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-a", "--audio-input", type="string", default="") parser.add_option("-A", "--audio-output", type="string", default="") parser.add_option("-f", "--factor", type="eng_float", default=1) parser.add_option("-i", "--do-interp", action="store_true", default=False, help="enable output interpolator") parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample rate") parser.add_option("-S", "--stretch", type="int", default=0, help="flex amt") parser.add_option("-y", "--symbol-rate", type="int", default=4800, help="input symbol rate") parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data") (options, args) = parser.parse_args() sample_rate = options.sample_rate symbol_rate = options.symbol_rate IN = audio.source(sample_rate, options.audio_input) audio_output_rate = 8000 if options.do_interp: audio_output_rate = 48000 OUT = audio.sink(audio_output_rate, options.audio_output) symbol_decim = 1 symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain sample_rate, # sampling rate symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type SYMBOL_FILTER = gr.fir_filter_fff(symbol_decim, symbol_coeffs) AMP = gr.multiply_const_ff(options.factor) msgq = gr.msg_queue(2) FSK4 = op25.fsk4_demod_ff(msgq, sample_rate, symbol_rate) levels = levels = [-2.0, 0.0, 2.0, 4.0] SLICER = repeater.fsk4_slicer_fb(levels) framer_msgq = gr.msg_queue(2) DECODE = repeater.p25_frame_assembler( '', # udp hostname 0, # udp port no. options.verbose, #debug True, # do_imbe True, # do_output False, # do_msgq framer_msgq) IMBE = repeater.vocoder( False, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors CVT = gr.short_to_float() if options.do_interp: interp_taps = gr.firdes.low_pass(1.0, 48000, 4000, 4000 * 0.1, gr.firdes.WIN_HANN) INTERP = gr.interp_fir_filter_fff(48000 // 8000, interp_taps) AMP2 = gr.multiply_const_ff(1.0 / 32767.0) self.connect(IN, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODE, IMBE, CVT, AMP2) if options.do_interp: self.connect(AMP2, INTERP, OUT) else: self.connect(AMP2, OUT)
def __init__(self, freq, subdev_spec, which_USRP, audio_input, debug): #gr.hier_block2.__init__(self, "analog_transmit_path", # gr.io_signature(0, 0, 0), #input signature # gr.io_signature(0, 0, 0)) #output signature gr.top_block.__init__(self) self.DEBUG = debug self.freq = freq #self.freq = 462562500 # audio_input="hw:0" #Formerly from XML self.tx_usrp_pga_gain_scaling = 1.0 self.tx_power = 1 self.tx_mod_type = 'fm' self.tx_freq_deviation = 2.5e3 self.tx_base_band_bw = 5e3 ################## USRP settings ################### r = gr.enable_realtime_scheduling () # acquire USRP via USB 2.0 #self.u = usrp.sink_c(fusb_block_size=1024, # fusb_nblocks=4, # which=which_USRP) self.u = uhd.single_usrp_sink( device_addr="", io_type=uhd.io_type_t.COMPLEX_FLOAT32, num_channels=1, ) # get D/A converter sampling rate #self.dac_rate = self.u.dac_rate() #128 MS/s self.dac_rate = 128e6 #128 MS/s if self.DEBUG: print " Tx Path DAC rate: %d" %(self.dac_rate) #System digital sample rate setting self.audio_rate = 16e3 self._gr_interp = 16 self.max_gr_interp_rate = 40 self._usrp_interp = 500 self.gr_rate = self.dac_rate / self._usrp_interp self._gr_decim = 1 if self.DEBUG: print " usrp interp: ", self._usrp_interp print " gr interp: ", self._gr_interp print " gr rate1: ", self.gr_rate print " gr decim: ", self._gr_decim print " audio rate: ", self.audio_rate # set USRP interplation ratio #self.u.set_interp_rate(self._usrp_interp) self.u.set_samp_rate(self.gr_rate) # set USRP daughterboard subdevice #if subdev_spec is None: # subdev_spec = usrp.pick_tx_subdevice(self.u) #self.u.set_mux(usrp.determine_tx_mux_value(self.u, subdev_spec)) #self.subdev = usrp.selected_subdev(self.u, subdev_spec) self.u.set_antenna("TX/RX") #if self.DEBUG: # print " TX Path use daughterboard: %s" % (self.subdev.side_and_name()) # Set center frequency of USRP """ Set the center frequency we're interested in. Tuning is a two step process. First we ask the front-end to tune as close to the desired frequency as it can. Then we use the result of that operation and our target_frequency to determine the value for the digital up converter. """ assert(self.freq != None) #r = self.u.tune(self.subdev.which(), self.subdev, self.freq) r = self.u.set_center_freq(self.freq, 0) if self.DEBUG: if r: print " Tx Frequency: %s" %(eng_notation.num_to_str(self.freq)) else: print "----Failed to set Tx frequency to %s" % (eng_notation.num_to_str(self.freq),) raise ValueError # Set the USRP Tx PGA gain, (Note that on the RFX cards this is a nop.) # subdev.set_gain(subdev.gain_range()[1]) # set max Tx gain #g = self.subdev.gain_range() g = self.u.get_gain_range(0) #_tx_usrp_gain_range = g[1]-g[0] _tx_usrp_gain_range = g #_tx_usrp_gain = g[0] + _tx_usrp_gain_range * self.tx_usrp_pga_gain_scaling #_tx_usrp_gain = g + _tx_usrp_gain_range * self.tx_usrp_pga_gain_scaling #self.subdev.set_gain(_tx_usrp_gain) #self.u.set_gain(_tx_usrp_gain, 0) self.u.set_gain(10, 0) #if self.DEBUG: # print " USRP Tx PGA Gain Range: min = %g, max = %g, step size = %g" \ # %(g[0], g[1], g[2]) # print " USRP Tx PGA gain set to: %g" %(_tx_usrp_gain) # Set the transmit amplitude sent to the USRP (param: ampl 0 <= ampl < 16384.) """ Convert tx_power(mW) in waveform.xml to amplitude in gnu radio """ ampl= 1638.3*pow(self.tx_power, 0.5) self.tx_amplitude = max(0.0, min(ampl, 16383.0)) if self.DEBUG: print "tx amplitude:", self.tx_amplitude #gr digital amplifier self.tx_amplitude = 1.0 self.gr_amp = gr.multiply_const_cc (int(self.tx_amplitude)) # software amplifier (scaler) print "GR amp= ", int(self.tx_amplitude) if self.DEBUG: print " Tx power acquired from waveform configuration XML file is: %f between (0, 100.0mW)" %(self.tx_power) print " Tx Path initial software signal amplitude to USRP: %f / 16383.0" %(ampl) print " Tx Path actual software signal amplitude to USRP: %f / 16383.0" %(self.tx_amplitude) ################## Choose the corresponding analog modem ################### if self.DEBUG: print "----Tx path modulation: %s" % (self.tx_mod_type) chan_filter_coeffs_fixed = ( 0.000457763671875, 0.000946044921875, 0.00067138671875, 0.001068115234375, 0.00091552734375, 0.0008544921875, 0.000518798828125, 0.0001220703125, -0.000396728515625, -0.0008544921875, -0.00128173828125, -0.00146484375, -0.001434326171875, -0.0010986328125, -0.000518798828125, 0.000274658203125, 0.001129150390625, 0.00189208984375, 0.00238037109375, 0.00250244140625, 0.002166748046875, 0.0013427734375, 0.000152587890625, -0.001220703125, -0.002532958984375, -0.0035400390625, -0.003997802734375, -0.003753662109375, -0.002777099609375, -0.0010986328125, 0.000946044921875, 0.00311279296875, 0.00494384765625, 0.00604248046875, 0.006103515625, 0.005035400390625, 0.00286865234375, -0.0001220703125, -0.00347900390625, -0.006561279296875, -0.008758544921875, -0.00958251953125, -0.008636474609375, -0.005950927734375, -0.001739501953125, 0.00335693359375, 0.00848388671875, 0.0126953125, 0.01507568359375, 0.014862060546875, 0.01171875, 0.00579833984375, -0.002227783203125, -0.01123046875, -0.0196533203125, -0.02587890625, -0.028228759765625, -0.025421142578125, -0.016754150390625, -0.002166748046875, 0.017608642578125, 0.041015625, 0.0660400390625, 0.090240478515625, 0.111083984375, 0.12640380859375, 0.134490966796875, 0.134490966796875, 0.12640380859375, 0.111083984375, 0.090240478515625, 0.0660400390625, 0.041015625, 0.017608642578125, -0.002166748046875, -0.016754150390625, -0.025421142578125, -0.028228759765625, -0.02587890625, -0.0196533203125, -0.01123046875, -0.002227783203125, 0.00579833984375, 0.01171875, 0.014862060546875, 0.01507568359375, 0.0126953125, 0.00848388671875, 0.00335693359375, -0.001739501953125, -0.005950927734375, -0.008636474609375, -0.00958251953125, -0.008758544921875, -0.006561279296875, -0.00347900390625, -0.0001220703125, 0.00286865234375, 0.005035400390625, 0.006103515625, 0.00604248046875, 0.00494384765625, 0.00311279296875, 0.000946044921875, -0.0010986328125, -0.002777099609375, -0.003753662109375, -0.003997802734375, -0.0035400390625, -0.002532958984375, -0.001220703125, 0.000152587890625, 0.0013427734375, 0.002166748046875, 0.00250244140625, 0.00238037109375, 0.00189208984375, 0.001129150390625, 0.000274658203125, -0.000518798828125, -0.0010986328125, -0.001434326171875, -0.00146484375, -0.00128173828125, -0.0008544921875, -0.000396728515625, 0.0001220703125, 0.000518798828125, 0.0008544921875, 0.00091552734375, 0.001068115234375, 0.00067138671875, 0.000946044921875, 0.000457763671875) #chan_filter = gr.interp_fir_filter_ccf(self._gr_interp, chan_filter_coeffs_fixed) #chan_filter_dsp = gr.dsp_fir_ccf (chan_filter_coeffs_fixed, 14, self._gr_interp, 0, 0, 0, 1) #r = gr.enable_realtime_scheduling () if self.DEBUG: print "interpolation rate = ", self._gr_interp # FM modulator k = 2 * math.pi * self.tx_freq_deviation / self.gr_rate modulator = gr.frequency_modulator_fc(k) # Pre-emphasis for FM modulation """ tau is preemphasis time constant, inverse proportional to channel bandwidth """ chan_bw = 2.0*(self.tx_base_band_bw + \ self.tx_freq_deviation)# Carson's rule of FM channel bandwidth tau = 1/(chan_bw * 0.5) if self.DEBUG: print " channel bandwidth: ", chan_bw print " tau: ", tau preemph = fm_preemph (self.gr_rate, tau) # audio_coeffs = ( # 0.00058729130373770002, # 0.0016584444738215582, # 0.0015819269921330031, # 0.0014607862142637573, # 0.00020681278261230754, #-0.0013001097961560814, #-0.00249802658603143, #-0.0024276134129972843, #-0.00083069749014258953, # 0.0017562878158492619, # 0.003963761120687582, # 0.0043075911442784871, # 0.0020710872871114866, #-0.0020172640629268932, #-0.005882026963765212, #-0.0070692053073845166, #-0.0041954626649490937, # 0.0019311082705710714, # 0.0082980827342646387, # 0.011045923787287403, # 0.0076530405054369872, #-0.0012102332109476402, #-0.011372099802214802, #-0.016910189774436514, #-0.013347352799620162, #-0.00068013535845177706, # 0.015578754320259895, # 0.026379517186832846, # 0.023618496101893545, # 0.0051085800414948012, #-0.022608534445133374, #-0.045529642916534545, #-0.047580556152787695, #-0.018048092177406189, # 0.042354392363985506, # 0.11988807809069109, # 0.19189052073753335, # 0.2351677633079737, # 0.2351677633079737, # 0.19189052073753335, # 0.11988807809069109, # 0.042354392363985506, #-0.018048092177406189, #-0.047580556152787695, #-0.045529642916534545, #-0.022608534445133374, # 0.0051085800414948012, # 0.023618496101893545, # 0.026379517186832846, # 0.015578754320259895, #-0.00068013535845177706, #-0.013347352799620162, #-0.016910189774436514, #-0.011372099802214802, #-0.0012102332109476402, # 0.0076530405054369872, # 0.011045923787287403, # 0.0082980827342646387, # 0.0019311082705710714, #-0.0041954626649490937, #-0.0070692053073845166, #-0.005882026963765212, #-0.0020172640629268932, # 0.0020710872871114866, # 0.0043075911442784871, # 0.003963761120687582, # 0.0017562878158492619, #-0.00083069749014258953, #-0.0024276134129972843, #-0.00249802658603143, #-0.0013001097961560814, # 0.00020681278261230754, # 0.0014607862142637573, # 0.0015819269921330031, # 0.0016584444738215582, # 0.00058729130373770002) audio_coeffs = ( -0.021392822265625, -0.0194091796875, 0.02972412109375, -0.018341064453125, -0.025299072265625, 0.07745361328125, -0.08251953125, -0.033905029296875, 0.56634521484375, 0.56634521484375, -0.033905029296875, -0.08251953125, 0.07745361328125, -0.025299072265625, -0.018341064453125, 0.02972412109375, -0.0194091796875, -0.021392822265625) #audio_coeffs = ( # -0.21392822265625, # -0.194091796875, # 0.2972412109375, # -0.18341064453125, # -0.25299072265625, # 0.7745361328125, # -0.8251953125, # -0.33905029296875, # 5.6634521484375, # 5.6634521484375, # -0.33905029296875, # -0.8251953125, # 0.7745361328125, # -0.25299072265625, # -0.18341064453125, # 0.2972412109375, # -0.194091796875, # -0.21392822265625) self.audio_filter = gr.interp_fir_filter_fff(self._gr_interp, audio_coeffs) #Source audio Low-pass Filter #self.audio_throt = gr.multiply_const_ff(50) self.audio_throt = gr.multiply_const_ff(5) if self.DEBUG: print "audio decim FIR filter tap length:", len(audio_coeffs) # Setup audio source src = audio.source(int(self.audio_rate), audio_input) # Wiring up #self.connect(src, self.audio_throt, interpolator, preemph, modulator, chan_filter_dsp, self.gr_amp, self.u) self.connect(src, self.audio_throt, self.audio_filter, modulator, self.gr_amp, self.u)
def __init__(self, options, parent): ''' See below for what options should hold ''' gr.hier_block2.__init__(self, "transmit_path", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature options = copy.copy(options) # make a copy so we can destructively modify self._bitrate = options.bitrate # desired bit rate #self._inter = options.inter # Decimating rate for the USRP (prelim) self._samples_per_symbol = options.samples_per_symbol # desired samples/symbol self._down_sample_rate = options.down_sample_rate self._verbose = options.verbose self._tx_amplitude = options.tx_amplitude # digital amplitude sent to USRP self._use_whitener_offset = options.use_whitener_offset # increment start of whitener XOR data self._access_code = packet_utils.conv_packed_binary_string_to_1_0_string(default_ola_spade_code) self._subchannel = options.subchannel self._msgq_limit = 4 self.parent = parent # Turn it into NRZ data. self.nrz = gr.bytes_to_syms() self.sqwave = (1,) * self._samples_per_symbol # rectangular window self.gaussian_filter = gr.interp_fir_filter_fff(self._samples_per_symbol, self.sqwave) #Sensitivity will be seletected by set_sensitivity function in main loop self.sensitivity_a = (2 *pi * self._subchannel) / self._samples_per_symbol # phase change per bit = pi / 2 (for BFSK) self.sensitivity_b = (2 *pi * (self._subchannel)) / self._samples_per_symbol # phase change per bit = pi / 2 (for BFSK) self._pad_for_usrp = True self._use_whitener_offset = False self._whitener_offset = 0 # TODO # BUG : Improve or Implement Stream Selector!!!! (Check the new GNU Radio blocks!!!) # ============================================================================= # The first flowgraph for Digital Only Modulation # ============================================================================= self._pkt_input = gr.message_source(gr.sizeof_char, self._msgq_limit) # accepts messages from the outside world self.fmmod = gtlib.bfsk_modulator_fc(self.sensitivity_a,self.sensitivity_b) # BFSK modulation self.amp = gr.multiply_const_cc(1) # (Note that on the RFX cards this is a nop.) self.amp_2 = gr.multiply_const_cc(1) # (Sub channel correction) if self._subchannel >= 1 and self._subchannel <= 4: self.amp_2.set_k(pow(1.2,(float(self._subchannel)-1))) #self.timetag_inserter = gtlib.usrp_timetag_insert() if self._verbose: self._print_verbage() # Display some information about the setup # ============================================================================= # Flowgraph connection # ============================================================================= self.connect(self._pkt_input, self.nrz, self.gaussian_filter,self.fmmod,self.amp, self.amp_2, self) self.set_tx_amplitude(self._tx_amplitude)
def __init__(self, samples_per_symbol=_def_samples_per_symbol, sensitivity=_def_sensitivity, bt=_def_bt, verbose=_def_verbose, log=_def_log): """ Hierarchical block for Gaussian Frequency Shift Key (GFSK) 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 bt: Gaussian filter bandwidth * symbol time @type bt: float @param verbose: Print information about modulator? @type verbose: bool @param debug: Print modualtion data to files? @type debug: bool """ gr.hier_block2.__init__(self, "gfsk_mod", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature samples_per_symbol = int(samples_per_symbol) self._samples_per_symbol = samples_per_symbol self._bt = bt self._differential = False if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol,)) ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once #sensitivity = (pi / 2) / samples_per_symbol # phase change per bit = pi / 2 # Turn it into NRZ data. self.nrz = gr.bytes_to_syms() # Form Gaussian filter # Generate Gaussian response (Needs to be convolved with window below). self.gaussian_taps = gr.firdes.gaussian( 1.0, # gain samples_per_symbol, # symbol_rate bt, # bandwidth * symbol time ntaps # number of taps ) self.sqwave = (1,) * samples_per_symbol # rectangular window self.taps = numpy.convolve(numpy.array(self.gaussian_taps),numpy.array(self.sqwave)) self.gaussian_filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) # FM modulation self.fmmod = gr.frequency_modulator_fc(sensitivity) # small amount of output attenuation to prevent clipping USRP sink self.amp = gr.multiply_const_cc(0.999) if verbose: self._print_verbage() if log: self._setup_logging() # Connect & Initialize base class self.connect(self, self.nrz, self.gaussian_filter, self.fmmod, self.amp, self)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 320000 ################################################## # Blocks ################################################## self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.GetWin(), title="Scope Plot", sample_rate=samp_rate, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_0.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_f( self.GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.hilbert_fc_0 = filter.hilbert_fc(64) self.high_pass_filter_0 = gr.interp_fir_filter_fff(1, firdes.high_pass( 1, samp_rate, 15000, 10, firdes.WIN_HAMMING, 6.76)) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float*1, samp_rate) self.blocks_multiply_xx_1_0 = blocks.multiply_vff(1) self.blocks_multiply_xx_1 = blocks.multiply_vcc(1) self.blocks_multiply_xx_0 = blocks.multiply_vff(1) self.blocks_complex_to_real_0 = blocks.complex_to_real(1) self.blocks_add_xx_0 = blocks.add_vff(1) self.analog_sig_source_x_0_0_2 = analog.sig_source_c(samp_rate, analog.GR_SIN_WAVE, 20000, 1, 0) self.analog_sig_source_x_0_0_1 = analog.sig_source_f(samp_rate, analog.GR_COS_WAVE, 20000, 1, 0) self.analog_sig_source_x_0_0 = analog.sig_source_f(samp_rate, analog.GR_COS_WAVE, 20000, 1, 0) self.analog_sig_source_x_0 = analog.sig_source_f(samp_rate, analog.GR_COS_WAVE, 1000, 1, 0) ################################################## # Connections ################################################## self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.analog_sig_source_x_0_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.blocks_multiply_xx_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.high_pass_filter_0, 0)) self.connect((self.high_pass_filter_0, 0), (self.hilbert_fc_0, 0)) self.connect((self.hilbert_fc_0, 0), (self.blocks_multiply_xx_1, 0)) self.connect((self.analog_sig_source_x_0_0_2, 0), (self.blocks_multiply_xx_1, 1)) self.connect((self.high_pass_filter_0, 0), (self.blocks_multiply_xx_1_0, 1)) self.connect((self.analog_sig_source_x_0_0_1, 0), (self.blocks_multiply_xx_1_0, 0)) self.connect((self.blocks_multiply_xx_1, 0), (self.blocks_complex_to_real_0, 0)) self.connect((self.blocks_multiply_xx_1_0, 0), (self.blocks_add_xx_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.blocks_add_xx_0, 1)) self.connect((self.blocks_add_xx_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.blocks_add_xx_0, 0), (self.wxgui_scopesink2_0, 0))
def run_test(seed, blocksize): tb = gr.top_block() ################################################## # Variables ################################################## M = 2 K = 1 P = 2 h = (1.0 * K) / P L = 3 Q = 4 frac = 0.99 f = trellis.fsm(P, M, L) # CPFSK signals #p = numpy.ones(Q)/(2.0) #q = numpy.cumsum(p)/(1.0*Q) # GMSK signals BT = 0.3 tt = numpy.arange(0, L * Q) / (1.0 * Q) - L / 2.0 #print tt p = (0.5 * scipy.stats.erfc(2 * math.pi * BT * (tt - 0.5) / math.sqrt( math.log(2.0)) / math.sqrt(2.0)) - 0.5 * scipy.stats.erfc( 2 * math.pi * BT * (tt + 0.5) / math.sqrt(math.log(2.0)) / math.sqrt(2.0))) / 2.0 p = p / sum(p) * Q / 2.0 #print p q = numpy.cumsum(p) / Q q = q / q[-1] / 2.0 #print q (f0T, SS, S, F, Sf, Ff, N) = fsm_utils.make_cpm_signals(K, P, M, L, q, frac) #print N #print Ff Ffa = numpy.insert(Ff, Q, numpy.zeros(N), axis=0) #print Ffa MF = numpy.fliplr(numpy.transpose(Ffa)) #print MF E = numpy.sum(numpy.abs(Sf)**2, axis=0) Es = numpy.sum(E) / f.O() #print Es constellation = numpy.reshape(numpy.transpose(Sf), N * f.O()) #print Ff #print Sf #print constellation #print numpy.max(numpy.abs(SS - numpy.dot(Ff , Sf))) EsN0_db = 10.0 N0 = Es * 10.0**(-(1.0 * EsN0_db) / 10.0) #N0 = 0.0 #print N0 head = 4 tail = 4 numpy.random.seed(seed * 666) data = numpy.random.randint(0, M, head + blocksize + tail + 1) #data = numpy.zeros(blocksize+1+head+tail,'int') for i in range(head): data[i] = 0 for i in range(tail + 1): data[-i] = 0 ################################################## # Blocks ################################################## random_source_x_0 = gr.vector_source_b(data.tolist(), False) gr_chunks_to_symbols_xx_0 = gr.chunks_to_symbols_bf((-1, 1), 1) gr_interp_fir_filter_xxx_0 = gr.interp_fir_filter_fff(Q, p) gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(2 * math.pi * h * (1.0 / Q)) gr_add_vxx_0 = gr.add_vcc(1) gr_noise_source_x_0 = gr.noise_source_c(gr.GR_GAUSSIAN, (N0 / 2.0)**0.5, -long(seed)) gr_multiply_vxx_0 = gr.multiply_vcc(1) gr_sig_source_x_0 = gr.sig_source_c(Q, gr.GR_COS_WAVE, -f0T, 1, 0) # only works for N=2, do it manually for N>2... gr_fir_filter_xxx_0_0 = gr.fir_filter_ccc(Q, MF[0].conjugate()) gr_fir_filter_xxx_0_0_0 = gr.fir_filter_ccc(Q, MF[1].conjugate()) gr_streams_to_stream_0 = gr.streams_to_stream(gr.sizeof_gr_complex * 1, int(N)) gr_skiphead_0 = gr.skiphead(gr.sizeof_gr_complex * 1, int(N * (1 + 0))) viterbi = trellis.viterbi_combined_cb(f, head + blocksize + tail, 0, -1, int(N), constellation, digital.TRELLIS_EUCLIDEAN) gr_vector_sink_x_0 = gr.vector_sink_b() ################################################## # Connections ################################################## tb.connect((random_source_x_0, 0), (gr_chunks_to_symbols_xx_0, 0)) tb.connect((gr_chunks_to_symbols_xx_0, 0), (gr_interp_fir_filter_xxx_0, 0)) tb.connect((gr_interp_fir_filter_xxx_0, 0), (gr_frequency_modulator_fc_0, 0)) tb.connect((gr_frequency_modulator_fc_0, 0), (gr_add_vxx_0, 0)) tb.connect((gr_noise_source_x_0, 0), (gr_add_vxx_0, 1)) tb.connect((gr_add_vxx_0, 0), (gr_multiply_vxx_0, 0)) tb.connect((gr_sig_source_x_0, 0), (gr_multiply_vxx_0, 1)) tb.connect((gr_multiply_vxx_0, 0), (gr_fir_filter_xxx_0_0, 0)) tb.connect((gr_multiply_vxx_0, 0), (gr_fir_filter_xxx_0_0_0, 0)) tb.connect((gr_fir_filter_xxx_0_0, 0), (gr_streams_to_stream_0, 0)) tb.connect((gr_fir_filter_xxx_0_0_0, 0), (gr_streams_to_stream_0, 1)) tb.connect((gr_streams_to_stream_0, 0), (gr_skiphead_0, 0)) tb.connect((gr_skiphead_0, 0), (viterbi, 0)) tb.connect((viterbi, 0), (gr_vector_sink_x_0, 0)) tb.run() dataest = gr_vector_sink_x_0.data() #print data #print numpy.array(dataest) perr = 0 err = 0 for i in range(blocksize): if data[head + i] != dataest[head + i]: #print i err += 1 if err != 0: perr = 1 return (err, perr)
def __init__(self, samples_per_symbol=_def_samples_per_symbol, bits_per_symbol=_def_bits_per_symbol, h_numerator=_def_h_numerator, h_denominator=_def_h_denominator, cpm_type=_def_cpm_type, bt=_def_bt, symbols_per_pulse=_def_symbols_per_pulse, generic_taps=_def_generic_taps, verbose=_def_verbose, log=_def_log): """ Hierarchical block for Continuous Phase modulation. The input is a byte stream (unsigned char) representing packed bits and the output is the complex modulated signal at baseband. See Proakis for definition of generic CPM signals: s(t)=exp(j phi(t)) phi(t)= 2 pi h int_0^t f(t') dt' f(t)=sum_k a_k g(t-kT) (normalizing assumption: int_0^infty g(t) dt = 1/2) @param samples_per_symbol: samples per baud >= 2 @type samples_per_symbol: integer @param bits_per_symbol: bits per symbol @type bits_per_symbol: integer @param h_numerator: numerator of modulation index @type h_numerator: integer @param h_denominator: denominator of modulation index (numerator and denominator must be relative primes) @type h_denominator: integer @param cpm_type: supported types are: 0=CPFSK, 1=GMSK, 2=RC, 3=GENERAL @type cpm_type: integer @param bt: bandwidth symbol time product for GMSK @type bt: float @param symbols_per_pulse: shaping pulse duration in symbols @type symbols_per_pulse: integer @param generic_taps: define a generic CPM pulse shape (sum = samples_per_symbol/2) @type generic_taps: array of floats @param verbose: Print information about modulator? @type verbose: bool @param debug: Print modulation data to files? @type debug: bool """ gr.hier_block2.__init__( "cpm_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._bits_per_symbol = bits_per_symbol self._h_numerator = h_numerator self._h_denominator = h_denominator self._cpm_type = cpm_type self._bt = bt if cpm_type == 0 or cpm_type == 2 or cpm_type == 3: # CPFSK, RC, Generic self._symbols_per_pulse = symbols_per_pulse elif cpm_type == 1: # GMSK self._symbols_per_pulse = 4 else: raise TypeError, ( "cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type, )) self._generic_taps = numpy.array(generic_taps) if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: raise TypeError, ( "samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol, )) self.nsymbols = 2**bits_per_symbol self.sym_alphabet = numpy.arange(-(self.nsymbols - 1), self.nsymbols, 2) self.ntaps = self._symbols_per_pulse * samples_per_symbol sensitivity = 2 * pi * h_numerator / h_denominator / samples_per_symbol # Unpack Bytes into bits_per_symbol groups self.B2s = gr.packed_to_unpacked_bb(bits_per_symbol, gr.GR_MSB_FIRST) # Turn it into symmetric PAM data. self.pam = gr.chunks_to_symbols_bf(self.sym_alphabet, 1) # Generate pulse (sum of taps = samples_per_symbol/2) if cpm_type == 0: # CPFSK self.taps = (1.0 / self._symbols_per_pulse / 2, ) * self.ntaps elif cpm_type == 1: # GMSK gaussian_taps = gr.firdes.gaussian( 1.0 / 2, # gain samples_per_symbol, # symbol_rate bt, # bandwidth * symbol time self.ntaps # number of taps ) sqwave = (1, ) * samples_per_symbol # rectangular window self.taps = numpy.convolve(numpy.array(gaussian_taps), numpy.array(sqwave)) elif cpm_type == 2: # Raised Cosine # generalize it for arbitrary roll-off factor self.taps = (1 - numpy.cos( 2 * pi * numpy.arange(0, self.ntaps) / samples_per_symbol / self._symbols_per_pulse)) / (2 * self._symbols_per_pulse) elif cpm_type == 3: # Generic CPM self.taps = generic_taps else: raise TypeError, ( "cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type, )) self.filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) # FM modulation self.fmmod = gr.frequency_modulator_fc(sensitivity) if verbose: self._print_verbage() if log: self._setup_logging() # Connect self.connect(self, self.B2s, self.pam, self.filter, self.fmmod, self)
alle.append([0,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,1,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,0,0,1,1,0,1,1,1,0,1,0,0,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0]) alle.append([0,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,1,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,0,1,1,0]) alle.append([0,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,0,1,1,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,0,1,1,0,0,0,1,0,1,1,0,0,0,1,1,0,0,1,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,0,1,1,0,1,1,0,1]) src = ais.ais_source_f(alle[0], 500, True) dst = gr.vector_sink_f() slice = gr.binary_slicer_fb() diffdec = gr.diff_decoder_bb(2) invert = ais.invert10_bb() dst2 = gr.vector_sink_b() gaussian_taps = gr.firdes.gaussian(1,5,0.35,100) sqwave = (1,) * 5 taps = numpy.convolve(numpy.array(gaussian_taps),numpy.array(sqwave)) gaussian_filter = gr.interp_fir_filter_fff(5,taps) gange = gr.multiply_const_ff(0.3) lydut = audio.sink(9600*5,"default") filut = gr.file_sink(gr.sizeof_float,"filut.raw") #fg.connect(src,dst) #fg.connect(src,slice,diffdec,invert,dst2) fg.connect(src,gaussian_filter,gange,lydut) #fg.connect(gange,filut) fg.start() for i in alle: time.sleep(0.5) src.nypakke(i)
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) parser = OptionParser (option_class=eng_option) parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, help="select USRP Tx side A or B") parser.add_option("-f", "--freq", type="eng_float", default=107.2e6, help="set Tx frequency to FREQ [required]", metavar="FREQ") parser.add_option("--wavfile", type="string", default="", help="read input from FILE") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.usrp_interp = 200 self.u = usrp.sink_c (0, self.usrp_interp) print "USRP Serial: ", self.u.serial_number() self.dac_rate = self.u.dac_rate() # 128 MS/s self.usrp_rate = self.dac_rate / self.usrp_interp # 640 kS/s self.sw_interp = 5 self.audio_rate = self.usrp_rate / self.sw_interp # 128 kS/s # determine the daughterboard subdevice we're using if options.tx_subdev_spec is None: options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u) self.u.set_mux(usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec)) self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec) print "Using d'board: ", self.subdev.side_and_name() # set max Tx gain, tune frequency and enable transmitter self.subdev.set_gain(self.subdev.gain_range()[1]) if self.u.tune(self.subdev.which(), self.subdev, options.freq): print "Tuned to", options.freq/1e6, "MHz" else: sys.exit(1) self.subdev.set_enable(True) # open wav file containing floats in the [-1, 1] range, repeat if options.wavfile is None: print "Please provide a wavfile to transmit! Exiting\n" sys.exit(1) self.src = gr.wavfile_source (options.wavfile, True) nchans = self.src.channels() sample_rate = self.src.sample_rate() bits_per_sample = self.src.bits_per_sample() print nchans, "channels,", sample_rate, "kS/s,", bits_per_sample, "bits/sample" # resample to 128kS/s if sample_rate == 44100: self.resample_left = blks2.rational_resampler_fff(32,11) self.resample_right = blks2.rational_resampler_fff(32,11) elif sample_rate == 48000: self.resample_left == blks2.rational_resampler_fff(8,3) self.resample_right == blks2.rational_resampler_fff(8,3) elif sample_rate == 8000: self.resample_left == blks2.rational_resampler_fff(16,1) self.resample_right == blks2.rational_resampler_fff(16,1) else: print sample_rate, "is an unsupported sample rate" sys.exit(1) self.connect ((self.src, 0), self.resample_left) self.connect ((self.src, 1), self.resample_right) # create L+R (mono) and L-R (stereo) self.audio_lpr = gr.add_ff() self.audio_lmr = gr.sub_ff() self.connect (self.resample_left, (self.audio_lpr, 0)) self.connect (self.resample_left, (self.audio_lmr, 0)) self.connect (self.resample_right, (self.audio_lpr, 1)) self.connect (self.resample_right, (self.audio_lmr, 1)) # low-pass filter for L+R audio_lpr_taps = gr.firdes.low_pass (0.3, # gain self.audio_rate, # sampling rate 15e3, # passband cutoff 2e3, # transition width gr.firdes.WIN_HANN) self.audio_lpr_filter = gr.fir_filter_fff (1, audio_lpr_taps) self.connect (self.audio_lpr, self.audio_lpr_filter) # create pilot tone at 19 kHz self.pilot = gr.sig_source_f(self.audio_rate, # sampling freq gr.GR_SIN_WAVE, # waveform 19e3, # frequency 3e-2) # amplitude # create the L-R signal carrier at 38 kHz, high-pass to remove 0Hz tone self.stereo_carrier = gr.multiply_ff() self.connect (self.pilot, (self.stereo_carrier, 0)) self.connect (self.pilot, (self.stereo_carrier, 1)) stereo_carrier_taps = gr.firdes.high_pass (1, # gain self.audio_rate, # sampling rate 1e4, # cutoff freq 2e3, # transition width gr.firdes.WIN_HANN) self.stereo_carrier_filter = gr.fir_filter_fff(1, stereo_carrier_taps) self.connect (self.stereo_carrier, self.stereo_carrier_filter) # upconvert L-R to 23-53 kHz and band-pass self.mix_stereo = gr.multiply_ff() audio_lmr_taps = gr.firdes.band_pass (3e3, # gain self.audio_rate, # sampling rate 23e3, # low cutoff 53e3, # high cuttof 2e3, # transition width gr.firdes.WIN_HANN) self.audio_lmr_filter = gr.fir_filter_fff (1, audio_lmr_taps) self.connect (self.audio_lmr, (self.mix_stereo, 0)) self.connect (self.stereo_carrier_filter, (self.mix_stereo, 1)) self.connect (self.mix_stereo, self.audio_lmr_filter) # mix L+R, pilot and L-R self.mixer = gr.add_ff() self.connect (self.audio_lpr_filter, (self.mixer, 0)) self.connect (self.pilot, (self.mixer, 1)) self.connect (self.audio_lmr_filter, (self.mixer, 2)) # interpolation & pre-emphasis interp_taps = gr.firdes.low_pass (self.sw_interp, # gain self.audio_rate, # Fs 60e3, # cutoff freq 5e3, # transition width gr.firdes.WIN_HAMMING) self.interpolator = gr.interp_fir_filter_fff (self.sw_interp, interp_taps) self.pre_emph = blks2.fm_preemph(self.usrp_rate, tau=50e-6) self.connect (self.mixer, self.interpolator, self.pre_emph) # fm modulation, gain & TX max_dev = 100e3 k = 2 * math.pi * max_dev / self.usrp_rate # modulator sensitivity self.modulator = gr.frequency_modulator_fc (k) self.gain = gr.multiply_const_cc (1e3) self.connect (self.pre_emph, self.modulator, self.gain, self.u) # plot an FFT to verify we are sending what we want pre_mod = fftsink2.fft_sink_f(panel, title="Before Interpolation", fft_size=512, sample_rate=self.audio_rate, y_per_div=20, ref_level=20) self.connect (self.mixer, pre_mod) vbox.Add (pre_mod.win, 1, wx.EXPAND)
def __init__(self, fg, samples_per_symbol=_def_samples_per_symbol, bt=_def_bt, verbose=_def_verbose, log=_def_log): """ Hierarchical block for Gaussian Minimum Shift Key (GMSK) modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. @param fg: flow graph @type fg: flow graph @param samples_per_symbol: samples per baud >= 2 @type samples_per_symbol: integer @param bt: Gaussian filter bandwidth * symbol time @type bt: float @param verbose: Print information about modulator? @type verbose: bool @param debug: Print modualtion data to files? @type debug: bool """ self._fg = fg self._samples_per_symbol = samples_per_symbol self._bt = bt if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol,)) ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once sensitivity = (pi / 2) / samples_per_symbol # phase change per bit = pi / 2 # Turn it into NRZ data. self.nrz = gr.bytes_to_syms() # Form Gaussian filter # Generate Gaussian response (Needs to be convolved with window below). self.gaussian_taps = gr.firdes.gaussian( 1, # gain samples_per_symbol, # symbol_rate bt, # bandwidth * symbol time ntaps # number of taps ) self.sqwave = (1,) * samples_per_symbol # rectangular window self.taps = numpy.convolve(numpy.array(self.gaussian_taps),numpy.array(self.sqwave)) self.gaussian_filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) # FM modulation self.fmmod = gr.frequency_modulator_fc(sensitivity) if verbose: self._print_verbage() if log: self._setup_logging() # Connect & Initialize base class self._fg.connect(self.nrz, self.gaussian_filter, self.fmmod) gr.hier_block.__init__(self, self._fg, self.nrz, self.fmmod)
def run_test(seed,blocksize): tb = gr.top_block() ################################################## # Variables ################################################## M = 2 K = 1 P = 2 h = (1.0*K)/P L = 3 Q = 4 frac = 0.99 f = trellis.fsm(P,M,L) # CPFSK signals #p = numpy.ones(Q)/(2.0) #q = numpy.cumsum(p)/(1.0*Q) # GMSK signals BT=0.3; tt=numpy.arange(0,L*Q)/(1.0*Q)-L/2.0; #print tt p=(0.5*scipy.stats.erfc(2*math.pi*BT*(tt-0.5)/math.sqrt(math.log(2.0))/math.sqrt(2.0))-0.5*scipy.stats.erfc(2*math.pi*BT*(tt+0.5)/math.sqrt(math.log(2.0))/math.sqrt(2.0)))/2.0; p=p/sum(p)*Q/2.0; #print p q=numpy.cumsum(p)/Q; q=q/q[-1]/2.0; #print q (f0T,SS,S,F,Sf,Ff,N) = fsm_utils.make_cpm_signals(K,P,M,L,q,frac) #print N #print Ff Ffa = numpy.insert(Ff,Q,numpy.zeros(N),axis=0) #print Ffa MF = numpy.fliplr(numpy.transpose(Ffa)) #print MF E = numpy.sum(numpy.abs(Sf)**2,axis=0) Es = numpy.sum(E)/f.O() #print Es constellation = numpy.reshape(numpy.transpose(Sf),N*f.O()) #print Ff #print Sf #print constellation #print numpy.max(numpy.abs(SS - numpy.dot(Ff , Sf))) EsN0_db = 10.0 N0 = Es * 10.0**(-(1.0*EsN0_db)/10.0) #N0 = 0.0 #print N0 head = 4 tail = 4 numpy.random.seed(seed*666) data = numpy.random.randint(0, M, head+blocksize+tail+1) #data = numpy.zeros(blocksize+1+head+tail,'int') for i in range(head): data[i]=0 for i in range(tail+1): data[-i]=0 ################################################## # Blocks ################################################## random_source_x_0 = gr.vector_source_b(data, False) gr_chunks_to_symbols_xx_0 = gr.chunks_to_symbols_bf((-1, 1), 1) gr_interp_fir_filter_xxx_0 = gr.interp_fir_filter_fff(Q, p) gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(2*math.pi*h*(1.0/Q)) gr_add_vxx_0 = gr.add_vcc(1) gr_noise_source_x_0 = gr.noise_source_c(gr.GR_GAUSSIAN, (N0/2.0)**0.5, -long(seed)) gr_multiply_vxx_0 = gr.multiply_vcc(1) gr_sig_source_x_0 = gr.sig_source_c(Q, gr.GR_COS_WAVE, -f0T, 1, 0) # only works for N=2, do it manually for N>2... gr_fir_filter_xxx_0_0 = gr.fir_filter_ccc(Q, MF[0].conjugate()) gr_fir_filter_xxx_0_0_0 = gr.fir_filter_ccc(Q, MF[1].conjugate()) gr_streams_to_stream_0 = gr.streams_to_stream(gr.sizeof_gr_complex*1, N) gr_skiphead_0 = gr.skiphead(gr.sizeof_gr_complex*1, N*(1+0)) viterbi = trellis.viterbi_combined_cb(f, head+blocksize+tail, 0, -1, N, constellation, trellis.TRELLIS_EUCLIDEAN) gr_vector_sink_x_0 = gr.vector_sink_b() ################################################## # Connections ################################################## tb.connect((random_source_x_0, 0), (gr_chunks_to_symbols_xx_0, 0)) tb.connect((gr_chunks_to_symbols_xx_0, 0), (gr_interp_fir_filter_xxx_0, 0)) tb.connect((gr_interp_fir_filter_xxx_0, 0), (gr_frequency_modulator_fc_0, 0)) tb.connect((gr_frequency_modulator_fc_0, 0), (gr_add_vxx_0, 0)) tb.connect((gr_noise_source_x_0, 0), (gr_add_vxx_0, 1)) tb.connect((gr_add_vxx_0, 0), (gr_multiply_vxx_0, 0)) tb.connect((gr_sig_source_x_0, 0), (gr_multiply_vxx_0, 1)) tb.connect((gr_multiply_vxx_0, 0), (gr_fir_filter_xxx_0_0, 0)) tb.connect((gr_multiply_vxx_0, 0), (gr_fir_filter_xxx_0_0_0, 0)) tb.connect((gr_fir_filter_xxx_0_0, 0), (gr_streams_to_stream_0, 0)) tb.connect((gr_fir_filter_xxx_0_0_0, 0), (gr_streams_to_stream_0, 1)) tb.connect((gr_streams_to_stream_0, 0), (gr_skiphead_0, 0)) tb.connect((gr_skiphead_0, 0), (viterbi, 0)) tb.connect((viterbi, 0), (gr_vector_sink_x_0, 0)) tb.run() dataest = gr_vector_sink_x_0.data() #print data #print numpy.array(dataest) perr = 0 err = 0 for i in range(blocksize): if data[head+i] != dataest[head+i]: #print i err += 1 if err != 0 : perr = 1 return (err,perr)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") ################################################## # Variables ################################################## self.variable_chooser_0 = variable_chooser_0 = 1 self.transition_width = transition_width = 10000 self.sym_per_sec = sym_per_sec = 2032 self.samp_rate = samp_rate = 2000000 self.rf_gain = rf_gain = 10 self.cutoff_freq = cutoff_freq = 10000 ################################################## # Blocks ################################################## _transition_width_sizer = wx.BoxSizer(wx.VERTICAL) self._transition_width_text_box = forms.text_box( parent=self.GetWin(), sizer=_transition_width_sizer, value=self.transition_width, callback=self.set_transition_width, label='transition_width', converter=forms.float_converter(), proportion=0, ) self._transition_width_slider = forms.slider( parent=self.GetWin(), sizer=_transition_width_sizer, value=self.transition_width, callback=self.set_transition_width, minimum=100, maximum=100000, num_steps=1000, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_transition_width_sizer) _rf_gain_sizer = wx.BoxSizer(wx.VERTICAL) self._rf_gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_rf_gain_sizer, value=self.rf_gain, callback=self.set_rf_gain, label='rf_gain', converter=forms.int_converter(), proportion=0, ) self._rf_gain_slider = forms.slider( parent=self.GetWin(), sizer=_rf_gain_sizer, value=self.rf_gain, callback=self.set_rf_gain, minimum=0, maximum=47, num_steps=47, style=wx.SL_HORIZONTAL, cast=int, proportion=1, ) self.Add(_rf_gain_sizer) _cutoff_freq_sizer = wx.BoxSizer(wx.VERTICAL) self._cutoff_freq_text_box = forms.text_box( parent=self.GetWin(), sizer=_cutoff_freq_sizer, value=self.cutoff_freq, callback=self.set_cutoff_freq, label='cutoff_freq', converter=forms.int_converter(), proportion=0, ) self._cutoff_freq_slider = forms.slider( parent=self.GetWin(), sizer=_cutoff_freq_sizer, value=self.cutoff_freq, callback=self.set_cutoff_freq, minimum=100, maximum=100000, num_steps=1000, style=wx.SL_HORIZONTAL, cast=int, proportion=1, ) self.Add(_cutoff_freq_sizer) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.GetWin(), title="Scope Plot", sample_rate=samp_rate, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_0.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self._variable_chooser_0_chooser = forms.drop_down( parent=self.GetWin(), value=self.variable_chooser_0, callback=self.set_variable_chooser_0, label='variable_chooser_0', choices=[1, 2, 3], labels=["a", "b", "c"], ) self.Add(self._variable_chooser_0_chooser) self.osmosdr_sink_c_0 = osmosdr.sink_c( args="numchan=" + str(1) + " " + "" ) self.osmosdr_sink_c_0.set_sample_rate(samp_rate) self.osmosdr_sink_c_0.set_center_freq(27.14e6, 0) self.osmosdr_sink_c_0.set_freq_corr(0, 0) self.osmosdr_sink_c_0.set_gain(10, 0) self.osmosdr_sink_c_0.set_if_gain(rf_gain, 0) self.osmosdr_sink_c_0.set_bb_gain(20, 0) self.osmosdr_sink_c_0.set_antenna("", 0) self.osmosdr_sink_c_0.set_bandwidth(0, 0) self.low_pass_filter_0 = gr.interp_fir_filter_fff(1, firdes.low_pass( 1, samp_rate, cutoff_freq, transition_width, firdes.WIN_BLACKMAN, 6.76)) self.const_source_x_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 0) self.blocks_vector_source_x_0 = blocks.vector_source_f([1,1,1,0, 1,1,1,0, 1,1,1,0, 1,1,1,0, 1,0, 1,0, 1,0, 1,0, 1,0, 1,0, 1,0, 1,0, 1,0, 1,0], True, 1, []) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float*1, samp_rate) self.blocks_repeat_0 = blocks.repeat(gr.sizeof_float*1, samp_rate/sym_per_sec) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) ################################################## # Connections ################################################## self.connect((self.blocks_vector_source_x_0, 0), (self.blocks_repeat_0, 0)) self.connect((self.blocks_repeat_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.const_source_x_0, 0), (self.blocks_float_to_complex_0, 1)) self.connect((self.low_pass_filter_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.osmosdr_sink_c_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.wxgui_fftsink2_0, 0))
def __init__(self, output_sample_rate=_def_output_sample_rate, excess_bw=_def_excess_bw, reverse=_def_reverse, verbose=_def_verbose, log=_def_log): """ Hierarchical block for RRC-filtered P25 FM modulation. The input is a dibit (P25 symbol) stream (char, not packed) and the output is the float "C4FM" signal at baseband, suitable for application to an FM modulator stage Input is at the base symbol rate (4800), output sample rate is typically either 32000 (USRP TX chain) or 48000 (sound card) @param output_sample_rate: output sample rate @type output_sample_rate: integer @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float @param reverse: reverse polarity flag @type reverse: bool @param verbose: Print information about modulator? @type verbose: bool @param debug: Print modulation data to files? @type debug: bool """ gr.hier_block2.__init__(self, "p25_c4fm_mod_bf", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature input_sample_rate = 4800 # P25 baseband symbol rate lcm = gru.lcm(input_sample_rate, output_sample_rate) self._interp_factor = int(lcm // input_sample_rate) self._decimation = int(lcm // output_sample_rate) self._excess_bw = excess_bw mod_map = [1.0/3.0, 1.0, -(1.0/3.0), -1.0] self.C2S = gr.chunks_to_symbols_bf(mod_map) if reverse: self.polarity = gr.multiply_const_ff(-1) else: self.polarity = gr.multiply_const_ff( 1) ntaps = 11 * self._interp_factor rrc_taps = gr.firdes.root_raised_cosine( self._interp_factor, # gain (since we're interpolating by sps) lcm, # sampling rate input_sample_rate, # symbol rate self._excess_bw, # excess bandwidth (roll-off factor) ntaps) # rrc_coeffs work slightly differently: each input sample # (from mod_map above) at 4800 rate, then 9 zeros are inserted # to bring to 48000 rate, then this filter is applied: # rrc_filter = gr.fir_filter_fff(1, rrc_coeffs) # FIXME: how to insert the 9 zero samples using gr ? # rrc_coeffs = [0, -0.003, -0.006, -0.009, -0.012, -0.014, -0.014, -0.013, -0.01, -0.006, 0, 0.007, 0.014, 0.02, 0.026, 0.029, 0.029, 0.027, 0.021, 0.012, 0, -0.013, -0.027, -0.039, -0.049, -0.054, -0.055, -0.049, -0.038, -0.021, 0, 0.024, 0.048, 0.071, 0.088, 0.098, 0.099, 0.09, 0.07, 0.039, 0, -0.045, -0.091, -0.134, -0.17, -0.193, -0.199, -0.184, -0.147, -0.085, 0, 0.105, 0.227, 0.36, 0.496, 0.629, 0.751, 0.854, 0.933, 0.983, 1, 0.983, 0.933, 0.854, 0.751, 0.629, 0.496, 0.36, 0.227, 0.105, 0, -0.085, -0.147, -0.184, -0.199, -0.193, -0.17, -0.134, -0.091, -0.045, 0, 0.039, 0.07, 0.09, 0.099, 0.098, 0.088, 0.071, 0.048, 0.024, 0, -0.021, -0.038, -0.049, -0.055, -0.054, -0.049, -0.039, -0.027, -0.013, 0, 0.012, 0.021, 0.027, 0.029, 0.029, 0.026, 0.02, 0.014, 0.007, 0, -0.006, -0.01, -0.013, -0.014, -0.014, -0.012, -0.009, -0.006, -0.003, 0] self.rrc_filter = gr.interp_fir_filter_fff(self._interp_factor, rrc_taps) # FM pre-emphasis filter shaping_coeffs = [-0.018, 0.0347, 0.0164, -0.0064, -0.0344, -0.0522, -0.0398, 0.0099, 0.0798, 0.1311, 0.121, 0.0322, -0.113, -0.2499, -0.3007, -0.2137, -0.0043, 0.2825, 0.514, 0.604, 0.514, 0.2825, -0.0043, -0.2137, -0.3007, -0.2499, -0.113, 0.0322, 0.121, 0.1311, 0.0798, 0.0099, -0.0398, -0.0522, -0.0344, -0.0064, 0.0164, 0.0347, -0.018] self.shaping_filter = gr.fir_filter_fff(1, shaping_coeffs) if verbose: self._print_verbage() if log: self._setup_logging() self.connect(self, self.C2S, self.polarity, self.rrc_filter, self.shaping_filter) if (self._decimation > 1): self.decimator = blks2.rational_resampler_fff(1, self._decimation) self.connect(self.shaping_filter, self.decimator, self) else: self.connect(self.shaping_filter, self)