def __init__(self, sample_rate, offset, deviation, decimation, symbol_rate): super(fsk_demodulator, self).__init__( "fsk_demodulator", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signature(1, 1, gr.sizeof_float*1), ) symbol_taps_length = int(floor(float(sample_rate) / symbol_rate)) symbol_taps = (1,) * symbol_taps_length self.symbol_filter_h = filter.freq_xlating_fir_filter_ccf(1, (symbol_taps), offset + deviation, sample_rate) self.symbol_filter_l = filter.freq_xlating_fir_filter_ccf(1, (symbol_taps), offset - deviation, sample_rate) self.mag_h = blocks.complex_to_mag(1) self.mag_l = blocks.complex_to_mag(1) self.sub = blocks.sub_ff(1) output_filter_cutoff = symbol_rate * 0.75 output_filter_transition = symbol_rate * 0.25 output_filter_attenuation = 40 output_filter_taps = firdes.low_pass_2(1.0, sample_rate, output_filter_cutoff, output_filter_transition, output_filter_attenuation) self.output_filter = filter.fir_filter_fff(decimation, (output_filter_taps)) self.connect((self, 0), (self.symbol_filter_h, 0)) self.connect((self, 0), (self.symbol_filter_l, 0)) self.connect((self.symbol_filter_h, 0), (self.mag_h, 0)) self.connect((self.symbol_filter_l, 0), (self.mag_l, 0)) self.connect((self.mag_h, 0), (self.sub, 0)) self.connect((self.mag_l, 0), (self.sub, 1)) self.connect((self.sub, 0), (self.output_filter, 0)) self.connect((self.output_filter, 0), (self, 0))
def test_fir_filter_ccf_001(self): self.generate_ccf_source() expected_data = ((0.001697700354270637+0.004312471952289343j), (0.003520616563037038-0.003014103975147009j), (0.004252811893820763-0.008337559178471565j), (0.0030743128154426813-0.010262271389365196j), (0.0007344777695834637-0.007861139252781868j), (-0.0011067686136811972-0.0028924935031682253j), (-0.002371778478845954+0.0019914964213967323j), (-0.003023319412022829+0.005717850290238857j), (-0.0021738125942647457+0.007211698684841394j), (-0.0004628606839105487+0.005501383915543556j), (0.0007428556564264+0.0019867848604917526j), (0.001634795218706131-0.0013514887541532516j), (0.002205110155045986-0.00402155052870512j), (0.0015480631263926625-0.005179159343242645j), (0.00026722141774371266-0.003887997241690755j), (-0.0004911854630336165-0.0013578246580436826j), (-0.0011226939968764782+0.0009080552263185382j), (-0.0016229727771133184+0.0028335191309452057j), (-0.0010890064295381308+0.0037298379465937614j), (-0.00012392725329846144+0.0027196139562875032j)) src = blocks.vector_source_c(self.src_data) op = filter.freq_xlating_fir_filter_ccf(1, self.taps, self.fc, self.fs) dst = blocks.vector_sink_c() self.tb.connect(src, op, dst) self.tb.run() result_data = dst.data() self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
def test_fir_filter_ccf_002(self): self.generate_ccf_source() expected_data = ((6.419439159799367e-05-0.0006292851758189499j), (-0.00037074743886478245+0.0013245552545413375j), (0.0006853155209682882-0.0023769831750541925j), (-0.001427714480087161+0.002608160488307476j), (0.0015907397028058767-0.000811046629678458j), (-0.0004226673918310553-0.0024389736354351044j), (-0.0013841050677001476+0.006231029983609915j), (0.0035029184073209763-0.009738259017467499j), (-0.005924836732447147+0.010320881381630898j), (0.006831614300608635-0.003950652200728655j), (-0.0021247887052595615-0.015604906715452671j), (-0.04283163696527481+0.09995654970407486j), (-0.01391829177737236+0.07924056798219681j), (0.010886997915804386-0.02463012933731079j), (-0.0056075905449688435+0.004998659715056419j), (0.0016976913902908564+0.004312459379434586j), (0.0007344821933656931-0.007861112244427204j), (-0.002173811662942171+0.007211671676486731j), (0.0022051059640944004-0.00402153329923749j), (-0.0011226903880015016+0.0009080505697056651j)) src = blocks.vector_source_c(self.src_data) op = filter.freq_xlating_fir_filter_ccf(4, self.taps, self.fc, self.fs) dst = blocks.vector_sink_c() self.tb.connect(src, op, dst) self.tb.run() result_data = dst.data() self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
def test_fir_filter_ccf_001(self): self.generate_ccf_source() expected_data = ((0.001697700354270637 + 0.004312471952289343j), (0.003520616563037038 - 0.003014103975147009j), (0.004252811893820763 - 0.008337559178471565j), (0.0030743128154426813 - 0.010262271389365196j), (0.0007344777695834637 - 0.007861139252781868j), (-0.0011067686136811972 - 0.0028924935031682253j), (-0.002371778478845954 + 0.0019914964213967323j), (-0.003023319412022829 + 0.005717850290238857j), (-0.0021738125942647457 + 0.007211698684841394j), (-0.0004628606839105487 + 0.005501383915543556j), (0.0007428556564264 + 0.0019867848604917526j), (0.001634795218706131 - 0.0013514887541532516j), (0.002205110155045986 - 0.00402155052870512j), (0.0015480631263926625 - 0.005179159343242645j), (0.00026722141774371266 - 0.003887997241690755j), (-0.0004911854630336165 - 0.0013578246580436826j), (-0.0011226939968764782 + 0.0009080552263185382j), (-0.0016229727771133184 + 0.0028335191309452057j), (-0.0010890064295381308 + 0.0037298379465937614j), (-0.00012392725329846144 + 0.0027196139562875032j)) src = blocks.vector_source_c(self.src_data) op = filter.freq_xlating_fir_filter_ccf(1, self.taps, self.fc, self.fs) dst = blocks.vector_sink_c() self.tb.connect(src, op, dst) self.tb.run() result_data = dst.data() self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
def __init__(self, freq, rate, designator): gr.hier_block2.__init__(self, "ais_rx", gr.io_signature(1,1,gr.sizeof_gr_complex), gr.io_signature(0,0,0)) self._bits_per_sec = 9600.0 self._samples_per_symbol = 5 self.coeffs = filter.firdes.low_pass(1, rate, 11000, 1000) self._filter_decimation = int(rate/(self._bits_per_sec*self._samples_per_symbol)) self.filter = filter.freq_xlating_fir_filter_ccf(self._filter_decimation, self.coeffs, freq, rate) # self.resamp = pfb.arb_resampler_ccf((self._bits_per_sec*self._samples_per_symbol)/int(rate/self._filter_decimation)) options = {} options[ "samples_per_symbol" ] = (rate/self._filter_decimation)/self._bits_per_sec options[ "clockrec_gain" ] = 0.04 options[ "omega_relative_limit" ] = 0.01 options[ "bits_per_sec" ] = self._bits_per_sec options[ "fftlen" ] = 1024 #trades off accuracy of freq estimation in presence of noise, vs. delay time. options[ "samp_rate" ] = self._bits_per_sec * self._samples_per_symbol self.demod = ais.ais_demod(options) #ais_demod takes in complex baseband and spits out 1-bit unpacked bitstream self.deframer = digital.hdlc_deframer_bp(11,64) #takes bytes, deframes, unstuffs, CRCs, and emits PDUs with frame contents self.nmea = ais.pdu_to_nmea(designator) #turns data PDUs into NMEA sentences # self.msgq = ais.pdu_to_msgq(queue) #posts PDUs to message queue for main program to parse at will # self.parse = ais.parse(queue, designator) #ais_parse.cc, calculates CRC, parses data into NMEA AIVDM message, moves data onto queue self.connect(self, self.filter, self.demod, self.deframer) self.msg_connect(self.deframer, "out", self.nmea, "print")
def test_fir_filter_ccf_002(self): self.generate_ccf_source() expected_data = ((6.419439159799367e-05 - 0.0006292851758189499j), (-0.00037074743886478245 + 0.0013245552545413375j), (0.0006853155209682882 - 0.0023769831750541925j), (-0.001427714480087161 + 0.002608160488307476j), (0.0015907397028058767 - 0.000811046629678458j), (-0.0004226673918310553 - 0.0024389736354351044j), (-0.0013841050677001476 + 0.006231029983609915j), (0.0035029184073209763 - 0.009738259017467499j), (-0.005924836732447147 + 0.010320881381630898j), (0.006831614300608635 - 0.003950652200728655j), (-0.0021247887052595615 - 0.015604906715452671j), (-0.04283163696527481 + 0.09995654970407486j), (-0.01391829177737236 + 0.07924056798219681j), (0.010886997915804386 - 0.02463012933731079j), (-0.0056075905449688435 + 0.004998659715056419j), (0.0016976913902908564 + 0.004312459379434586j), (0.0007344821933656931 - 0.007861112244427204j), (-0.002173811662942171 + 0.007211671676486731j), (0.0022051059640944004 - 0.00402153329923749j), (-0.0011226903880015016 + 0.0009080505697056651j)) src = blocks.vector_source_c(self.src_data) op = filter.freq_xlating_fir_filter_ccf(4, self.taps, self.fc, self.fs) dst = blocks.vector_sink_c() self.tb.connect(src, op, dst) self.tb.run() result_data = dst.data() self.assertComplexTuplesAlmostEqual(expected_data, result_data[-20:], 5)
def BuildXlate(self,scope=True,tscope=True): self.f2c = blocks.float_to_complex() taps = filter.firdes.low_pass ( 1.0, rate, 2000, 750, filter.firdes.WIN_HAMMING ) self.xlate = filter.freq_xlating_fir_filter_ccf ( 12, taps, 10000, rate ) self.connect( self,self.f2c, self.xlate, self ) self.connect( (self,1), (self.f2c,1) ) if scope: self.scope = qtgui.sink_c(1024, filter.firdes.WIN_BLACKMAN_hARRIS, fc=0, bw=rate/12, name="FFT%d" % self.i, plotfreq=True, plotwaterfall=True, plottime=True, plotconst=True) self.connect( self.xlate, self.scope ) # Get the reference pointer to the SpectrumDisplayForm QWidget self.pyobj = sip.wrapinstance(self.scope.pyqwidget(), QtGui.QWidget) self.pyobj.show() if tscope: self.tscope = qtgui.sink_c(1024, filter.firdes.WIN_BLACKMAN_hARRIS, fc=0, bw=rate, name="Top FFT%d" % self.i, plotfreq=True, plotwaterfall=True, plottime=False, plotconst=False) self.connect(self.f2c,self.tscope) self.tpyobj = sip.wrapinstance(self.tscope.pyqwidget(), QtGui.QWidget) self.tpyobj.show()
def __init__(self, sample_rate, freq_offset, queue, logger = None, group_description_csv = None): gr.hier_block2.__init__( self, "SmartZone Control Channel", gr.io_signature(1, 1, gr.sizeof_gr_complex), # input signature gr.io_signature(0, 0, 0) # output signature ) self._CC_DEVIATION = 4e3 # observed self._symbol_rate = 3600.0 # control channel rate is 3.6kb/s self._oversample = 4 # XXX reduce # get close to the desired sample rate with decimation channel_decimation = int(sample_rate / (self._oversample * self._symbol_rate)) & ~1 channel_rate = sample_rate / channel_decimation samples_per_symbol = channel_rate / self._symbol_rate # channel_bw = self._CC_DEVIATION + self._symbol_rate # from pager source channel_bw = 3 * self._symbol_rate # taps = firdes.low_pass(1, sample_rate, int(3.0 * self._symbol_rate), int(3.0 * self._symbol_rate / 10.0), firdes.WIN_HAMMING) channel_taps = firdes.low_pass(1, sample_rate, channel_bw, channel_bw / 10.0, firdes.WIN_HAMMING) channel_filter = filter.freq_xlating_fir_filter_ccf(channel_decimation, channel_taps, freq_offset, sample_rate) #quad_demod = analog.quadrature_demod_cf(1.0) quad_demod = analog.quadrature_demod_cf(channel_rate / (2 * math.pi * self._CC_DEVIATION)) clock = digital.clock_recovery_mm_ff(omega = samples_per_symbol, gain_omega = 0.001, mu = 0, gain_mu = 0.001, omega_relative_limit = 0.005) slicer = digital.binary_slicer_fb() digital_correlate = digital.correlate_access_code_bb("10101100", 0) cc_sink = control_channel_sink(logger, queue, group_description_csv) self.connect(self, channel_filter, quad_demod, clock, slicer, digital_correlate, cc_sink)
def ais_rx(self, src, freq, designator, options, queue): self.rate = options.rate self.u = src self.coeffs = firdes.low_pass(1,self.rate,7000,1000) self._filter_decimation = 4 self.filter = filter.freq_xlating_fir_filter_ccf(self._filter_decimation, self.coeffs, freq, self.rate) self._bits_per_sec = 9600.0; self._samples_per_symbol = self.rate / self._filter_decimation / self._bits_per_sec options.samples_per_symbol = self._samples_per_symbol options.gain_mu = 0.3 options.mu=0.5 options.omega_relative_limit = 0.0001 options.bits_per_sec = self._bits_per_sec #trades off accuracy of freq estimation in presence of noise, vs. delay time. options.fftlen = 4096 options.samp_rate = self.rate / self._filter_decimation #ais_demod.py, hierarchical demodulation block, takes in complex baseband and spits out 1-bit packed bitstream self.demod = ais_demod(options) self.unstuff = unstuff() #ais_unstuff.cc, unstuffs data #should mark start of packet self.start_correlator = digital.correlate_access_code_tag_bb("1010101010101010", 0, "ais_preamble") #should mark start and end of packet self.stop_correlator = digital.correlate_access_code_tag_bb("01111110", 0, "ais_frame") #ais_parse.cc, calculates CRC, parses data into ASCII message, moves data onto queue self.parse = parse(queue, designator, options.verbose, options.lon, options.lat) self.connect(self.u, self.filter, self.demod, self.unstuff, self.start_correlator, self.stop_correlator, self.parse)
def __init__(self, options, queue): gr.top_block.__init__(self, "rtl_flex_noX") self.options = options self.offset = 0.0 self.adj_time = time.time() self.verbose = options.verbose self.log = options.log # Set up rtl source self.u = osmosdr.source(args="%s" % (options.device)) # set Freq self.u.set_center_freq(options.freq + options.calibration, 0) # Grab 250 KHz of spectrum self.u.set_sample_rate(250e3) rate = self.u.get_sample_rate() if rate != 250e3: print "Unable to set required sample rate of 250 Ksps (got %f)" % rate sys.exit(1) # Set gain if options.rx_gain is None: grange = self.u.get_gain_range() options.rx_gain = float(grange.start() + grange.stop()) / 2.0 print "\nNo gain specified." print "Setting gain to %f (from [%f, %f])" % (options.rx_gain, grange.start(), grange.stop()) self.u.set_gain(options.rx_gain, 0) taps = optfir.low_pass(1.0, 250e3, 11000, 12500, 0.1, 60) self.chan = filter.freq_xlating_fir_filter_ccf(10, taps, 0.0, 250e3) self.flex = pager.flex_demod(queue, options.freq, options.verbose, options.log) self.connect(self.u, self.chan, self.flex)
def _set_filter(self): filter_cutoff = 145e3 filter_t_width = 10e3 offset = 0 filter_taps = filter.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, filter.firdes.WIN_HAMMING) filtr = filter.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) return filtr
def _set_filter(self): filter_cutoff = 145e3 filter_t_width = 10e3 offset = 0 # print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width filter_taps = filter.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) filtr = filter.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) return filtr
def __init__(self, options): gr.top_block.__init__(self) # Create a USRP2 source and set decimation rate self._u = usrp2.source_32fc(options.interface, options.mac_addr) self._u.set_decim(512) # Set receive daughterboard gain if options.gain is None: g = self._u.gain_range() options.gain = float(g[0] + g[1]) / 2 print "Using mid-point gain of", options.gain, "(", g[0], "-", g[ 1], ")" self._u.set_gain(options.gain) # Set receive frequency if options.lo_offset is not None: self._u.set_lo_offset(options.lo_offset) tr = self._u.set_center_freq(options.freq) if tr == None: sys.stderr.write('Failed to set center frequency\n') raise SystemExit, 1 sample_rate = 100e6 / 512 symbol_rate = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps channel_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" % (sample_rate)) DEMOD = cqpsk.cqpsk_demod(samples_per_symbol=sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_resampler_cc(0, r) self.connect(self._u, FILTER, INTERPOLATOR, DEMOD, OUT)
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel options = get_options() sample_rate = int(options.sample_rate) self.asrc = audio.source(sample_rate, options.audio_device, True) self.f2c = blocks.float_to_complex(1) self.connect((self.asrc, 1), (self.f2c, 1)) self.connect((self.asrc, 0), (self.f2c, 0)) symbol_rate = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps channel_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" %(sample_rate)) DEMOD = cqpsk.cqpsk_demod( samples_per_symbol = sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_interpolator_cc(0, r) self.connect(self.f2c, FILTER, INTERPOLATOR, DEMOD, OUT) self.scope = fftsink2.fft_sink_c(panel, fft_size=512, sample_rate=sample_rate, ref_scale=2.0, ref_level=-30, y_divs=10, fft_rate=10, average=True, avg_alpha=0.2) self.connect(self.f2c, self.scope)
def __init__(self, options): gr.top_block.__init__(self) # Create a USRP2 source and set decimation rate self._u = usrp2.source_32fc(options.interface, options.mac_addr) self._u.set_decim(512) # Set receive daughterboard gain if options.gain is None: g = self._u.gain_range() options.gain = float(g[0]+g[1])/2 print "Using mid-point gain of", options.gain, "(", g[0], "-", g[1], ")" self._u.set_gain(options.gain) # Set receive frequency if options.lo_offset is not None: self._u.set_lo_offset(options.lo_offset) tr = self._u.set_center_freq(options.freq) if tr == None: sys.stderr.write('Failed to set center frequency\n') raise SystemExit, 1 sample_rate = 100e6/512 symbol_rate = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps channel_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" %(sample_rate)) DEMOD = cqpsk.cqpsk_demod( samples_per_symbol = sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_resampler_cc(0, r) self.connect(self._u, FILTER, INTERPOLATOR, DEMOD, OUT)
def __init__(self, sample_rate, offset, deviation, decimation, symbol_rate): super(fsk_demodulator, self).__init__( "fsk_demodulator", gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_float * 1), ) symbol_taps_length = int(floor(float(sample_rate) / symbol_rate)) symbol_taps = (1, ) * symbol_taps_length self.symbol_filter_h = filter.freq_xlating_fir_filter_ccf( 1, (symbol_taps), offset + deviation, sample_rate) self.symbol_filter_l = filter.freq_xlating_fir_filter_ccf( 1, (symbol_taps), offset - deviation, sample_rate) self.mag_h = blocks.complex_to_mag(1) self.mag_l = blocks.complex_to_mag(1) self.sub = blocks.sub_ff(1) output_filter_cutoff = symbol_rate * 0.75 output_filter_transition = symbol_rate * 0.25 output_filter_attenuation = 40 output_filter_taps = firdes.low_pass_2(1.0, sample_rate, output_filter_cutoff, output_filter_transition, output_filter_attenuation) self.output_filter = filter.fir_filter_fff(decimation, (output_filter_taps)) self.connect((self, 0), (self.symbol_filter_h, 0)) self.connect((self, 0), (self.symbol_filter_l, 0)) self.connect((self.symbol_filter_h, 0), (self.mag_h, 0)) self.connect((self.symbol_filter_l, 0), (self.mag_l, 0)) self.connect((self.mag_h, 0), (self.sub, 0)) self.connect((self.mag_l, 0), (self.sub, 1)) self.connect((self.sub, 0), (self.output_filter, 0)) self.connect((self.output_filter, 0), (self, 0))
def __init__(self, samp_rate): gr.hier_block2.__init__(self, 'phase_offset_corrector', gr.io_signature(2, 2, gr.sizeof_gr_complex), gr.io_signature(2, 2, gr.sizeof_gr_complex)) ## the overlapping parts of the spectra are processed at a lower sampling rate decim = 5 delta_f = float(samp_rate) / 4.0 self._taps = taps = filter.firdes.low_pass(1, samp_rate, 0.05 * samp_rate, 0.02 * samp_rate) self._xlplus = filter.freq_xlating_fir_filter_ccf( decim, (taps), +delta_f, samp_rate) self._xlminus = filter.freq_xlating_fir_filter_ccf( decim, (taps), -delta_f, samp_rate) self._mult_ccA = blocks.multiply_conjugate_cc(1) self._mult_ccB = blocks.multiply_conjugate_cc(1) vlen = int(np.power(2, np.ceil(np.log2(0.1 * samp_rate / decim)))) self._s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, vlen) self._v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, vlen * decim) ## phase offsets depend on the combination of resampling and pfb_synth filter self._pB = phase_estimator(vlen, decim, np.exp( 2j * np.pi * 0.5)) ## phase 1 for num_streams==4, 0.5 for num_streams==6 ## output = conj([conj(#0) * #1]) * #1 self.connect((self, 0), (self._xlplus), (self._mult_ccA, 1)) self.connect((self, 1), (self._xlminus), (self._mult_ccA, 0)) self.connect((self._mult_ccA), (self._s2v), (self._pB), (self._v2s), (self._mult_ccB, 1)) self.connect((self, 1), (self._mult_ccB, 0)) self.connect((self._mult_ccB), (self, 0)) ## phase offsets self.connect((self._v2s), (self, 1))
def __init__(self): gr.top_block.__init__(self) options = get_options() self.tune_corrector_callback = tune_corrector(self) self.synchronizer_callback = synchronizer(self) self.converter = blocks.vector_to_stream(gr.sizeof_float, 142) self.ifreq = options.frequency self.rfgain = options.gain self.src = osmosdr.source(options.args) self.src.set_center_freq(self.ifreq) self.src.set_sample_rate(int(options.sample_rate)) if self.rfgain is None: self.src.set_gain_mode(1) self.iagc = 1 self.rfgain = 0 else: self.iagc = 0 self.src.set_gain_mode(0) self.src.set_gain(self.rfgain) # may differ from the requested rate sample_rate = self.src.get_sample_rate() sys.stderr.write("sample rate: %d\n" % (sample_rate)) gsm_symb_rate = 1625000.0 / 6.0 sps = sample_rate / gsm_symb_rate / 4 out_sample_rate = gsm_symb_rate * 4 self.offset = 0 taps = filter.firdes.low_pass(1.0, sample_rate, 145e3, 10e3, filter.firdes.WIN_HANN) self.tuner = filter.freq_xlating_fir_filter_ccf( 1, taps, self.offset, sample_rate) self.interpolator = filter.fractional_resampler_cc(0, sps) self.receiver = gsm.receiver_cf(self.tune_corrector_callback, self.synchronizer_callback, 4, options.key.replace(' ', '').lower(), options.configuration.upper()) self.output = blocks.file_sink(gr.sizeof_float, options.output_file) self.connect(self.src, self.tuner, self.interpolator, self.receiver, self.converter, self.output)
def __init__(self, options): gr.top_block.__init__(self) pubsub.__init__(self) self._options = options self._source = osmosdr.source(options.source) wat = self._source.get_sample_rates() rate = wat.stop() # Maximum available sample rate print "Using sample rate of %d" % rate self._source.set_sample_rate(rate) self._source.set_gain(34) self._source.set_center_freq(options.center_freq) channel_spacing = 25e3 channel_decimation = int(rate / channel_spacing) print "Using channel decimation of %d" % channel_decimation taps = firdes.low_pass(1.0, rate, channel_spacing*0.4, channel_spacing*0.1, firdes.WIN_HANN) #taps = optfir.low_pass(1.0, # rate, # 11000, # 12500, # 0.1, # 60) self._ctrl_chan = freq_xlating_fir_filter_ccf(channel_decimation, taps, options.ctrl_freq - options.center_freq, rate) data_sample_rate = float(rate) / channel_decimation print "Using data sample rate of %f" % data_sample_rate self._data_path = smartnet_all_rx(data_sample_rate) self.connect(self._source, self._ctrl_chan, self._data_path) if options.fft: pass
def test_fir_filter_ccf_002(self): self.generate_ccf_source() decim = 4 lo = sig_source_c(self.fs, -self.fc, 1, len(self.src_data)) despun = mix(lo, self.src_data) expected_data = fir_filter(despun, self.taps, decim) src = blocks.vector_source_c(self.src_data) op = filter.freq_xlating_fir_filter_ccf(decim, self.taps, self.fc, self.fs) dst = blocks.vector_sink_c() self.tb.connect(src, op, dst) self.tb.run() result_data = dst.data() self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
def graph (): print os.getpid() sampling_freq = 19200000 tb = gr.top_block () src0 = blocks.file_source(gr.sizeof_gr_complex,"/tmp/atsc_pipe_1") duc_coeffs = filter.firdes.low_pass( 1, 19.2e6, 9e6, 1e6, filter.firdes.WIN_HAMMING ) duc = filter.freq_xlating_fir_filter_ccf( 1, duc_coeffs, 5.75e6, 19.2e6 ) c2f = blocks.complex_to_float() file = blocks.file_sink(gr.sizeof_float,"/tmp/atsc_pipe_2") tb.connect( src0, duc, c2f, file ) tb.run()
def __init__(self, options): gr.top_block.__init__(self) sample_rate = int(options.sample_rate) self.asrc = audio.source(sample_rate, options.audio_device, True) self.f2c = blocks.float_to_complex(1) self.connect((self.asrc, 1), (self.f2c, 1)) self.connect((self.asrc, 0), (self.f2c, 0)) symbol_rate = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps channel_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" % (sample_rate)) DEMOD = cqpsk.cqpsk_demod(samples_per_symbol=sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_resampler_cc(0, r) self.connect(self.f2c, FILTER, INTERPOLATOR, DEMOD, OUT)
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-c", "--calibration", type="eng_float", default=0, help="freq offset") parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file") parser.add_option("-l", "--log", action="store_true", default=False, help="dump debug .dat files") parser.add_option("-L", "--low-pass", type="eng_float", default=25e3, help="low pass cut-off", metavar="Hz") parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file") parser.add_option("-s", "--sample-rate", type="int", default=100000000/512, help="input sample 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 = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps channel_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" %(sample_rate)) IN = blocks.file_source(gr.sizeof_gr_complex, options.input_file) DEMOD = cqpsk.cqpsk_demod( samples_per_symbol = sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_resampler_cc(0, r) self.connect(IN, FILTER, INTERPOLATOR, DEMOD, OUT)
def __init__(self, input_samp_rate, output_samp_rate): gr.hier_block2.__init__( self, "Am Block", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signature(1, 1, gr.sizeof_float*1), ) # Parameters self.input_samp_rate = input_samp_rate self.output_samp_rate = output_samp_rate self.internal_samp_rate = 50000 # Blocks self.xlating_fir_filter = filter.freq_xlating_fir_filter_ccf( int(input_samp_rate/self.internal_samp_rate), (filter.firdes.low_pass_2(1, input_samp_rate, 25e3, 10e3, 40)), 0, input_samp_rate) self.agc = analog.agc2_cc(1e-1, 1e-2, 1, 1) self.agc.set_max_gain(100) self.am_demodulator = analog.am_demod_cf( channel_rate=self.internal_samp_rate, audio_decim=1, audio_pass=5000, audio_stop=5500, ) self.rational_resampler = filter.rational_resampler_fff( interpolation=output_samp_rate, decimation=self.internal_samp_rate, taps=None, fractional_bw=None, ) # Connections self.connect( self, self.xlating_fir_filter, self.agc, self.am_demodulator, self.rational_resampler, self )
def __init__(self, options): gr.top_block.__init__(self) sample_rate = int(options.sample_rate) self.asrc = audio.source(sample_rate, options.audio_device, True) self.f2c = blocks.float_to_complex(1) self.connect((self.asrc, 1), (self.f2c, 1)) self.connect((self.asrc, 0), (self.f2c, 0)) symbol_rate = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps channel_taps = filter.firdes.low_pass( 1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN ) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" % (sample_rate)) DEMOD = cqpsk.cqpsk_demod( samples_per_symbol=sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose, ) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_resampler_cc(0, r) self.connect(self.f2c, FILTER, INTERPOLATOR, DEMOD, OUT)
def __init__(self, in_samp_rate, freq, offset, finetune, realtime): gr.hier_block2.__init__(self, "lora_receiver", # Min, Max, gr.sizeof_<type> gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(0, 0, 0)) # Output signature # Parameters self.finetune = finetune self.offset = offset self.in_samp_rate = in_samp_rate self.realtime = realtime bw = 125000 # Define blocks null1 = null_sink(gr.sizeof_float) null2 = null_sink(gr.sizeof_float) if realtime: self.c_decoder = lora.decoder(finetune) out_samp_rate = 1000000 decimation = 1 else: decoder = lora_decoder() out_samp_rate = 10000000 decimation = 10 lpf = firdes.low_pass(1, out_samp_rate, bw, 10000, firdes.WIN_HAMMING, 6.67) qdemod = quadrature_demod_cf(1.0) channelizer = freq_xlating_fir_filter_ccf(decimation, lpf, offset, out_samp_rate) resampler = fractional_resampler_cc(0, in_samp_rate / float(out_samp_rate)) # Connect blocks self.connect((self, 0), (resampler, 0)) self.connect((resampler, 0), (channelizer, 0)) if realtime: self.connect((channelizer, 0), (self.c_decoder, 0)) else: self.connect((channelizer, 0), (qdemod, 0)) self.connect((channelizer, 0), (decoder, 1)) self.connect((qdemod, 0), (decoder, 0)) self.connect((decoder, 0), (null1, 0)) self.connect((decoder, 1), (null2, 0))
def __init__(self, audio_input, input_rate, audio_output, output_rate, frequency=55000, ampl=1.0): gr.top_block.__init__(self) if ampl > 1.0: ampl = 1.0 to_real = blocks.complex_to_real() to_imag = blocks.complex_to_imag() float_to_complex = blocks.float_to_complex() src = audio.source (input_rate, audio_input) firdes_taps = filter.firdes.low_pass_2(1, 1, 0.2, 0.1, 60) self._converter = filter.freq_xlating_fir_filter_ccf ( 1, firdes_taps, 0, input_rate ) self._converter.set_center_freq(frequency) dst = audio.sink (output_rate, audio_output, True) #self.connect(src, converter, to_real, dst) self.connect((src, 1), (float_to_complex, 0)) self.connect((src, 0), (float_to_complex, 1)) self.connect(float_to_complex, self._converter) self.connect(self._converter, to_real, (dst,0)) self.connect(self._converter, to_imag, (dst,1))
def __init__(self, freq=0): gr.top_block.__init__(self, "Am") ################################################## # Parameters ################################################## self.freq = freq ################################################## # Variables ################################################## self.center_freq = center_freq = 133e6 ################################################## # Blocks ################################################## self.freq_xlating_fir_filter_xxx_0_0_0_0_0_0_0_0 = filter.freq_xlating_fir_filter_ccf( 800, (firdes.low_pass(1, 10e6, 10e6 / (2 * 800), 1000)), (freq * 1e3) - center_freq, 10e6) self.dc_blocker_xx_0_0_0_0_0_0_0_0 = filter.dc_blocker_ff(32, True) self.blocks_wavfile_sink_0_0_0_0_0_0_0_0 = blocks.wavfile_sink( "/tmp/" + str(freq) + ".wav", 1, int(12.5e3), 16) self.blocks_file_source_0 = blocks.file_source( gr.sizeof_gr_complex * 1, "/tmp/decompress.iq", False) self.blocks_complex_to_mag_0_0_0_0_0_0_0_0 = blocks.complex_to_mag(1) ################################################## # Connections ################################################## self.connect((self.blocks_complex_to_mag_0_0_0_0_0_0_0_0, 0), (self.dc_blocker_xx_0_0_0_0_0_0_0_0, 0)) self.connect((self.blocks_file_source_0, 0), (self.freq_xlating_fir_filter_xxx_0_0_0_0_0_0_0_0, 0)) self.connect((self.dc_blocker_xx_0_0_0_0_0_0_0_0, 0), (self.blocks_wavfile_sink_0_0_0_0_0_0_0_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0_0_0_0_0_0_0_0, 0), (self.blocks_complex_to_mag_0_0_0_0_0_0_0_0, 0))
def __init__(self, freq, rate, designator, queue, use_viterbi=False): gr.hier_block2.__init__(self, "ais_rx", gr.io_signature(1,1,gr.sizeof_gr_complex), gr.io_signature(0,0,0)) self.coeffs = filter.firdes.low_pass(1, rate, 7000, 1000) self._filter_decimation = 12 #fixed, TODO make settable via params or better yet do resampling self.filter = filter.freq_xlating_fir_filter_ccf(self._filter_decimation, self.coeffs, freq, rate) self._bits_per_sec = 9600.0 self._samples_per_symbol = rate / self._filter_decimation / self._bits_per_sec options = {} options[ "viterbi" ] = use_viterbi options[ "samples_per_symbol" ] = self._samples_per_symbol options[ "gain_mu" ] = 0.3 options[ "mu" ] = 0.5 options[ "omega_relative_limit" ] = 0.003 options[ "bits_per_sec" ] = self._bits_per_sec options[ "fftlen" ] = 4096 #trades off accuracy of freq estimation in presence of noise, vs. delay time. options[ "samp_rate" ] = rate / self._filter_decimation self.demod = ais.ais_demod(options) #ais_demod takes in complex baseband and spits out 1-bit packed bitstream self.unstuff = ais.unstuff() #undoes bit stuffing operation self.start_correlator = digital.correlate_access_code_tag_bb("1010101010101010", 0, "ais_preamble") #should mark start of packet self.stop_correlator = digital.correlate_access_code_tag_bb("01111110", 0, "ais_frame") #should mark start and end of packet self.parse = ais.parse(queue, designator) #ais_parse.cc, calculates CRC, parses data into NMEA AIVDM message, moves data onto queue self.connect(self, self.filter, self.demod, self.unstuff, self.start_correlator, self.stop_correlator, self.parse) #parse posts messages to the queue, which the main loop reads and prints
def __init__(self, FH_seq, start_chann_idx): gr.top_block.__init__(self, "Sequence Follower") ################################################## # Variables ################################################## self.sql_on = sql_on = 0 self.samp_rate = samp_rate = 32000 self.curr_chann_idx = start_chann_idx self.FH_seq = FH_seq ################################################## # Blocks ################################################## self.analog_pwr_squelch_xx_0 = analog.pwr_squelch_cc(-10, 1, 25, False) def _sql_on_probe(): while True: val = self.analog_pwr_squelch_xx_0.unmuted() try: self.set_sql_on(val) except AttributeError, e: pass time.sleep(1.0/(100)) _sql_on_thread = threading.Thread(target=_sql_on_probe) _sql_on_thread.daemon = True _sql_on_thread.start() self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccf(64, ( [0.0027054441161453724, 0.002875175094231963, 0.0033175654243677855, 0.004034834913909435, 0.005023509729653597, 0.006274390500038862, 0.007772639859467745, 0.009498009458184242, 0.011425167322158813, 0.013524158857762814, 0.015760963782668114, 0.01809815689921379, 0.020495640113949776, 0.02291143871843815, 0.025302572175860405, 0.027625905349850655, 0.02983906865119934, 0.03190131485462189, 0.03377437964081764, 0.035423289984464645, 0.03681709244847298, 0.03792952373623848, 0.038739532232284546, 0.03923177719116211, 0.039396900683641434, 0.03923177719116211, 0.038739532232284546, 0.03792952373623848, 0.03681709244847298, 0.035423289984464645, 0.03377437964081764, 0.03190131485462189, 0.02983906865119934, 0.027625905349850655, 0.025302572175860405, 0.02291143871843815, 0.020495640113949776, 0.01809815689921379, 0.015760963782668114, 0.013524158857762814, 0.011425167322158813, 0.009498009458184242, 0.007772639859467745, 0.006274390500038862, 0.005023509729653597, 0.004034834913909435, 0.0033175654243677855, 0.002875175094231963, 0.0027054441161453724]), 1000, samp_rate) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate) self.blocks_file_source_0 = blocks.file_source(gr.sizeof_gr_complex*1, "/home/hocheol/GRC/Sample/FHSS_Sig", True) self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_gr_complex*1, "/home/hocheol/GRC/Sample/FHSS_Demodulated.cfloat", False) self.blocks_file_sink_0.set_unbuffered(True) ################################################## # Connections ################################################## self.connect((self.blocks_file_source_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.analog_pwr_squelch_xx_0, 0)) self.connect((self.analog_pwr_squelch_xx_0, 0), (self.blocks_file_sink_0, 0))
def __init__(self, dev_type="UHD", dev_addr="", dip_conf="10101", socket="A", func="on", gain=33): gr.top_block.__init__(self) ################################################## # Parameters ################################################## self.dev_type = dev_type self.dev_addr = dev_addr self.dip_conf = dip_conf self.func = func self.socket = socket self.gain = gain ################################################## # Variables ################################################## self.samp_rate = samp_rate = 5e5 ################################################## # Blocks ################################################## #self.init_device() self.device = None self.build_signal() self.gr_vector_source_x_0 = blocks.vector_source_c(self.signal, False, 1) self.gr_repeat_0 = blocks.repeat(gr.sizeof_gr_complex * 1, 125) self.gr_freq_xlating_fir_filter_xxx_0 = gr_filter.freq_xlating_fir_filter_ccf(1, (1, ), -180e3, samp_rate) ################################################## # Connections ################################################## #self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.device, 0)) self.connect((self.gr_vector_source_x_0, 0), (self.gr_repeat_0, 0)) self.connect((self.gr_repeat_0, 0), (self.gr_freq_xlating_fir_filter_xxx_0, 0))
def __init__(self, options, queue): gr.top_block.__init__(self, "rtl_flex_noX") self.options = options self.offset = 0.0 self.adj_time = time.time() self.verbose = options.verbose self.log = options.log # Set up rtl source self.u = osmosdr.source(args="%s" % (options.device)) #set Freq self.u.set_center_freq(options.freq + options.calibration, 0) # Grab 250 KHz of spectrum self.u.set_sample_rate(250e3) rate = self.u.get_sample_rate() if rate != 250e3: print "Unable to set required sample rate of 250 Ksps (got %f)" % rate sys.exit(1) #Set gain if options.rx_gain is None: grange = self.u.get_gain_range() options.rx_gain = float(grange.start() + grange.stop()) / 2.0 print "\nNo gain specified." print "Setting gain to %f (from [%f, %f])" % \ (options.rx_gain, grange.start(), grange.stop()) self.u.set_gain(options.rx_gain, 0) taps = optfir.low_pass(1.0, 250e3, 11000, 12500, 0.1, 60) self.chan = filter.freq_xlating_fir_filter_ccf(10, taps, 0.0, 250e3) self.flex = pager.flex_demod(queue, options.freq, options.verbose, options.log) self.connect(self.u, self.chan, self.flex)
def graph (args): print os.getpid() nargs = len(args) if nargs == 2: infile = args[0] outfile = args[1] else: raise ValueError('usage: interp.py input_file output_file.ts\n') input_rate = 19.2e6 IF_freq = 5.75e6 tb = gr.top_block() # Read from input file srcf = blocks.file_source(gr.sizeof_short, infile) # Convert interleaved shorts (I,Q,I,Q) to complex is2c = blocks.interleaved_short_to_complex() # 1/2 as wide because we're designing lp filter symbol_rate = atsc.ATSC_SYMBOL_RATE/2. NTAPS = 279 tt = filter.firdes.root_raised_cosine (1.0, input_rate / 3, symbol_rate, .1152, NTAPS) rrc = filter.fir_filter_ccf(1, tt) # Interpolate Filter our 6MHz wide signal centered at 0 ilp_coeffs = filter.firdes.low_pass(1, input_rate, 3.2e6, .5e6, filter.firdes.WIN_HAMMING) ilp = filter.interp_fir_filter_ccf(3, ilp_coeffs) # Move the center frequency to 5.75MHz ( this wont be needed soon ) duc_coeffs = filter.firdes.low_pass ( 1, 19.2e6, 9e6, 1e6, filter.firdes.WIN_HAMMING ) duc = filter.freq_xlating_fir_filter_ccf ( 1, duc_coeffs, -5.75e6, 19.2e6 ) # fpll input is float c2f = blocks.complex_to_float() # Phase locked loop fpll = atsc.fpll() # Clean fpll output lp_coeffs2 = filter.firdes.low_pass (1.0, input_rate, 5.75e6, 120e3, filter.firdes.WIN_HAMMING); lp_filter = filter.fir_filter_fff (1, lp_coeffs2) # Remove pilot ( at DC now ) iir = filter.single_pole_iir_filter_ff(1e-5) remove_dc = blocks.sub_ff() # Bit Timing Loop, Field Sync Checker and Equalizer btl = atsc.bit_timing_loop() fsc = atsc.fs_checker() eq = atsc.equalizer() fsd = atsc.field_sync_demux() # Viterbi viterbi = atsc.viterbi_decoder() deinter = atsc.deinterleaver() rs_dec = atsc.rs_decoder() derand = atsc.derandomizer() depad = atsc.depad() # Write to output file outf = blocks.file_sink(gr.sizeof_char,outfile) # Connect it all together tb.connect( srcf, is2c, rrc, ilp, duc, c2f, fpll, lp_filter) tb.connect( lp_filter, iir ) tb.connect( lp_filter, (remove_dc, 0) ) tb.connect( iir, (remove_dc, 1) ) tb.connect( remove_dc, btl ) tb.connect( (btl, 0), (fsc, 0), (eq, 0), (fsd,0) ) tb.connect( (btl, 1), (fsc, 1), (eq, 1), (fsd,1) ) tb.connect( fsd, viterbi, deinter, rs_dec, derand, depad, outf ) tb.run()
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") options = get_options() self.ifreq = options.frequency self.rfgain = options.gain self.src = osmosdr.source(options.args) self.src.set_center_freq(self.ifreq) self.src.set_sample_rate(int(options.sample_rate)) if self.rfgain is None: self.src.set_gain_mode(1) self.iagc = 1 self.rfgain = 0 else: self.iagc = 0 self.src.set_gain_mode(0) self.src.set_gain(self.rfgain) # may differ from the requested rate sample_rate = self.src.get_sample_rate() sys.stderr.write("sample rate: %d\n" % (sample_rate)) symbol_rate = 18000 sps = 2 # output rate will be 36,000 out_sample_rate = symbol_rate * sps options.low_pass = options.low_pass / 2.0 if sample_rate == 96000: # FunCube Dongle first_decim = 2 else: first_decim = 10 self.offset = 0 taps = firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.2, firdes.WIN_HANN) self.tuner = filter.freq_xlating_fir_filter_ccf(first_decim, taps, self.offset, sample_rate) self.demod = cqpsk.cqpsk_demod( samples_per_symbol = sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) self.output = blocks.file_sink(gr.sizeof_float, options.output_file) rerate = float(sample_rate / float(first_decim)) / float(out_sample_rate) sys.stderr.write("resampling factor: %f\n" % rerate) if rerate.is_integer(): sys.stderr.write("using pfb decimator\n") self.resamp = filter.pfb.decimator_ccf(int(rerate), None, 0, 110) #self.resamp = filter.pfb_decimator_ccf(int(rerate), taps, 0, 110) else: sys.stderr.write("using pfb resampler\n") self.resamp = filter.pfb_arb_resampler_ccf(1 / rerate) self.connect(self.src, self.tuner, self.resamp, self.demod, self.output) self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.Main.AddPage(grc_wxgui.Panel(self.Main), "Wideband Spectrum") self.Main.AddPage(grc_wxgui.Panel(self.Main), "Channel Spectrum") self.Main.AddPage(grc_wxgui.Panel(self.Main), "Soft Bits") def set_ifreq(ifreq): self.ifreq = ifreq self._ifreq_text_box.set_value(self.ifreq) self.src.set_center_freq(self.ifreq) self._ifreq_text_box = forms.text_box( parent=self.GetWin(), value=self.ifreq, callback=set_ifreq, label="Center Frequency", converter=forms.float_converter(), ) self.Add(self._ifreq_text_box) def set_iagc(iagc): self.iagc = iagc self._agc_check_box.set_value(self.iagc) self.src.set_gain_mode(self.iagc, 0) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) self._agc_check_box = forms.check_box( parent=self.GetWin(), value=self.iagc, callback=set_iagc, label="Automatic Gain", true=1, false=0, ) self.Add(self._agc_check_box) def set_rfgain(rfgain): self.rfgain = rfgain self._rfgain_slider.set_value(self.rfgain) self._rfgain_text_box.set_value(self.rfgain) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) _rfgain_sizer = wx.BoxSizer(wx.VERTICAL) self._rfgain_text_box = forms.text_box( parent=self.GetWin(), sizer=_rfgain_sizer, value=self.rfgain, callback=set_rfgain, label="RF Gain", converter=forms.float_converter(), proportion=0, ) self._rfgain_slider = forms.slider( parent=self.GetWin(), sizer=_rfgain_sizer, value=self.rfgain, callback=set_rfgain, minimum=0, maximum=50, num_steps=200, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_rfgain_sizer) self.Add(self.Main) def fftsink2_callback(x, y): if abs(x / (sample_rate / 2)) > 0.9: set_ifreq(self.ifreq + x / 2) else: sys.stderr.write("coarse tuned to: %d Hz\n" % x) self.offset = -x self.tuner.set_center_freq(self.offset) self.scope = fftsink2.fft_sink_c(self.Main.GetPage(0).GetWin(), title="Wideband Spectrum (click to coarse tune)", fft_size=1024, sample_rate=sample_rate, ref_scale=2.0, ref_level=0, y_divs=10, fft_rate=10, average=False, avg_alpha=0.6) self.Main.GetPage(0).Add(self.scope.win) self.scope.set_callback(fftsink2_callback) self.connect(self.src, self.scope) def fftsink2_callback2(x, y): self.offset = self.offset - (x / 10) sys.stderr.write("fine tuned to: %d Hz\n" % self.offset) self.tuner.set_center_freq(self.offset) self.scope2 = fftsink2.fft_sink_c(self.Main.GetPage(1).GetWin(), title="Channel Spectrum (click to fine tune)", fft_size=1024, sample_rate=out_sample_rate, ref_scale=2.0, ref_level=-20, y_divs=10, fft_rate=10, average=False, avg_alpha=0.6) self.Main.GetPage(1).Add(self.scope2.win) self.scope2.set_callback(fftsink2_callback2) self.connect(self.resamp, self.scope2) self.scope3 = scopesink2.scope_sink_f( self.Main.GetPage(2).GetWin(), title="Soft Bits", sample_rate=out_sample_rate, v_scale=0, v_offset=0, t_scale=0.001, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=wxgui.TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Main.GetPage(2).Add(self.scope3.win) self.connect(self.demod, self.scope3)
def __init__(self): gr.top_block.__init__(self) # Variables options = self.get_options() self.src = osmosdr.source(options.args) self.src.set_center_freq(options.frequency) self.src.set_freq_corr(options.ppm) self.src.set_sample_rate(int(options.sample_rate)) if options.gain is None: self.src.set_gain_mode(1) else: self.src.set_gain_mode(0) self.src.set_gain(options.gain) # may differ from the requested rate sample_rate = self.src.get_sample_rate() sys.stderr.write("sample rate: %d\n" % sample_rate) gsm_symb_rate = 1625000.0 / 6.0 sps = sample_rate / gsm_symb_rate / options.osr # configure channel filter filter_cutoff = 135e3 # 135,417Hz is GSM bandwidth filter_t_width = 10e3 offset = 0.0 filter_taps = filter.firdes.low_pass(1.0, sample_rate, filter_cutoff, filter_t_width, filter.firdes.WIN_HAMMING) self.gr_null_sink = blocks.null_sink(568) self.filter = filter.freq_xlating_fir_filter_ccf(1, filter_taps, offset, sample_rate) self.interpolator = filter.fractional_resampler_cc(0, sps) self.tuner_callback = tuner(self) self.synchronizer_callback = synchronizer(self) self.null_callback = nullcb(self) print ">>>>>Input rate: ", sample_rate self.receiver = npgsm.receiver_cf( self.tuner_callback, self.synchronizer_callback, options.osr, options.c0pos, options.ma.replace(' ', '').lower(), options.maio, options.hsn, options.key.replace(' ', '').lower(), options.configuration.upper(), True) #self.receiver_1 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'1S',False) #self.receiver_2 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'2S',False) #self.receiver_3 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'3S',False) #self.receiver_4 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'4S',False) #self.receiver_5 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'5S',False) #self.receiver_6 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'6S',False) #self.receiver_7 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'7S',False) self.connect((self.src, 0), (self.filter, 0), (self.interpolator, 0), (self.receiver, 0), (self.gr_null_sink, 0))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") options = get_options() self.tune_corrector_callback = tune_corrector(self) self.synchronizer_callback = synchronizer(self) self.converter = blocks.vector_to_stream(gr.sizeof_float, 142) self.ifreq = options.frequency self.rfgain = options.gain self.src = osmosdr.source(options.args) self.src.set_center_freq(self.ifreq) self.src.set_sample_rate(int(options.sample_rate)) if self.rfgain is None: self.src.set_gain_mode(1) self.iagc = 1 self.rfgain = 0 else: self.iagc = 0 self.src.set_gain_mode(0) self.src.set_gain(self.rfgain) # may differ from the requested rate sample_rate = self.src.get_sample_rate() sys.stderr.write("sample rate: %d\n" % (sample_rate)) gsm_symb_rate = 1625000.0 / 6.0 sps = sample_rate / gsm_symb_rate / 4 out_sample_rate = gsm_symb_rate * 4 self.offset = 0 taps = filter.firdes.low_pass(1.0, sample_rate, 145e3, 10e3, filter.firdes.WIN_HANN) self.tuner = filter.freq_xlating_fir_filter_ccf(1, taps, self.offset, sample_rate) self.interpolator = filter.fractional_resampler_cc(0, sps) self.receiver = gsm.receiver_cf( self.tune_corrector_callback, self.synchronizer_callback, 4, options.key.replace(' ', '').lower(), options.configuration.upper()) self.output = blocks.file_sink(gr.sizeof_float, options.output_file) self.connect(self.src, self.tuner, self.interpolator, self.receiver, self.converter, self.output) def set_ifreq(ifreq): self.ifreq = ifreq self._ifreq_text_box.set_value(self.ifreq) self.src.set_center_freq(self.ifreq) self._ifreq_text_box = forms.text_box( parent=self.GetWin(), value=self.ifreq, callback=set_ifreq, label="Center Frequency", converter=forms.float_converter(), ) self.Add(self._ifreq_text_box) def set_iagc(iagc): self.iagc = iagc self._agc_check_box.set_value(self.iagc) self.src.set_gain_mode(self.iagc, 0) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) self._agc_check_box = forms.check_box( parent=self.GetWin(), value=self.iagc, callback=set_iagc, label="Automatic Gain", true=1, false=0, ) self.Add(self._agc_check_box) def set_rfgain(rfgain): self.rfgain = rfgain self._rfgain_slider.set_value(self.rfgain) self._rfgain_text_box.set_value(self.rfgain) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) _rfgain_sizer = wx.BoxSizer(wx.VERTICAL) self._rfgain_text_box = forms.text_box( parent=self.GetWin(), sizer=_rfgain_sizer, value=self.rfgain, callback=set_rfgain, label="RF Gain", converter=forms.float_converter(), proportion=0, ) self._rfgain_slider = forms.slider( parent=self.GetWin(), sizer=_rfgain_sizer, value=self.rfgain, callback=set_rfgain, minimum=0, maximum=50, num_steps=200, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_rfgain_sizer) def fftsink2_callback(x, y): if abs(x / (sample_rate / 2)) > 0.9: set_ifreq(self.ifreq + x / 2) else: sys.stderr.write("coarse tuned to: %d Hz\n" % x) self.offset = -x self.tuner.set_center_freq(self.offset) self.scope = fftsink2.fft_sink_c(self.GetWin(), title="Wideband Spectrum (click to coarse tune)", fft_size=1024, sample_rate=sample_rate, ref_scale=2.0, ref_level=0, y_divs=10, fft_rate=10, average=False, avg_alpha=0.3) self.Add(self.scope.win) self.scope.set_callback(fftsink2_callback) self.connect(self.src, self.scope) def fftsink2_callback2(x, y): self.offset = self.offset - (x / 10) sys.stderr.write("fine tuned to: %d Hz\n" % self.offset) self.tuner.set_center_freq(self.offset) self.scope2 = fftsink2.fft_sink_c(self.GetWin(), title="Channel Spectrum (click to fine tune)", fft_size=1024, sample_rate=gsm_symb_rate * 4, ref_scale=2.0, ref_level=-20, y_divs=10, fft_rate=10, average=False, avg_alpha=0.3) self.Add(self.scope2.win) self.scope2.set_callback(fftsink2_callback2) self.connect(self.interpolator, self.scope2)
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("-a", "--args", type="string", default="", help="UHD device address args [default=%default]") parser.add_option("", "--spec", type="string", default=None, help="Subdevice of UHD device where appropriate") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, help="set sample rate (bandwidth) [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=1008.0e3, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-I", "--use-if-freq", action="store_true", default=False, help="use intermediate freq (compensates DC problems in quadrature boards)" ) parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is maximum)") parser.add_option("-V", "--volume", type="eng_float", default=None, help="set volume (default is midpoint)") parser.add_option("-O", "--audio-output", type="string", default="default", help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.frame = frame self.panel = panel self.use_IF=options.use_if_freq if self.use_IF: self.IF_freq=64000.0 else: self.IF_freq=0.0 self.vol = 0 self.state = "FREQ" self.freq = 0 # build graph self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32')) # Set the subdevice spec if(options.spec): self.u.set_subdev_spec(options.spec, 0) # Set the antenna if(options.antenna): self.u.set_antenna(options.antenna, 0) usrp_rate = 256e3 demod_rate = 64e3 audio_rate = 32e3 chanfilt_decim = int(usrp_rate // demod_rate) audio_decim = int(demod_rate // audio_rate) self.u.set_samp_rate(usrp_rate) dev_rate = self.u.get_samp_rate() # Resample signal to exactly self.usrp_rate # FIXME: make one of the follow-on filters an arb resampler rrate = usrp_rate / dev_rate self.resamp = filter.pfb.arb_resampler_ccf(rrate) chan_filt_coeffs = filter.firdes.low_pass_2(1, # gain usrp_rate, # sampling rate 8e3, # passband cutoff 4e3, # transition bw 60) # stopband attenuation if self.use_IF: # Turn If to baseband and filter. self.chan_filt = filter.freq_xlating_fir_filter_ccf(chanfilt_decim, chan_filt_coeffs, self.IF_freq, usrp_rate) else: self.chan_filt = filter.fir_filter_ccf(chanfilt_decim, chan_filt_coeffs) self.agc = analog.agc_cc(0.1, 1, 1, 100000) self.am_demod = blocks.complex_to_mag() self.volume_control = blocks.multiply_const_ff(self.vol) audio_filt_coeffs = filter.firdes.low_pass_2(1, # gain demod_rate, # sampling rate 8e3, # passband cutoff 2e3, # transition bw 60) # stopband attenuation self.audio_filt = filter.fir_filter_fff(audio_decim, audio_filt_coeffs) # sound card as final sink self.audio_sink = audio.sink(int (audio_rate), options.audio_output, False) # ok_to_block # now wire it all together self.connect (self.u, self.resamp, self.chan_filt, self.agc, self.am_demod, self.audio_filt, self.volume_control, self.audio_sink) self._build_gui(vbox, usrp_rate, demod_rate, audio_rate) if options.gain is None: g = self.u.get_gain_range() # if no gain was specified, use the mid gain options.gain = (g.start() + g.stop())/2.0 if options.volume is None: v = self.volume_range() options.volume = float(v[0]*3+v[1])/4.0 if abs(options.freq) < 1e3: options.freq *= 1e3 # set initial values self.set_gain(options.gain) self.set_vol(options.volume) if not(self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency")
def __init__(self): gr.top_block.__init__(self) # grc_wxgui.top_block_gui.__init__(self, title="Top Block") options = get_options() self.tune_corrector_callback = tune_corrector(self) self.synchronizer_callback = synchronizer(self) self.converter = blocks.vector_to_stream(gr.sizeof_float, 142) self.ifreq = options.frequency self.rfgain = options.gain self.src = osmosdr.source(options.args) self.src.set_center_freq(self.ifreq) self.src.set_sample_rate(int(options.sample_rate)) if self.rfgain is None: self.src.set_gain_mode(1) self.iagc = 1 self.rfgain = 0 else: self.iagc = 0 self.src.set_gain_mode(0) self.src.set_gain(self.rfgain) # may differ from the requested rate sample_rate = self.src.get_sample_rate() sys.stderr.write("sample rate: %d\n" % (sample_rate)) gsm_symb_rate = 1625000.0 / 6.0 sps = sample_rate / gsm_symb_rate / 4 out_sample_rate = gsm_symb_rate * 4 self.offset = 0 taps = filter.firdes.low_pass(1.0, sample_rate, 145e3, 10e3, filter.firdes.WIN_HANN) self.tuner = filter.freq_xlating_fir_filter_ccf(1, taps, self.offset, sample_rate) self.interpolator = filter.fractional_resampler_cc(0, sps) self.receiver = gsm.receiver_cf( self.tune_corrector_callback, self.synchronizer_callback, 4, options.key.replace(' ', '').lower(), options.configuration.upper()) self.output = blocks.file_sink(gr.sizeof_float, options.output_file) self.connect(self.src, self.tuner, self.interpolator, self.receiver, self.converter, self.output) def set_ifreq(ifreq): self.ifreq = ifreq self._ifreq_text_box.set_value(self.ifreq) self.src.set_center_freq(self.ifreq) def set_iagc(iagc): self.iagc = iagc self._agc_check_box.set_value(self.iagc) self.src.set_gain_mode(self.iagc, 0) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) def set_rfgain(rfgain): self.rfgain = rfgain self._rfgain_slider.set_value(self.rfgain) self._rfgain_text_box.set_value(self.rfgain) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) def fftsink2_callback(x, y): if abs(x / (sample_rate / 2)) > 0.9: set_ifreq(self.ifreq + x / 2) else: sys.stderr.write("coarse tuned to: %d Hz\n" % x) self.offset = -x self.tuner.set_center_freq(self.offset) def fftsink2_callback2(x, y): self.offset = self.offset - (x / 10) sys.stderr.write("fine tuned to: %d Hz\n" % self.offset) self.tuner.set_center_freq(self.offset)
def __init__(self): gr.top_block.__init__(self) # Variables options = self.get_options() self.src = osmosdr.source(options.args) self.src.set_center_freq(options.frequency) self.src.set_freq_corr(options.ppm) self.src.set_sample_rate(int(options.sample_rate)) if options.gain is None: self.src.set_gain_mode(1) else: self.src.set_gain_mode(0) self.src.set_gain(options.gain) # may differ from the requested rate sample_rate = self.src.get_sample_rate() sys.stderr.write("sample rate: %d\n" % sample_rate) gsm_symb_rate = 1625000.0 / 6.0 sps = sample_rate / gsm_symb_rate / options.osr # configure channel filter filter_cutoff = 135e3 # 135,417Hz is GSM bandwidth filter_t_width = 10e3 offset = 0.0 filter_taps = filter.firdes.low_pass(1.0, sample_rate, filter_cutoff, filter_t_width, filter.firdes.WIN_HAMMING) self.gr_null_sink = blocks.null_sink(568) self.filter = filter.freq_xlating_fir_filter_ccf( 1, filter_taps, offset, sample_rate) self.interpolator = filter.fractional_resampler_cc(0, sps) self.tuner_callback = tuner(self) self.synchronizer_callback = synchronizer(self) self.null_callback = nullcb(self) print ">>>>>Input rate: ", sample_rate self.receiver = npgsm.receiver_cf(self.tuner_callback, self.synchronizer_callback, options.osr, options.c0pos, options.ma.replace(' ', '').lower(), options.maio, options.hsn, options.key.replace(' ', '').lower(), options.configuration.upper(), True) #self.receiver_1 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'1S',False) #self.receiver_2 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'2S',False) #self.receiver_3 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'3S',False) #self.receiver_4 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'4S',False) #self.receiver_5 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'5S',False) #self.receiver_6 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'6S',False) #self.receiver_7 = npgsm.receiver_cf(self.null_callback,self.null_callback,options.osr,options.c0pos,options.ma.replace(' ', '').lower(),options.maio,options.hsn,options.key.replace(' ', '').lower(),'7S',False) self.connect((self.src, 0), (self.filter, 0), (self.interpolator, 0), (self.receiver, 0), (self.gr_null_sink, 0))
def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) # Menu Bar self.frame_1_menubar = wx.MenuBar() self.SetMenuBar(self.frame_1_menubar) wxglade_tmp_menu = wx.Menu() self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL) wxglade_tmp_menu.AppendItem(self.Exit) self.frame_1_menubar.Append(wxglade_tmp_menu, "File") # Menu Bar end self.panel_1 = wx.Panel(self, -1) self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB") self.button_2 = wx.Button(self, ID_BUTTON_2, "USB") self.button_3 = wx.Button(self, ID_BUTTON_3, "AM") self.button_4 = wx.Button(self, ID_BUTTON_4, "CW") self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper") self.slider_fcutoff_hi = wx.Slider(self, ID_SLIDER_1, 0, -15798, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower") self.slider_fcutoff_lo = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15798, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_5 = wx.Panel(self, -1) self.label_1 = wx.StaticText(self, -1, " Band\nCenter") self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "") self.panel_6 = wx.Panel(self, -1) self.panel_7 = wx.Panel(self, -1) self.panel_2 = wx.Panel(self, -1) self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq") self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000) self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100) self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol") self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500) self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20) self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time") self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew") self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd") self.panel_3 = wx.Panel(self, -1) self.label_2 = wx.StaticText(self, -1, "PGA ") self.panel_4 = wx.Panel(self, -1) self.panel_8 = wx.Panel(self, -1) self.panel_9 = wx.Panel(self, -1) self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier") self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.label_4 = wx.StaticText(self, -1, "Antenna Tune") self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_10 = wx.Panel(self, -1) self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune") self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate") self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset") self.panel_11 = wx.Panel(self, -1) self.panel_12 = wx.Panel(self, -1) self.__set_properties() self.__do_layout() # end wxGlade parser = OptionParser(option_class=eng_option) parser.add_option( "", "--address", type="string", default="addr=192.168.10.2", help="Address of UHD device, [default=%default]", ) parser.add_option( "-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ" ) parser.add_option( "-s", "--samp-rate", type="eng_float", default=256e3, help="set sample rate (bandwidth) [default=%default]" ) parser.add_option("-a", "--audio_file", default="", help="audio output file", metavar="FILE") parser.add_option("-r", "--radio_file", default="", help="radio output file", metavar="FILE") parser.add_option("-i", "--input_file", default="", help="radio input file", metavar="FILE") parser.add_option( "-O", "--audio-output", type="string", default="", help="audio output device name. E.g., hw:0,0, /dev/dsp, or pulse", ) (options, args) = parser.parse_args() self.usrp_center = options.ddc_freq input_rate = options.samp_rate self.slider_range = input_rate * 0.9375 self.f_lo = self.usrp_center - (self.slider_range / 2) self.f_hi = self.usrp_center + (self.slider_range / 2) self.af_sample_rate = 32000 fir_decim = long(input_rate / self.af_sample_rate) # data point arrays for antenna tuner self.xdata = [] self.ydata = [] self.tb = gr.top_block() # radio variables, initial conditions self.frequency = self.usrp_center # these map the frequency slider (0-6000) to the actual range self.f_slider_offset = self.f_lo self.f_slider_scale = 10000 self.spin_ctrl_1.SetRange(self.f_lo, self.f_hi) self.text_ctrl_1.SetValue(str(int(self.usrp_center))) self.slider_5.SetValue(0) self.AM_mode = False self.slider_3.SetValue((self.frequency - self.f_slider_offset) / self.f_slider_scale) self.spin_ctrl_1.SetValue(int(self.frequency)) POWERMATE = True try: self.pm = powermate.powermate(self) except: sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n") POWERMATE = False if POWERMATE: powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton) self.active_button = 7 # command line options if options.audio_file == "": SAVE_AUDIO_TO_FILE = False else: SAVE_AUDIO_TO_FILE = True if options.radio_file == "": SAVE_RADIO_TO_FILE = False else: SAVE_RADIO_TO_FILE = True if options.input_file == "": self.PLAY_FROM_USRP = True else: self.PLAY_FROM_USRP = False if self.PLAY_FROM_USRP: self.src = uhd.usrp_source(device_addr=options.address, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) self.src.set_samp_rate(input_rate) input_rate = self.src.get_samp_rate() self.src.set_center_freq(self.usrp_center, 0) self.tune_offset = 0 else: self.src = blocks.file_source(gr.sizeof_short, options.input_file) self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band # convert rf data in interleaved short int form to complex s2ss = blocks.stream_to_streams(gr.sizeof_short, 2) s2f1 = blocks.short_to_float() s2f2 = blocks.short_to_float() src_f2c = blocks.float_to_complex() self.tb.connect(self.src, s2ss) self.tb.connect((s2ss, 0), s2f1) self.tb.connect((s2ss, 1), s2f2) self.tb.connect(s2f1, (src_f2c, 0)) self.tb.connect(s2f2, (src_f2c, 1)) # save radio data to a file if SAVE_RADIO_TO_FILE: radio_file = blocks.file_sink(gr.sizeof_short, options.radio_file) self.tb.connect(self.src, radio_file) # 2nd DDC xlate_taps = filter.firdes.low_pass(1.0, input_rate, 16e3, 4e3, filter.firdes.WIN_HAMMING) self.xlate = filter.freq_xlating_fir_filter_ccf(fir_decim, xlate_taps, self.tune_offset, input_rate) # Complex Audio filter audio_coeffs = filter.firdes.complex_band_pass( 1.0, # gain self.af_sample_rate, # sample rate -3000, # low cutoff 0, # high cutoff 100, # transition filter.firdes.WIN_HAMMING, ) # window self.slider_fcutoff_hi.SetValue(0) self.slider_fcutoff_lo.SetValue(-3000) self.audio_filter = filter.fir_filter_ccc(1, audio_coeffs) # Main +/- 16Khz spectrum display self.fft = fftsink2.fft_sink_c( self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240) ) # AM Sync carrier if AM_SYNC_DISPLAY: self.fft2 = fftsink.fft_sink_c( self.tb, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240), ) c2f = blocks.complex_to_float() # AM branch self.sel_am = blocks.multiply_const_cc(0) # the following frequencies turn out to be in radians/sample # analog.pll_refout_cc(alpha,beta,min_freq,max_freq) # suggested alpha = X, beta = .25 * X * X pll = analog.pll_refout_cc( 0.5, 0.0625, (2.0 * math.pi * 7.5e3 / self.af_sample_rate), (2.0 * math.pi * 6.5e3 / self.af_sample_rate) ) self.pll_carrier_scale = blocks.multiply_const_cc(complex(10, 0)) am_det = blocks.multiply_cc() # these are for converting +7.5kHz to -7.5kHz # for some reason blocks.conjugate_cc() adds noise ?? c2f2 = blocks.complex_to_float() c2f3 = blocks.complex_to_float() f2c = blocks.float_to_complex() phaser1 = blocks.multiply_const_ff(1) phaser2 = blocks.multiply_const_ff(-1) # filter for pll generated carrier pll_carrier_coeffs = filter.firdes.complex_band_pass( 2.0, # gain self.af_sample_rate, # sample rate 7400, # low cutoff 7600, # high cutoff 100, # transition filter.firdes.WIN_HAMMING, ) # window self.pll_carrier_filter = filter.fir_filter_ccc(1, pll_carrier_coeffs) self.sel_sb = blocks.multiply_const_ff(1) combine = blocks.add_ff() # AGC sqr1 = blocks.multiply_ff() intr = filter.iir_filter_ffd([0.004, 0], [0, 0.999]) offset = blocks.add_const_ff(1) agc = blocks.divide_ff() self.scale = blocks.multiply_const_ff(0.00001) dst = audio.sink(long(self.af_sample_rate), options.audio_output) if self.PLAY_FROM_USRP: self.tb.connect(self.src, self.xlate, self.fft) else: self.tb.connect(src_f2c, self.xlate, self.fft) self.tb.connect(self.xlate, self.audio_filter, self.sel_am, (am_det, 0)) self.tb.connect(self.sel_am, pll, self.pll_carrier_scale, self.pll_carrier_filter, c2f3) self.tb.connect((c2f3, 0), phaser1, (f2c, 0)) self.tb.connect((c2f3, 1), phaser2, (f2c, 1)) self.tb.connect(f2c, (am_det, 1)) self.tb.connect(am_det, c2f2, (combine, 0)) self.tb.connect(self.audio_filter, c2f, self.sel_sb, (combine, 1)) if AM_SYNC_DISPLAY: self.tb.connect(self.pll_carrier_filter, self.fft2) self.tb.connect(combine, self.scale) self.tb.connect(self.scale, (sqr1, 0)) self.tb.connect(self.scale, (sqr1, 1)) self.tb.connect(sqr1, intr, offset, (agc, 1)) self.tb.connect(self.scale, (agc, 0)) self.tb.connect(agc, dst) if SAVE_AUDIO_TO_FILE: f_out = blocks.file_sink(gr.sizeof_short, options.audio_file) sc1 = blocks.multiply_const_ff(64000) f2s1 = blocks.float_to_short() self.tb.connect(agc, sc1, f2s1, f_out) self.tb.start() # for mouse position reporting on fft display self.fft.win.Bind(wx.EVT_LEFT_UP, self.Mouse) # and left click to re-tune self.fft.win.Bind(wx.EVT_LEFT_DOWN, self.Click) # start a timer to check for web commands if WEB_CONTROL: self.timer = UpdateTimer(self, 1000) # every 1000 mSec, 1 Sec wx.EVT_BUTTON(self, ID_BUTTON_1, self.set_lsb) wx.EVT_BUTTON(self, ID_BUTTON_2, self.set_usb) wx.EVT_BUTTON(self, ID_BUTTON_3, self.set_am) wx.EVT_BUTTON(self, ID_BUTTON_4, self.set_cw) wx.EVT_BUTTON(self, ID_BUTTON_10, self.fwd) wx.EVT_BUTTON(self, ID_BUTTON_11, self.rew) wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate) wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_5, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_6, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_7, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_8, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_9, self.on_button) wx.EVT_SLIDER(self, ID_SLIDER_1, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_2, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_3, self.slide_tune) wx.EVT_SLIDER(self, ID_SLIDER_4, self.set_volume) wx.EVT_SLIDER(self, ID_SLIDER_5, self.set_pga) wx.EVT_SLIDER(self, ID_SLIDER_6, self.am_carrier) wx.EVT_SLIDER(self, ID_SLIDER_7, self.antenna_tune) wx.EVT_SPINCTRL(self, ID_SPIN_1, self.spin_tune) wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)
def graph(args): nargs = len(args) if nargs == 2: infile = args[0] outfile = args[1] else: raise ValueError('usage: interp.py input_file output_file\n') tb = gr.top_block() # Convert to a from shorts to a stream of complex numbers. srcf = blocks.file_source(gr.sizeof_short, infile) s2ss = blocks.stream_to_streams(gr.sizeof_short, 2) s2f1 = blocks.short_to_float() s2f2 = blocks.short_to_float() src0 = blocks.float_to_complex() tb.connect(srcf, s2ss) tb.connect((s2ss, 0), s2f1, (src0, 0)) tb.connect((s2ss, 1), s2f2, (src0, 1)) # Low pass filter it and increase sample rate by a factor of 3. lp_coeffs = filter.firdes.low_pass(3, 19.2e6, 3.2e6, .5e6, filter.firdes.WIN_HAMMING) lp = filter.interp_fir_filter_ccf(3, lp_coeffs) tb.connect(src0, lp) # Upconvert it. duc_coeffs = filter.firdes.low_pass(1, 19.2e6, 9e6, 1e6, filter.firdes.WIN_HAMMING) duc = filter.freq_xlating_fir_filter_ccf(1, duc_coeffs, 5.75e6, 19.2e6) # Discard the imaginary component. c2f = blocks.complex_to_float() tb.connect(lp, duc, c2f) # Frequency Phase Lock Loop input_rate = 19.2e6 IF_freq = 5.75e6 # 1/2 as wide because we're designing lp filter symbol_rate = atsc.ATSC_SYMBOL_RATE / 2. NTAPS = 279 tt = filter.firdes.root_raised_cosine(1.0, input_rate, symbol_rate, .115, NTAPS) # heterodyne the low pass coefficients up to the specified bandpass # center frequency. Note that when we do this, the filter bandwidth # is effectively twice the low pass (2.69 * 2 = 5.38) and hence # matches the diagram in the ATSC spec. arg = 2. * math.pi * IF_freq / input_rate t = [] for i in range(len(tt)): t += [tt[i] * 2. * math.cos(arg * i)] rrc = filter.fir_filter_fff(1, t) fpll = atsc.fpll() pilot_freq = IF_freq - 3e6 + 0.31e6 lower_edge = 6e6 - 0.31e6 upper_edge = IF_freq - 3e6 + pilot_freq transition_width = upper_edge - lower_edge lp_coeffs = filter.firdes.low_pass(1.0, input_rate, (lower_edge + upper_edge) * 0.5, transition_width, filter.firdes.WIN_HAMMING) lp_filter = filter.fir_filter_fff(1, lp_coeffs) alpha = 1e-5 iir = filter.single_pole_iir_filter_ff(alpha) remove_dc = blocks.sub_ff() tb.connect(c2f, fpll, lp_filter) tb.connect(lp_filter, iir) tb.connect(lp_filter, (remove_dc, 0)) tb.connect(iir, (remove_dc, 1)) # Bit Timing Loop, Field Sync Checker and Equalizer btl = atsc.bit_timing_loop() fsc = atsc.fs_checker() eq = atsc.equalizer() fsd = atsc.field_sync_demux() tb.connect(remove_dc, btl) tb.connect((btl, 0), (fsc, 0), (eq, 0), (fsd, 0)) tb.connect((btl, 1), (fsc, 1), (eq, 1), (fsd, 1)) # Viterbi viterbi = atsc.viterbi_decoder() deinter = atsc.deinterleaver() rs_dec = atsc.rs_decoder() derand = atsc.derandomizer() depad = atsc.depad() dst = blocks.file_sink(gr.sizeof_char, outfile) tb.connect(fsd, viterbi, deinter, rs_dec, derand, depad, dst) dst2 = blocks.file_sink(gr.sizeof_gr_complex, "atsc_complex.data") tb.connect(src0, dst2) tb.run()
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") options = get_options() self.ifreq = options.frequency self.rfgain = options.gain self.offset = options.frequency_offset self.src = osmosdr.source(options.args) self.src.set_center_freq(self.ifreq) self.src.set_sample_rate(int(options.sample_rate)) if self.rfgain is None: self.src.set_gain_mode(1) self.iagc = 1 self.rfgain = 0 else: self.iagc = 0 self.src.set_gain_mode(0) self.src.set_gain(self.rfgain) # may differ from the requested rate sample_rate = self.src.get_sample_rate() sys.stderr.write("sample rate: %d\n" % (sample_rate)) symbol_rate = 18000 sps = 2 # output rate will be 36,000 out_sample_rate = symbol_rate * sps options.low_pass = options.low_pass / 2.0 if sample_rate == 96000: # FunCube Dongle first_decim = 2 else: first_decim = 10 self.offset = 0 taps = firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.2, firdes.WIN_HANN) self.tuner = filter.freq_xlating_fir_filter_ccf( first_decim, taps, self.offset, sample_rate) self.demod = cqpsk.cqpsk_demod(samples_per_symbol=sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) self.output = blocks.file_sink(gr.sizeof_float, options.output_file) rerate = float(sample_rate) / float(first_decim) / float( out_sample_rate) sys.stderr.write("resampling factor: %f\n" % rerate) if rerate.is_integer(): sys.stderr.write("using pfb decimator\n") #self.resamp = filter.pfb_decimator_ccf(int(rerate), firdes.low_pass(1,int(sample_rate), 50000,5000), 1) self.resamp = filter.fir_filter_ccf( int(rerate), firdes.low_pass(1, int(sample_rate / first_decim), 50000, 5000)) else: sys.stderr.write("using pfb resampler\n") t = filter.firdes.low_pass_2( 32, 32.0 * sample_rate / first_decim, 60000, 5000, attenuation_dB=3, window=filter.firdes.WIN_BLACKMAN_hARRIS) self.resamp = filter.pfb_arb_resampler_ccf(1.0 / rerate, t, 32) self.connect(self.src, self.tuner, self.resamp, self.demod, self.output) self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.Main.AddPage(grc_wxgui.Panel(self.Main), "Wideband Spectrum") self.Main.AddPage(grc_wxgui.Panel(self.Main), "Channel Spectrum") self.Main.AddPage(grc_wxgui.Panel(self.Main), "Soft Bits") def set_ifreq(ifreq): self.ifreq = ifreq self._ifreq_text_box.set_value(self.ifreq) self.src.set_center_freq(self.ifreq) self._ifreq_text_box = forms.text_box( parent=self.GetWin(), value=self.ifreq, callback=set_ifreq, label="Center Frequency", converter=forms.float_converter(), ) self.Add(self._ifreq_text_box) def set_iagc(iagc): self.iagc = iagc self._agc_check_box.set_value(self.iagc) self.src.set_gain_mode(self.iagc, 0) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) self._agc_check_box = forms.check_box( parent=self.GetWin(), value=self.iagc, callback=set_iagc, label="Automatic Gain", true=1, false=0, ) self.Add(self._agc_check_box) def set_rfgain(rfgain): self.rfgain = rfgain self._rfgain_slider.set_value(self.rfgain) self._rfgain_text_box.set_value(self.rfgain) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) _rfgain_sizer = wx.BoxSizer(wx.VERTICAL) self._rfgain_text_box = forms.text_box( parent=self.GetWin(), sizer=_rfgain_sizer, value=self.rfgain, callback=set_rfgain, label="RF Gain", converter=forms.float_converter(), proportion=0, ) self._rfgain_slider = forms.slider( parent=self.GetWin(), sizer=_rfgain_sizer, value=self.rfgain, callback=set_rfgain, minimum=0, maximum=50, num_steps=200, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_rfgain_sizer) self.Add(self.Main) def fftsink2_callback(x, y): if abs(x / (sample_rate / 2)) > 0.9: set_ifreq(self.ifreq + x / 2) else: self.offset = -x sys.stderr.write("coarse tuned to: %d Hz => %d Hz\n" % (self.offset, (self.ifreq + self.offset))) self.tuner.set_center_freq(self.offset) self.scope = fftsink2.fft_sink_c( self.Main.GetPage(0).GetWin(), title="Wideband Spectrum (click to coarse tune)", fft_size=1024, sample_rate=sample_rate, ref_scale=2.0, ref_level=0, y_divs=10, fft_rate=10, average=False, avg_alpha=0.6) self.Main.GetPage(0).Add(self.scope.win) self.scope.set_callback(fftsink2_callback) self.connect(self.src, self.scope) def fftsink2_callback2(x, y): self.offset = self.offset - (x / 10) sys.stderr.write("fine tuned to: %d Hz => %d Hz\n" % (self.offset, (self.ifreq + self.offset))) self.tuner.set_center_freq(self.offset) self.scope2 = fftsink2.fft_sink_c( self.Main.GetPage(1).GetWin(), title="Channel Spectrum (click to fine tune)", fft_size=1024, sample_rate=out_sample_rate, ref_scale=2.0, ref_level=-20, y_divs=10, fft_rate=10, average=False, avg_alpha=0.6) self.Main.GetPage(1).Add(self.scope2.win) self.scope2.set_callback(fftsink2_callback2) self.connect(self.resamp, self.scope2) self.scope3 = scopesink2.scope_sink_f( self.Main.GetPage(2).GetWin(), title="Soft Bits", sample_rate=out_sample_rate, v_scale=0, v_offset=0, t_scale=0.001, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=wxgui.TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Main.GetPage(2).Add(self.scope3.win) self.connect(self.demod, self.scope3)
def run(self, starttime=None, endtime=None, duration=None, period=10): op = self.op # print current time and NTP status if op.verbose: call(('timedatectl', 'status')) # parse time arguments if starttime is None: st = None else: dtst = dateutil.parser.parse(starttime) epoch = datetime.datetime(1970, 1, 1, tzinfo=pytz.utc) st = int((dtst - epoch).total_seconds()) # find next suitable start time by cycle repeat period soon = int(math.ceil(time.time())) + 5 periods_until_next = (max(soon - st, 0) - 1) // period + 1 st = st + periods_until_next * period if op.verbose: dtst = datetime.datetime.utcfromtimestamp(st) dtststr = dtst.strftime('%a %b %d %H:%M:%S %Y') print('Start time: {0} ({1})'.format(dtststr, st)) if endtime is None: et = None else: dtet = dateutil.parser.parse(endtime) epoch = datetime.datetime(1970, 1, 1, tzinfo=pytz.utc) et = int((dtet - epoch).total_seconds()) if op.verbose: dtetstr = dtet.strftime('%a %b %d %H:%M:%S %Y') print('End time: {0} ({1})'.format(dtetstr, et)) if et is not None: if (et < time.time() + 5) or (st is not None and et <= st): raise ValueError('End time is before launch time!') if op.realtime: r = gr.enable_realtime_scheduling() if op.verbose: if r == gr.RT_OK: print('Realtime scheduling enabled') else: print('Note: failed to enable realtime scheduling') # create data directory so ringbuffer code can be started while waiting # to launch if not os.path.isdir(op.datadir): os.makedirs(op.datadir) # wait for the start time if it is not past while (st is not None) and (st - time.time()) > 10: ttl = int(math.floor(st - time.time())) if (ttl % 10) == 0: print('Standby {0} s remaining...'.format(ttl)) sys.stdout.flush() time.sleep(1) # get UHD USRP source u = self._usrp_setup() # force creation of the RX streamer ahead of time with a finite # acquisition (after setting time/clock sources, before setting the # device time) # this fixes timing with the B210 u.finite_acquisition_v(16384) # wait until time 0.2 to 0.5 past full second, then latch # we have to trust NTP to be 0.2 s accurate tt = time.time() while tt - math.floor(tt) < 0.2 or tt - math.floor(tt) > 0.3: time.sleep(0.01) tt = time.time() if op.verbose: print('Latching at ' + str(tt)) if op.sync: # waits for the next pps to happen # (at time math.ceil(tt)) # then sets the time for the subsequent pps # (at time math.ceil(tt) + 1.0) u.set_time_unknown_pps(uhd.time_spec(math.ceil(tt) + 1.0)) else: u.set_time_now(uhd.time_spec(tt)) # reset device stream and flush buffer to clear leftovers from finite # acquisition u.stop() # get output settings that depend on decimation rate samplerate_out = op.samplerate / op.dec samplerate_num_out = op.samplerate_num samplerate_den_out = op.samplerate_den * op.dec if op.dec > 1: sample_size = gr.sizeof_gr_complex sample_dtype = '<f4' taps = firdes.low_pass_2(1.0, float(op.samplerate), float(samplerate_out / 2.0), float(0.2 * samplerate_out), 80.0, window=firdes.WIN_BLACKMAN_hARRIS) else: sample_size = 2 * gr.sizeof_short sample_dtype = '<i2' # set launch time # (at least 1 second out so USRP time is set, time to set up flowgraph) if st is not None: lt = st else: lt = int(math.ceil(time.time() + 1.0)) # adjust launch time forward so it falls on an exact sample since epoch lt_samples = np.ceil(lt * samplerate_out) lt = lt_samples / samplerate_out if op.verbose: dtlt = datetime.datetime.utcfromtimestamp(lt) dtltstr = dtlt.strftime('%a %b %d %H:%M:%S.%f %Y') print('Launch time: {0} ({1})'.format(dtltstr, repr(lt))) # command time ct_samples = lt_samples # splitting ct into secs/frac lets us set a more accurate time_spec ct_secs = ct_samples // samplerate_out ct_frac = (ct_samples % samplerate_out) / samplerate_out u.set_start_time( uhd.time_spec(float(ct_secs)) + uhd.time_spec(float(ct_frac))) # populate flowgraph one channel at a time fg = gr.top_block() for k in range(op.nchs): # create digital RF sink chdir = os.path.join(op.datadir, op.chs[k]) dst = gr_drf.digital_rf_sink( dir=chdir, sample_size=sample_size, subdir_cadence_s=op.subdir_cadence_s, file_cadence_ms=op.file_cadence_ms, sample_rate_numerator=samplerate_num_out, sample_rate_denominator=samplerate_den_out, uuid=op.uuid, is_complex=True, num_subchannels=1, stop_on_dropped_packet=op.stop_on_dropped, start_sample_index=int(lt * samplerate_out), ignore_tags=False, ) if op.dec > 1: # create low-pass filter lpf = filter.freq_xlating_fir_filter_ccf( op.dec, taps, 0.0, float(op.samplerate)) # connections for usrp->lpf->drf connections = ((u, k), (lpf, 0), (dst, 0)) else: # connections for usrp->drf connections = ((u, k), (dst, 0)) # make channel connections in flowgraph fg.connect(*connections) # start to receive data fg.start() # write metadata one channel at a time for k in range(op.nchs): mbnum = op.mboardnum_bychan[k] # create metadata dir, dmd object, and write channel metadata mddir = os.path.join(op.datadir, op.chs[k], 'metadata') if not os.path.exists(mddir): os.makedirs(mddir) mdo = drf.DigitalMetadataWriter( metadata_dir=mddir, subdir_cadence_secs=op.subdir_cadence_s, file_cadence_secs=1, sample_rate_numerator=samplerate_num_out, sample_rate_denominator=samplerate_den_out, file_name='metadata', ) md = op.metadata.copy() md.update( # standard metadata by convention uuid_str=op.uuid, sample_rate_numerator=samplerate_num_out, sample_rate_denominator=samplerate_den_out, # put in a list because we want the data to be a 1-D array # and it would be a single value if we didn't center_frequencies=[np.array([op.centerfreqs[k]])], # additional receiver metadata for USRP receiver=dict( description='UHD USRP source using GNU Radio', info=dict(u.get_usrp_info(chan=k)), antenna=op.antennas[k], bandwidth=op.bandwidths[k], center_freq=op.centerfreqs[k], clock_rate=u.get_clock_rate(mboard=mbnum), clock_source=u.get_clock_source(mboard=mbnum), gain=op.gains[k], id=op.mboards_bychan[k], lo_offset=op.lo_offsets[k], otw_format=op.otw_format, samp_rate=u.get_samp_rate(), stream_args=','.join(op.stream_args), subdev=op.subdevs_bychan[k], time_source=u.get_time_source(mboard=mbnum), ), ) mdo.write( samples=int(lt * samplerate_out), data_dict=md, ) # wait until end time or until flowgraph stops if et is None and duration is not None: et = lt + duration try: if et is None: fg.wait() else: # sleep until end time nears while (time.time() < et - 1): time.sleep(1) else: # issue stream stop command at end time ct_secs = et // 1 ct_frac = et % 1 u.set_command_time( (uhd.time_spec(float(ct_secs)) + uhd.time_spec(float(ct_frac))), uhd.ALL_MBOARDS, ) stop_enum = uhd.stream_cmd.STREAM_MODE_STOP_CONTINUOUS u.issue_stream_cmd(uhd.stream_cmd(stop_enum)) u.clear_command_time(uhd.ALL_MBOARDS) # sleep until after end time time.sleep(1) except KeyboardInterrupt: # catch keyboard interrupt and simply exit pass fg.stop() print('done') sys.stdout.flush()
def __init__(self, options, queue): grc_wxgui.top_block_gui.__init__(self, title="RTL FLEX reciever") self.options = options self.offset = 0.0 self.adj_time = time.time() self.verbose = options.verbose self.log = options.log self.fft_enable = options.fft # Set up rtl source self.u = osmosdr.source( args="%s"%(options.device) ) #set Freq self.u.set_center_freq(options.freq+options.calibration, 0) # Grab 250 KHz of spectrum self.u.set_sample_rate(250e3) rate = self.u.get_sample_rate() if rate != 250e3: print "Unable to set required sample rate of 250 Ksps (got %f)" % rate sys.exit(1) #Set gain if options.rx_gain is None: grange = self.u.get_gain_range() options.rx_gain = float(grange.start()+grange.stop())/2.0 print "\nNo gain specified." print "Setting gain to %f (from [%f, %f])" % \ (options.rx_gain, grange.start(), grange.stop()) self.u.set_gain(options.rx_gain, 0) taps = optfir.low_pass(1.0, 250e3, 11000, 12500, 0.1, 60) self.chan = filter.freq_xlating_fir_filter_ccf(10, taps, 0.0, 250e3) if self.fft_enable: self.fftsink = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=options.freq+options.calibration, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=250e3, fft_size=1024, fft_rate=15, average=True, avg_alpha=None, title="RTL Output", peak_hold=False, ) self.Add(self.fftsink.win) self.fftsink2 = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=options.freq+options.calibration, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=250e3, fft_size=1024, fft_rate=15, average=True, avg_alpha=None, title="Decoder input (After the filters)", peak_hold=False, ) self.Add(self.fftsink2.win) self.flex = pager.flex_demod(queue, options.freq, options.verbose, options.log) self.connect(self.u, self.chan, self.flex) if self.fft_enable: self.connect(self.u, self.fftsink) self.connect(self.chan, self.fftsink2)
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-c", "--calibration", type="eng_float", default=0, help="freq offset") parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file") parser.add_option("-l", "--log", action="store_true", default=False, help="dump debug .dat files") parser.add_option("-L", "--low-pass", type="eng_float", default=25e3, help="low pass cut-off", metavar="Hz") parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file") parser.add_option("-s", "--sample-rate", type="int", default=100000000 / 512, help="input sample 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 = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps channel_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" % (sample_rate)) IN = blocks.file_source(gr.sizeof_gr_complex, options.input_file) DEMOD = cqpsk.cqpsk_demod(samples_per_symbol=sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_resampler_cc(0, r) self.connect(IN, FILTER, INTERPOLATOR, DEMOD, OUT)
def __init__(self, options, queue): grc_wxgui.top_block_gui.__init__(self, title="RTL FLEX reciever") self.options = options self.offset = 0.0 self.adj_time = time.time() self.verbose = options.verbose self.log = options.log self.fft_enable = options.fft # Set up rtl source self.u = osmosdr.source(args="%s" % (options.device)) #set Freq self.u.set_center_freq(options.freq + options.calibration, 0) # Grab 250 KHz of spectrum self.u.set_sample_rate(250e3) rate = self.u.get_sample_rate() if rate != 250e3: print "Unable to set required sample rate of 250 Ksps (got %f)" % rate sys.exit(1) #Set gain if options.rx_gain is None: grange = self.u.get_gain_range() options.rx_gain = float(grange.start() + grange.stop()) / 2.0 print "\nNo gain specified." print "Setting gain to %f (from [%f, %f])" % \ (options.rx_gain, grange.start(), grange.stop()) self.u.set_gain(options.rx_gain, 0) taps = optfir.low_pass(1.0, 250e3, 11000, 12500, 0.1, 60) self.chan = filter.freq_xlating_fir_filter_ccf(10, taps, 0.0, 250e3) if self.fft_enable: self.fftsink = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=options.freq + options.calibration, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=250e3, fft_size=1024, fft_rate=15, average=True, avg_alpha=None, title="RTL Output", peak_hold=False, ) self.Add(self.fftsink.win) self.fftsink2 = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=options.freq + options.calibration, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=250e3, fft_size=1024, fft_rate=15, average=True, avg_alpha=None, title="Decoder input (After the filters)", peak_hold=False, ) self.Add(self.fftsink2.win) self.flex = pager.flex_demod(queue, options.freq, options.verbose, options.log) self.connect(self.u, self.chan, self.flex) if self.fft_enable: self.connect(self.u, self.fftsink) self.connect(self.chan, self.fftsink2)
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) # station is the frequency to be received station = parseargs(argv[1:]) adc_rate = 64e6 #output sample rate of the ADC, 64Ms/s usrp_decim = 250 usrp_rate = adc_rate / usrp_decim # output sample rate of the usrp, 256 ks/s lpf_decim = 4 lpf_rate = usrp_rate / lpf_decim # 64 kHz # usrp is data source # tells which usrp board is used and what the dec rate is #src = usrp.source_c (0, usrp_decim) #Tell USRP what daughter board to use and displays name #(1,0) means side B, 1st channel - picks daughterboard #rx_subdev_spec = (1,0) #src.set_mux(usrp.determine_rx_mux_value(src,rx_subdev_spec)) #subdev = usrp.selected_subdev(src,rx_subdev_spec) #print "Using daughterboard",subdev.name() #sets the shift frequency of the ddc (on FPGA) Note: must be minus or FFT display is reversed JF 08-08-08 #src.set_rx_freq (0, -station) #Turn up USRP gain to maximum #g = subdev.gain_range() #subdev.set_gain(float(g[1])) # checks the actual shift frequency #actual_shift_freq =src.rx_freq(0) #this line is to allow playback without usrp actual_shift_freq = -710000 #print "Actual DDC shift frequency", actual_shift_freq #print "USRP gain ", float(g[1]) # set gain on USRP #src.set_pga(0,20) #defines a file to collect usrp output #am_usrp_sink = gr.file_sink(gr.sizeof_gr_complex, "am_usrp710.dat") #self.connect(src, am_usrp_sink) #defines the file to playback the usrp data from am_usrp_source = blocks.file_source(gr.sizeof_gr_complex, "am_usrp710.dat") # computes taps for LPF and creates channel filter with those taps channel_coeffs = optfir.low_pass( 1.0, # gain usrp_rate, # sampling rate 4.5e3, # low pass cutoff freq 5e3, # width of trans. band 0.1, #passband ripple 60) #stopband attenuation #set frequency shift for picking up other signals offset = 0 chan_filter = filter.freq_xlating_fir_filter_ccf( lpf_decim, channel_coeffs, offset, usrp_rate) # define a file to collect channel filter output and connect #chan_sink = gr.file_sink(gr.sizeof_gr_complex, "chan.dat") #self.connect(chan_filter, chan_sink) #create an automatic gain control (AGC) block with 1 second time constant decay .1 attack. my_agc = analog.agc2_cc(1.5e-4, 1.5e-5, 10, 1) # create a block to take the magnitude (envelope) of the AM Signal magblock = blocks.complex_to_mag() # define and connect a sink of collect the output of the magnitude block #mag_sink = gr.file_sink(gr.sizeof_float, "mag.dat") #self.connect(magblock, mag_sink) #create a volume control and collect data into a file volumecontrol = blocks.multiply_const_ff(.04) #volcont_sink = gr.file_sink(gr.sizeof_float, "volcont.dat") #self.connect(volumecontrol, volcont_sink) # compute FIR filter taps for audio filter audio_coeffs = optfir.low_pass( 1.0, # gain lpf_rate, # sampling rate 4.5e3, # edge of passband 5e3, # edge of stopband, 0.1, #passband ripple 60) # stopband ripple # create audio filter and a file for its output audio_filter = filter.fir_filter_fff(1, audio_coeffs) #audio_filt_sink = gr.file_sink(gr.sizeof_float, "audio_filt.dat") #self.connect(audio_filter, audio_filt_sink) # create a resampler to bring 64ks/s rate to 48ks/s for audio card and data file rsamp = filter.rational_resampler_fff(3, 4) #rsamp_sink = gr.file_sink(gr.sizeof_float, "rsamp.dat") #self.connect(rsamp, rsamp_sink) #create a sink representing the audio card audio_sink = audio.sink(int(48000)) # now wire it all together #use this line to receive from usrp #self.connect (src,chan_filter) #use this line to playback recorded data self.connect(am_usrp_source, chan_filter) self.connect(chan_filter, my_agc) self.connect(my_agc, magblock) self.connect(magblock, volumecontrol) self.connect(volumecontrol, audio_filter) self.connect(audio_filter, rsamp) self.connect(rsamp, (audio_sink, 0)) if 1: pre_demod = fftsink2.fft_sink_c(panel, title="USRP Output", ref_level=70, fft_size=512, sample_rate=usrp_rate) self.connect(am_usrp_source, pre_demod) vbox.Add(pre_demod.win, 1, wx.EXPAND) #Sets offset for floating pointer in FFT window pre_demod.win.set_baseband_freq(-actual_shift_freq) if False: post_demod = fftsink2.fft_sink_c(panel, title="Post Channel Filter", fft_size=256, sample_rate=lpf_rate) self.connect(chan_filter, post_demod) vbox.Add(post_demod.win, 1, wx.EXPAND) if False: post_filt = fftsink2.fft_sink_f(panel, title="Post Envelope Detector", fft_size=512, sample_rate=lpf_rate) self.connect(magblock, post_filt) vbox.Add(post_filt.win, 1, wx.EXPAND)
def graph(args): print os.getpid() nargs = len(args) if nargs == 2: infile = args[0] outfile = args[1] else: raise ValueError('usage: interp.py input_file output_file.ts\n') input_rate = 19.2e6 IF_freq = 5.75e6 tb = gr.top_block() # Read from input file srcf = blocks.file_source(gr.sizeof_short, infile) # Convert interleaved shorts (I,Q,I,Q) to complex is2c = blocks.interleaved_short_to_complex() # 1/2 as wide because we're designing lp filter symbol_rate = atsc.ATSC_SYMBOL_RATE / 2. NTAPS = 279 tt = filter.firdes.root_raised_cosine(1.0, input_rate / 3, symbol_rate, .1152, NTAPS) rrc = filter.fir_filter_ccf(1, tt) # Interpolate Filter our 6MHz wide signal centered at 0 ilp_coeffs = filter.firdes.low_pass(1, input_rate, 3.2e6, .5e6, filter.firdes.WIN_HAMMING) ilp = filter.interp_fir_filter_ccf(3, ilp_coeffs) # Move the center frequency to 5.75MHz ( this won't be needed soon ) duc_coeffs = filter.firdes.low_pass(1, 19.2e6, 9e6, 1e6, filter.firdes.WIN_HAMMING) duc = filter.freq_xlating_fir_filter_ccf(1, duc_coeffs, -5.75e6, 19.2e6) # fpll input is float c2f = blocks.complex_to_float() # Phase locked loop fpll = atsc.fpll() # Clean fpll output lp_coeffs2 = filter.firdes.low_pass(1.0, input_rate, 5.75e6, 120e3, filter.firdes.WIN_HAMMING) lp_filter = filter.fir_filter_fff(1, lp_coeffs2) # Remove pilot ( at DC now ) iir = filter.single_pole_iir_filter_ff(1e-5) remove_dc = blocks.sub_ff() # Bit Timing Loop, Field Sync Checker and Equalizer btl = atsc.bit_timing_loop() fsc = atsc.fs_checker() eq = atsc.equalizer() fsd = atsc.field_sync_demux() # Viterbi viterbi = atsc.viterbi_decoder() deinter = atsc.deinterleaver() rs_dec = atsc.rs_decoder() derand = atsc.derandomizer() depad = atsc.depad() # Write to output file outf = blocks.file_sink(gr.sizeof_char, outfile) # Connect it all together tb.connect(srcf, is2c, rrc, ilp, duc, c2f, fpll, lp_filter) tb.connect(lp_filter, iir) tb.connect(lp_filter, (remove_dc, 0)) tb.connect(iir, (remove_dc, 1)) tb.connect(remove_dc, btl) tb.connect((btl, 0), (fsc, 0), (eq, 0), (fsd, 0)) tb.connect((btl, 1), (fsc, 1), (eq, 1), (fsd, 1)) tb.connect(fsd, viterbi, deinter, rs_dec, derand, depad, outf) tb.run()
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") options = get_options() self.tune_corrector_callback = tune_corrector(self) self.synchronizer_callback = synchronizer(self) self.converter = blocks.vector_to_stream(gr.sizeof_float, 142) self.ifreq = options.frequency self.rfgain = options.gain self.src = osmosdr.source(options.args) # added by scateu @ 2014-1-9 self.src.set_freq_corr(0, 0) self.src.set_dc_offset_mode(1, 0) self.src.set_iq_balance_mode(0, 0) self.src.set_gain_mode(0, 0) self.src.set_gain(14, 0) self.src.set_if_gain(58, 0) self.src.set_bb_gain(20, 0) self.src.set_antenna("", 0) self.src.set_bandwidth(0, 0) self.src.set_center_freq(self.ifreq) self.src.set_sample_rate(int(options.sample_rate)) if self.rfgain is None: self.src.set_gain_mode(1) self.iagc = 1 self.rfgain = 0 else: self.iagc = 0 self.src.set_gain_mode(0) self.src.set_gain(self.rfgain) # may differ from the requested rate sample_rate = self.src.get_sample_rate() sys.stderr.write("sample rate: %d\n" % (sample_rate)) gsm_symb_rate = 1625000.0 / 6.0 sps = sample_rate / gsm_symb_rate / 4 out_sample_rate = gsm_symb_rate * 4 self.offset = 0 taps = firdes.low_pass(1.0, sample_rate, 145e3, 10e3, firdes.WIN_HANN) self.tuner = freq_xlating_fir_filter_ccf(1, taps, self.offset, sample_rate) self.interpolator = fractional_interpolator_cc(0, sps) self.receiver = gsm.receiver_cf(self.tune_corrector_callback, self.synchronizer_callback, 4, options.key.replace(' ', '').lower(), options.configuration.upper()) self.output = blocks.file_sink(gr.sizeof_float, options.output_file) self.connect(self.src, self.tuner, self.interpolator, self.receiver, self.converter, self.output) def set_ifreq(ifreq): self.ifreq = ifreq self._ifreq_text_box.set_value(self.ifreq) self.src.set_center_freq(self.ifreq) self._ifreq_text_box = forms.text_box( parent=self.GetWin(), value=self.ifreq, callback=set_ifreq, label="Center Frequency", converter=forms.float_converter(), ) self.Add(self._ifreq_text_box) def set_iagc(iagc): self.iagc = iagc self._agc_check_box.set_value(self.iagc) self.src.set_gain_mode(self.iagc, 0) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) self._agc_check_box = forms.check_box( parent=self.GetWin(), value=self.iagc, callback=set_iagc, label="Automatic Gain", true=1, false=0, ) self.Add(self._agc_check_box) def set_rfgain(rfgain): self.rfgain = rfgain self._rfgain_slider.set_value(self.rfgain) self._rfgain_text_box.set_value(self.rfgain) self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0) _rfgain_sizer = wx.BoxSizer(wx.VERTICAL) self._rfgain_text_box = forms.text_box( parent=self.GetWin(), sizer=_rfgain_sizer, value=self.rfgain, callback=set_rfgain, label="RF Gain", converter=forms.float_converter(), proportion=0, ) self._rfgain_slider = forms.slider( parent=self.GetWin(), sizer=_rfgain_sizer, value=self.rfgain, callback=set_rfgain, minimum=0, maximum=50, num_steps=200, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_rfgain_sizer) def fftsink2_callback(x, y): if abs(x / (sample_rate / 2)) > 0.9: set_ifreq(self.ifreq + x / 2) else: sys.stderr.write("coarse tuned to: %d Hz\n" % x) self.offset = -x self.tuner.set_center_freq(self.offset) self.scope = fftsink2.fft_sink_c( self.GetWin(), title="Wideband Spectrum (click to coarse tune)", fft_size=1024, sample_rate=sample_rate, ref_scale=2.0, ref_level=0, y_divs=10, fft_rate=10, average=False, avg_alpha=0.3) self.Add(self.scope.win) self.scope.set_callback(fftsink2_callback) self.connect(self.src, self.scope) def fftsink2_callback2(x, y): self.offset = self.offset - (x / 10) sys.stderr.write("fine tuned to: %d Hz\n" % self.offset) self.tuner.set_center_freq(self.offset) self.scope2 = fftsink2.fft_sink_c( self.GetWin(), title="Channel Spectrum (click to fine tune)", fft_size=1024, sample_rate=gsm_symb_rate * 4, ref_scale=2.0, ref_level=-20, y_divs=10, fft_rate=10, average=False, avg_alpha=0.3) self.Add(self.scope2.win) self.scope2.set_callback(fftsink2_callback2) self.connect(self.interpolator, self.scope2)
def __init__(self, antenna=satnogs.not_set_antenna, baudrate=1200, bb_gain=satnogs.not_set_rx_bb_gain, cw_offset=1500, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=20, enable_iq_dump=0, file_path='test.ogg', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=100e6, rx_sdr_device='rtlsdr', udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat'): gr.top_block.__init__(self, "BPSK Decoder") ################################################## # Parameters ################################################## self.antenna = antenna self.baudrate = baudrate self.bb_gain = bb_gain self.cw_offset = cw_offset self.decoded_data_file_path = decoded_data_file_path self.dev_args = dev_args self.doppler_correction_per_sec = doppler_correction_per_sec self.enable_iq_dump = enable_iq_dump self.file_path = file_path self.if_gain = if_gain self.iq_file_path = iq_file_path self.lo_offset = lo_offset self.ppm = ppm self.rf_gain = rf_gain self.rigctl_port = rigctl_port self.rx_freq = rx_freq self.rx_sdr_device = rx_sdr_device self.udp_IP = udp_IP self.udp_port = udp_port self.waterfall_file_path = waterfall_file_path ################################################## # Variables ################################################## self.samp_rate_rx = samp_rate_rx = satnogs.hw_rx_settings[ rx_sdr_device]['samp_rate'] self.samp_per_sym = samp_per_sym = 5 self.nfilts = nfilts = 16 self.xlate_filter_taps = xlate_filter_taps = firdes.low_pass( 1, samp_rate_rx, 125000, 25000, firdes.WIN_HAMMING, 6.76) self.taps = taps = firdes.low_pass(12.0, samp_rate_rx, 100e3, 60000, firdes.WIN_HAMMING, 6.76) self.rrc_taps = rrc_taps = firdes.root_raised_cosine( nfilts, nfilts, 1.0 / float(samp_per_sym), 0.35, 11 * samp_per_sym * nfilts) self.filter_rate = filter_rate = 250000 self.filt_mode = filt_mode = 0.1 self.deviation = deviation = 5000 self.audio_samp_rate = audio_samp_rate = 48000 self.alpha = alpha = 0.1 ################################################## # Blocks ################################################## self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink( max(12000, int(3 * (1 + alpha) * baudrate)), 0.0, 10, 1024, waterfall_file_path, 1) self.satnogs_udp_msg_sink_0_0 = satnogs.udp_msg_sink( udp_IP, udp_port, 1500) self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source( "127.0.0.1", rigctl_port, False, 1000 / doppler_correction_per_sec, 1500) self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder( file_path, audio_samp_rate, 1.0) self.satnogs_iq_sink_0 = satnogs.iq_sink(32767, iq_file_path, False, enable_iq_dump) self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink( decoded_data_file_path, 0) self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc( rx_freq, samp_rate_rx) self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm( 'GND', 0, True, False, 1024) self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm( 'GND', 0, True, True, 1024) self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + satnogs.handle_rx_dev_args(rx_sdr_device, dev_args)) self.osmosdr_source_0.set_sample_rate(samp_rate_rx) self.osmosdr_source_0.set_center_freq(rx_freq - lo_offset, 0) self.osmosdr_source_0.set_freq_corr(ppm, 0) self.osmosdr_source_0.set_dc_offset_mode(2, 0) self.osmosdr_source_0.set_iq_balance_mode(0, 0) self.osmosdr_source_0.set_gain_mode(False, 0) self.osmosdr_source_0.set_gain( satnogs.handle_rx_rf_gain(rx_sdr_device, rf_gain), 0) self.osmosdr_source_0.set_if_gain( satnogs.handle_rx_if_gain(rx_sdr_device, if_gain), 0) self.osmosdr_source_0.set_bb_gain( satnogs.handle_rx_bb_gain(rx_sdr_device, bb_gain), 0) self.osmosdr_source_0.set_antenna( satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(samp_rate_rx, 0) self.low_pass_filter_0 = filter.fir_filter_ccf( 1, firdes.low_pass(1, audio_samp_rate, (1 + alpha) * baudrate, ((1 + alpha) * baudrate) * filt_mode, firdes.WIN_HAMMING, 6.76)) self.freq_xlating_fir_filter_xxx_0_0 = filter.freq_xlating_fir_filter_ccf( audio_samp_rate / (samp_per_sym * baudrate), (firdes.low_pass(1, audio_samp_rate, (1 + alpha) * baudrate, (1 + alpha) * baudrate * filt_mode)), cw_offset / 1200.0 * baudrate, audio_samp_rate) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc( int(samp_rate_rx / filter_rate), (xlate_filter_taps), lo_offset, samp_rate_rx) self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf( samp_per_sym, 0.063, (rrc_taps), nfilts, nfilts / 2, 1.5, 1) self.digital_costas_loop_cc_0_0_0_0 = digital.costas_loop_cc( 0.063, 2, False) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.blocks_multiply_xx_0_0 = blocks.multiply_vcc(1) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) self.blocks_complex_to_real_0_0 = blocks.complex_to_real(1) self.blocks_complex_to_real_0 = blocks.complex_to_real(1) self.blks2_rational_resampler_xxx_1_0 = filter.rational_resampler_ccc( interpolation=max(12000, int(3 * (1 + alpha) * baudrate)), decimation=48000, taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_1 = filter.rational_resampler_ccc( interpolation=audio_samp_rate, decimation=int(samp_rate_rx / (samp_rate_rx / filter_rate)), taps=None, fractional_bw=None, ) self.analog_sig_source_x_0 = analog.sig_source_c( audio_samp_rate, analog.GR_COS_WAVE, cw_offset / 1200.0 * baudrate, 1, 0) self.analog_agc2_xx_0_0 = analog.agc2_cc(0.01, 0.001, 0.015, 0.0) self.analog_agc2_xx_0_0.set_max_gain(65536) self.analog_agc2_xx_0 = analog.agc2_cc(0.01, 0.001, 0.5, 1.0) self.analog_agc2_xx_0.set_max_gain(65536) ################################################## # Connections ################################################## self.msg_connect((self.satnogs_ax25_decoder_bm_0, 'pdu'), (self.satnogs_frame_file_sink_0_1_0, 'frame')) self.msg_connect((self.satnogs_ax25_decoder_bm_0, 'pdu'), (self.satnogs_udp_msg_sink_0_0, 'in')) self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_frame_file_sink_0_1_0, 'frame')) self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_udp_msg_sink_0_0, 'in')) self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) self.connect((self.analog_agc2_xx_0, 0), (self.digital_pfb_clock_sync_xxx_0, 0)) self.connect((self.analog_agc2_xx_0_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.blks2_rational_resampler_xxx_1_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.blocks_multiply_xx_0_0, 1)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.low_pass_filter_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1_0, 0), (self.satnogs_waterfall_sink_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.satnogs_ogg_encoder_0, 0)) self.connect((self.blocks_complex_to_real_0_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.blocks_complex_to_real_0, 0)) self.connect((self.blocks_multiply_xx_0_0, 0), (self.freq_xlating_fir_filter_xxx_0_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) self.connect((self.digital_costas_loop_cc_0_0_0_0, 0), (self.blocks_complex_to_real_0_0, 0)) self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.digital_costas_loop_cc_0_0_0_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0_0, 0), (self.analog_agc2_xx_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_agc2_xx_0_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0))
def __init__(self, options): gr.top_block.__init__(self) fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) self._u = usrp.source_c(decim_rate=options.decim, fusb_block_size=fusb_block_size, fusb_nblocks=fusb_nblocks) # master clock if options.fpga_freq is not None: self._u.set_fpga_master_clock_freq(long(options.fpga_freq)) # default subdev if use didn't pick one if options.rx_subdev_spec is None: if u.db(0, 0).dbid() >= 0: options.rx_subdev_spec = (0, 0) elif u.db(1, 0).dbid() >= 0: options.rx_subdev_spec = (1, 0) else: options.rx_subdev_spec = (0, 0) # configure usrp mux self._u.set_mux(usrp.determine_rx_mux_value(self._u, options.rx_subdev_spec)) # determine the daughterboard subdevice self.subdev = usrp.selected_subdev(self._u, options.rx_subdev_spec) # select antenna if options.antenna is not None: print "Selecting antenna %s" % (options.antenna,) self.subdev.select_rx_antenna(options.antenna) # set initial values if options.gain is None: # if no gain was specified, use the mid-point in dB g = self.subdev.gain_range() options.gain = float(g[0]+g[1])/2 r = self._u.tune(0, self.subdev, options.freq) self.subdev.set_gain(options.gain) #sample_rate = options.fpga_clock/options.decim sample_rate = self._u.adc_freq() / self._u.decim_rate() symbol_rate = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps channel_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" %(sample_rate)) DEMOD = cqpsk.cqpsk_demod( samples_per_symbol = sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_resampler_cc(0, r) self.connect(self._u, FILTER, INTERPOLATOR, DEMOD, OUT)
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("-a", "--args", type="string", default="", help="UHD device address args [default=%default]") parser.add_option("", "--spec", type="string", default=None, help="Subdevice of UHD device where appropriate") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option( "-s", "--samp-rate", type="eng_float", default=1e6, help="set sample rate (bandwidth) [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=1008.0e3, help="set frequency to FREQ", metavar="FREQ") parser.add_option( "-I", "--use-if-freq", action="store_true", default=False, help= "use intermediate freq (compensates DC problems in quadrature boards)" ) parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is maximum)") parser.add_option("-V", "--volume", type="eng_float", default=None, help="set volume (default is midpoint)") parser.add_option( "-O", "--audio-output", type="string", default="default", help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.frame = frame self.panel = panel self.use_IF = options.use_if_freq if self.use_IF: self.IF_freq = 64000.0 else: self.IF_freq = 0.0 self.vol = 0 self.state = "FREQ" self.freq = 0 # build graph self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32')) # Set the subdevice spec if (options.spec): self.u.set_subdev_spec(options.spec, 0) # Set the antenna if (options.antenna): self.u.set_antenna(options.antenna, 0) usrp_rate = 256e3 demod_rate = 64e3 audio_rate = 32e3 chanfilt_decim = int(usrp_rate // demod_rate) audio_decim = int(demod_rate // audio_rate) self.u.set_samp_rate(usrp_rate) dev_rate = self.u.get_samp_rate() # Resample signal to exactly self.usrp_rate # FIXME: make one of the follow-on filters an arb resampler rrate = usrp_rate / dev_rate self.resamp = filter.pfb.arb_resampler_ccf(rrate) chan_filt_coeffs = filter.firdes.low_pass_2( 1, # gain usrp_rate, # sampling rate 8e3, # passband cutoff 4e3, # transition bw 60) # stopband attenuation if self.use_IF: # Turn If to baseband and filter. self.chan_filt = filter.freq_xlating_fir_filter_ccf( chanfilt_decim, chan_filt_coeffs, self.IF_freq, usrp_rate) else: self.chan_filt = filter.fir_filter_ccf(chanfilt_decim, chan_filt_coeffs) self.agc = analog.agc_cc(0.1, 1, 1, 100000) self.am_demod = blocks.complex_to_mag() self.volume_control = blocks.multiply_const_ff(self.vol) audio_filt_coeffs = filter.firdes.low_pass_2( 1, # gain demod_rate, # sampling rate 8e3, # passband cutoff 2e3, # transition bw 60) # stopband attenuation self.audio_filt = filter.fir_filter_fff(audio_decim, audio_filt_coeffs) # sound card as final sink self.audio_sink = audio.sink(int(audio_rate), options.audio_output, False) # ok_to_block # now wire it all together self.connect(self.u, self.resamp, self.chan_filt, self.agc, self.am_demod, self.audio_filt, self.volume_control, self.audio_sink) self._build_gui(vbox, usrp_rate, demod_rate, audio_rate) if options.gain is None: g = self.u.get_gain_range() # if no gain was specified, use the mid gain options.gain = (g.start() + g.stop()) / 2.0 if options.volume is None: v = self.volume_range() options.volume = float(v[0] * 3 + v[1]) / 4.0 if abs(options.freq) < 1e3: options.freq *= 1e3 # set initial values self.set_gain(options.gain) self.set_vol(options.volume) if not (self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency")
def __init__(self): gr.top_block.__init__(self, "DSRC RSU Receiver") Qt.QWidget.__init__(self) self.setWindowTitle("DSRC RSU Receiver") try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "rsu_receiver") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.symbol_per_second = symbol_per_second = 250e3 self.samp_per_symb = samp_per_symb = 20 self.usrp_samples_per_second = usrp_samples_per_second = 100e6 self.input_rate = input_rate = int(samp_per_symb * symbol_per_second) self.subcarrier_freq = subcarrier_freq = 1.5e6 self.lowpass_coeff = lowpass_coeff = firdes.low_pass( 1.0, input_rate, 100e3, 100e3, firdes.WIN_HAMMING, 6.76) self.gain = gain = 1.0 self.decimation_rate = decimation_rate = int(usrp_samples_per_second / input_rate) ################################################## # Blocks ################################################## self._subcarrier_freq_tool_bar = Qt.QToolBar(self) self._subcarrier_freq_tool_bar.addWidget( Qt.QLabel('Subcarrier frequency' + ": ")) self._subcarrier_freq_line_edit = Qt.QLineEdit( str(self.subcarrier_freq)) self._subcarrier_freq_tool_bar.addWidget( self._subcarrier_freq_line_edit) self._subcarrier_freq_line_edit.returnPressed.connect( lambda: self.set_subcarrier_freq( eng_notation.str_to_num( str(self._subcarrier_freq_line_edit.text().toAscii())))) self.top_layout.addWidget(self._subcarrier_freq_tool_bar) self.usrp_source = uhd.usrp_source( ",".join(("", "")), uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.usrp_source.set_samp_rate(input_rate) self.usrp_source.set_center_freq(5.8e9, 0) self.usrp_source.set_gain(gain, 0) self.usrp_source.set_antenna('RX2', 0) self.qtgui_time_sink_x_0 = qtgui.time_sink_c( 256, #size input_rate, #samp_rate "", #name 1 #number of inputs ) self.qtgui_time_sink_x_0.set_update_time(0.10) self.qtgui_time_sink_x_0.set_y_axis(-1, 1) self.qtgui_time_sink_x_0.set_y_label('Amplitude', "") self.qtgui_time_sink_x_0.enable_tags(-1, True) self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_0.enable_autoscale(True) self.qtgui_time_sink_x_0.enable_grid(False) self.qtgui_time_sink_x_0.enable_axis_labels(True) self.qtgui_time_sink_x_0.enable_control_panel(False) if not True: self.qtgui_time_sink_x_0.disable_legend() labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue" ] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(2 * 1): if len(labels[i]) == 0: if (i % 2 == 0): self.qtgui_time_sink_x_0.set_line_label( i, "Re{{Data {0}}}".format(i / 2)) else: self.qtgui_time_sink_x_0.set_line_label( i, "Im{{Data {0}}}".format(i / 2)) else: self.qtgui_time_sink_x_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_win = sip.wrapinstance( self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_time_sink_x_0_win) self.file_sink = blocks.file_sink(gr.sizeof_char * gr.sizeof_char, 'binary_nrz_data', False) self.file_sink.set_unbuffered(False) self.dsrcmod_nrzi_to_nrz_bb_0 = dsrcmod.nrzi_to_nrz_bb(1) self.digital_mpsk_receiver_cc_0 = digital.mpsk_receiver_cc( 2, 0, cmath.pi / 100.0, -0.00393, 0.00393, 0.5, 0.05, samp_per_symb, (samp_per_symb * samp_per_symb) / 4, 0.005) self.complex_to_real = blocks.complex_to_real(1) self.channel_filter = filter.freq_xlating_fir_filter_ccf( 1, (lowpass_coeff), 5.8e9 + subcarrier_freq, input_rate) self.binary_slicer = digital.binary_slicer_fb() ################################################## # Connections ################################################## self.connect((self.binary_slicer, 0), (self.dsrcmod_nrzi_to_nrz_bb_0, 0)) self.connect((self.channel_filter, 0), (self.digital_mpsk_receiver_cc_0, 0)) self.connect((self.complex_to_real, 0), (self.binary_slicer, 0)) self.connect((self.digital_mpsk_receiver_cc_0, 0), (self.complex_to_real, 0)) self.connect((self.dsrcmod_nrzi_to_nrz_bb_0, 0), (self.file_sink, 0)) self.connect((self.usrp_source, 0), (self.channel_filter, 0)) self.connect((self.usrp_source, 0), (self.qtgui_time_sink_x_0, 0))
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel options = get_options() sample_rate = int(options.sample_rate) self.asrc = audio.source(sample_rate, options.audio_device, True) self.f2c = blocks.float_to_complex(1) self.connect((self.asrc, 1), (self.f2c, 1)) self.connect((self.asrc, 0), (self.f2c, 0)) symbol_rate = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps channel_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" % (sample_rate)) DEMOD = cqpsk.cqpsk_demod(samples_per_symbol=sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_resampler_cc(0, r) self.connect(self.f2c, FILTER, INTERPOLATOR, DEMOD, OUT) self.scope = fftsink2.fft_sink_c(panel, fft_size=512, sample_rate=sample_rate, ref_scale=2.0, ref_level=-30, y_divs=10, fft_rate=10, average=True, avg_alpha=0.2) self.connect(self.f2c, self.scope)
def __init__(self, options): gr.top_block.__init__(self) # Create a UHD source self._u = uhd.usrp_source(device_addr=options.args, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) # Set the subdevice spec if (options.spec): self._u.set_subdev_spec(options.spec, 0) # Set the antenna if (options.antenna): self._u.set_antenna(options.antenna, 0) # Pick the lowest possible value for the input rate supported_rates = self._u.get_samp_rates() self._u.set_samp_rate(supported_rates.start()) sample_rate = self._u.get_samp_rate() symbol_rate = 18000 sps = 2 # output rate will be 36,000 ntaps = 11 * sps new_sample_rate = symbol_rate * sps # Set receive daughterboard gain if options.gain is None: g = self._u.get_gain_range() options.gain = float(g.stop() + g.start()) / 2 print "Using mid-point gain of", options.gain, "(", g.start( ), "-", g.stop(), ")" self._u.set_gain(options.gain) # Set frequency (tune request takes lo_offset) if (options.lo_offset is not None): treq = uhd.tune_request(options.freq, options.lo_offset) else: treq = uhd.tune_request(options.freq) tr = self._u.set_center_freq(treq) if tr == None: sys.stderr.write('Failed to set center frequency\n') raise SystemExit, 1 channel_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) FILTER = filter.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) sys.stderr.write("sample rate: %d\n" % (sample_rate)) DEMOD = cqpsk.cqpsk_demod(samples_per_symbol=sps, excess_bw=0.35, costas_alpha=0.03, gain_mu=0.05, mu=0.05, omega_relative_limit=0.05, log=options.log, verbose=options.verbose) OUT = blocks.file_sink(gr.sizeof_float, options.output_file) r = float(sample_rate) / float(new_sample_rate) INTERPOLATOR = filter.fractional_resampler_cc(0, r) self.connect(self._u, FILTER, INTERPOLATOR, DEMOD, OUT)