def build_pipeline(fg, quad_rate, audio_decimation): '''Given a flow_graph, fg, construct a pipeline for demodulating a broadcast FM signal. The input is the downconverteed complex baseband signal. The output is the demodulated audio. build_pipeline returns a two element tuple containing the input and output endpoints. ''' fm_demod_gain = 2200.0 / 32768.0 audio_rate = quad_rate / audio_decimation volume = 1.0 # input: complex; output: float fm_demod = gr.quadrature_demod_cf(volume * fm_demod_gain) # compute FIR filter taps for audio filter width_of_transition_band = audio_rate / 32 audio_coeffs = gr.firdes.low_pass( 1.0, # gain quad_rate, # sampling rate audio_rate / 2 - width_of_transition_band, width_of_transition_band, gr.firdes.WIN_HAMMING) # input: float; output: float audio_filter = gr.fir_filter_fff(audio_decimation, audio_coeffs) fg.connect(fm_demod, audio_filter) return ((fm_demod, 0), (audio_filter, 0))
def __init__(self): gr.top_block.__init__(self) input_sample_rate = 1e6 symbol_rate = 152.34e3 output_samples_per_symbol = 5 output_sample_rate = output_samples_per_symbol * symbol_rate # least common multiple lcm = gru.lcm(input_sample_rate, output_sample_rate) intrp = int(lcm // input_sample_rate) decim = int(lcm // output_sample_rate) print intrp print decim resampler = blks2.rational_resampler_ccc(intrp, decim, None, None) src = gr.file_source(gr.sizeof_gr_complex, "infile") sink = gr.file_sink(gr.sizeof_float, "outfile") f2c = gr.float_to_complex() c2r = gr.complex_to_real() #ddc_coeffs = \ #gr.firdes.low_pass (1.0, # gain #input_sample_rate, # sampling rate #2e3, # low pass cutoff freq #6e3, # width of trans. band #gr.firdes.WIN_HANN) # just grab the lower sideband: #ddc = gr.freq_xlating_fir_filter_ccf(1,ddc_coeffs,-111.5e3,input_sample_rate) qdemod = gr.quadrature_demod_cf(1.0) lp_coeffs = \ gr.firdes.low_pass (1.0, # gain output_sample_rate, # sampling rate symbol_rate, # low pass cutoff freq symbol_rate, # width of trans. band gr.firdes.WIN_HANN) lp = gr.fir_filter_fff (1,lp_coeffs) self.connect(src,resampler,qdemod,lp,sink)
def __init__(self, fg, audio_rate, quad_rate, tau=75e-6, max_dev=5e3): """ Narrow Band FM Receiver. Takes a single complex baseband input stream and produces a single float output stream of audio sample in the range [-1, +1]. @param fg: flow graph @param audio_rate: sample rate of audio stream, >= 16k @type audio_rate: integer @param quad_rate: sample rate of output stream @type quad_rate: integer @param tau: preemphasis time constant (default 75e-6) @type tau: float @param max_dev: maximum deviation in Hz (default 5e3) @type max_dev: float quad_rate must be an integer multiple of audio_rate. Exported sub-blocks (attributes): squelch quad_demod deemph audio_filter """ # FIXME audio_rate and quad_rate ought to be exact rationals audio_rate = int(audio_rate) quad_rate = int(quad_rate) if quad_rate % audio_rate != 0: raise ValueError, "quad_rate is not an integer multiple of audio_rate" squelch_threshold = 20 # dB #self.squelch = gr.simple_squelch_cc(squelch_threshold, 0.001) # FM Demodulator input: complex; output: float k = quad_rate/(2*math.pi*max_dev) self.quad_demod = gr.quadrature_demod_cf(k) # FM Deemphasis IIR filter self.deemph = fm_deemph (fg, quad_rate, tau=tau) # compute FIR taps for audio filter audio_decim = quad_rate // audio_rate audio_taps = gr.firdes.low_pass (1.0, # gain quad_rate, # sampling rate 4.5e3, # Audio LPF cutoff 2.5e3, # Transition band gr.firdes.WIN_HAMMING) # filter type print "len(audio_taps) =", len(audio_taps) # Decimating audio filter # input: float; output: float; taps: float self.audio_filter = gr.fir_filter_fff(audio_decim, audio_taps) fg.connect(self.quad_demod, self.deemph, self.audio_filter) gr.hier_block.__init__(self, fg, self.quad_demod, self.audio_filter)
def __init__(self, fg, channel_rate, audio_decim, deviation, audio_pass, audio_stop, gain=1.0, tau=75e-6): """ # Equalizer for ~100 us delay delay = 100e-6 num_taps = int(channel_rate*delay) mu = 1e-4/num_taps print "CMA: delay =", delay, "n =", num_taps, "mu =", mu CMA = gr.cma_equalizer_cc(num_taps, 1.0, mu) """ k = channel_rate / (2 * pi * deviation) QUAD = gr.quadrature_demod_cf(k) audio_taps = optfir.low_pass( gain, # Filter gain channel_rate, # Sample rate audio_pass, # Audio passband audio_stop, # Audio stopband 0.1, # Passband ripple 60, ) # Stopband attenuation LPF = gr.fir_filter_fff(audio_decim, audio_taps) if tau is not None: DEEMPH = fm_deemph(fg, channel_rate, tau) fg.connect(QUAD, DEEMPH, LPF) else: fg.connect(QUAD, LPF) gr.hier_block.__init__(self, fg, QUAD, LPF)
def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq): gr.hier_block2.__init__(self, "rx_channel_fm", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps, lo_freq, usrp_rate) symbol_decim = 1 symbol_rate = 4800 self.symbol_deviation = 600.0 fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) fm_demod = gr.quadrature_demod_cf(fm_demod_gain) symbol_coeffs = gr.firdes_root_raised_cosine(1.0, channel_rate, symbol_rate, 1.0, 51) symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # C4FM demodulator autotuneq = gr.msg_queue(2) demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, symbol_rate) self.connect(self, chan, fm_demod, symbol_filter, demod_fsk4, self)
def __init__(self): gr.top_block.__init__(self) self.samp_rate = samp_rate = 1000000 self.dump_freq = dump_freq = 2400490000 self._u = uhd.usrp_source( device_addr="%default", io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) self._u.set_gain(0, 0) self._u.set_samp_rate(self.samp_rate) treq = uhd.tune_request(self.dump_freq, 0) tr = self._u.set_center_freq(treq) if tr == None: sys.stderr.write('Failed to set center frequency\n') raise SystemExit, 1 self.filter1 = gr.interp_fir_filter_ccf(1, firdes.low_pass(1, samp_rate, 500000, 10000, firdes.WIN_HAMMING, 6.76)) self.squelch = gr.pwr_squelch_cc(-100, 0.001, 0, True) self.demod = gr.quadrature_demod_cf(1) self.sync = digital.clock_recovery_mm_ff(2, 0.0076562, 0.5, 0.175, 0.005) self.slicer = digital.binary_slicer_fb() self.detect_seq = digital.correlate_access_code_bb("01010101010101010101010101010101", 1) self.dump = flysky.dumpsync() self.connect(self._u,self.filter1,self.squelch,self.demod,self.sync,self.slicer,self.detect_seq, self.dump)
def __init__(self): gr.top_block.__init__(self) input_sample_rate = 1e6 symbol_rate = 152.34e3 output_samples_per_symbol = 5 output_sample_rate = output_samples_per_symbol * symbol_rate # least common multiple lcm = gru.lcm(input_sample_rate, output_sample_rate) intrp = int(lcm // input_sample_rate) decim = int(lcm // output_sample_rate) print intrp print decim resampler = blks2.rational_resampler_ccc(intrp, decim, None, None) src = gr.file_source(gr.sizeof_gr_complex, "infile") sink = gr.file_sink(gr.sizeof_float, "outfile") f2c = gr.float_to_complex() c2r = gr.complex_to_real() #ddc_coeffs = \ #gr.firdes.low_pass (1.0, # gain #input_sample_rate, # sampling rate #2e3, # low pass cutoff freq #6e3, # width of trans. band #gr.firdes.WIN_HANN) # just grab the lower sideband: #ddc = gr.freq_xlating_fir_filter_ccf(1,ddc_coeffs,-111.5e3,input_sample_rate) qdemod = gr.quadrature_demod_cf(1.0) lp_coeffs = \ gr.firdes.low_pass (1.0, # gain output_sample_rate, # sampling rate symbol_rate, # low pass cutoff freq symbol_rate, # width of trans. band gr.firdes.WIN_HANN) lp = gr.fir_filter_fff(1, lp_coeffs) self.connect(src, resampler, qdemod, lp, sink)
def __init__(self, queue, freq=0.0, verbose=False, log=False): gr.hier_block2.__init__(self, "flex_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0, 0, 0)) k = 25000 / (2 * pi * 1600) # 4800 Hz max deviation quad = gr.quadrature_demod_cf(k) self.connect(self, quad) rsamp = blks2.rational_resampler_fff(16, 25) self.slicer = pager_swig.slicer_fb( 5e-6) # DC removal averaging filter constant self.sync = pager_swig.flex_sync() self.connect(quad, rsamp, self.slicer, self.sync) for i in range(4): self.connect((self.sync, i), pager_swig.flex_deinterleave(), pager_swig.flex_parse(queue, freq)) if log: suffix = '_' + "%3.3f" % (freq / 1e6, ) + '.dat' quad_sink = gr.file_sink(gr.sizeof_float, 'quad' + suffix) rsamp_sink = gr.file_sink(gr.sizeof_float, 'rsamp' + suffix) slicer_sink = gr.file_sink(gr.sizeof_char, 'slicer' + suffix) self.connect(rsamp, rsamp_sink) self.connect(quad, quad_sink) self.connect(self.slicer, slicer_sink)
def __init__(self, samplerate, symbolrate = SYMRATE, channel_str = None, sendmsg = True, debug = False, samplepersymbol = SPS, fmdeviation = FM_DEVIATION ): gr.hier_block2.__init__(self, "pocsag", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, 1)) self.samplerate = samplerate self.symbolrate = symbolrate self.sendmsg = sendmsg self.debug = debug self.samplepersymbol = samplepersymbol self.fmdeviation = fmdeviation self.fractional_interpolator = gr.fractional_interpolator_cc(0, 1.0 * samplerate / (symbolrate * samplepersymbol)) self.quadrature_demod = gr.quadrature_demod_cf((symbolrate * samplepersymbol) / (fmdeviation * 4.0)) self.low_pass_filter = gr.fir_filter_fff(1, gr.firdes.low_pass(1, symbolrate * samplepersymbol, symbolrate * 2, symbolrate / 2.0, gr.firdes.WIN_HAMMING, 6.76)) self.digital_clock_recovery_mm = digital.clock_recovery_mm_ff(samplepersymbol, 0.03 * 0.03 * 0.3, 0.4, 0.03, 1e-4) self.digital_binary_slicer_fb = digital.binary_slicer_fb() self.pktdecoder = pocsag_pktdecoder(channel_str = channel_str, sendmsg = sendmsg, debug = debug) self.connect(self, self.fractional_interpolator, self.quadrature_demod, self.low_pass_filter, self.digital_clock_recovery_mm, self.digital_binary_slicer_fb, self.pktdecoder, self)
def __init__(self, queue, freq=0.0, verbose=False, log=False): gr.hier_block2.__init__(self, "flex_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0,0,0)) k = 25000/(2*pi*1600) # 4800 Hz max deviation quad = gr.quadrature_demod_cf(k) self.connect(self, quad) rsamp = blks2.rational_resampler_fff(16, 25) self.slicer = pager_swig.slicer_fb(5e-6) # DC removal averaging filter constant self.sync = pager_swig.flex_sync() self.connect(quad, rsamp, self.slicer, self.sync) for i in range(4): self.connect((self.sync, i), pager_swig.flex_deinterleave(), pager_swig.flex_parse(queue, freq)) if log: suffix = '_'+ "%3.3f" % (freq/1e6,) + '.dat' quad_sink = gr.file_sink(gr.sizeof_float, 'quad'+suffix) rsamp_sink = gr.file_sink(gr.sizeof_float, 'rsamp'+suffix) slicer_sink = gr.file_sink(gr.sizeof_char, 'slicer'+suffix) self.connect(rsamp, rsamp_sink) self.connect(quad, quad_sink) self.connect(self.slicer, slicer_sink)
def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq): gr.hier_block2.__init__(self, "rx_channel_fm", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps, lo_freq, usrp_rate) symbol_decim = 1 symbol_rate = 4800 self.symbol_deviation = 600.0 fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) fm_demod = gr.quadrature_demod_cf(fm_demod_gain) symbol_coeffs = gr.firdes_root_raised_cosine(1.0, channel_rate, symbol_rate, 1.0, 51) symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # C4FM demodulator autotuneq = gr.msg_queue(2) demod_fsk4 = fsk4.demod_ff(autotuneq, channel_rate, symbol_rate) self.connect (self, chan, fm_demod, symbol_filter, demod_fsk4, self)
def build_pipeline (fg, quad_rate, audio_decimation): '''Given a flow_graph, fg, construct a pipeline for demodulating a broadcast FM signal. The input is the downconverteed complex baseband signal. The output is the demodulated audio. build_pipeline returns a two element tuple containing the input and output endpoints. ''' fm_demod_gain = 2200.0/32768.0 audio_rate = quad_rate / audio_decimation volume = 1.0 # input: complex; output: float fm_demod = gr.quadrature_demod_cf (volume*fm_demod_gain) # compute FIR filter taps for audio filter width_of_transition_band = audio_rate / 32 audio_coeffs = gr.firdes.low_pass (1.0, # gain quad_rate, # sampling rate audio_rate/2 - width_of_transition_band, width_of_transition_band, gr.firdes.WIN_HAMMING) # input: float; output: float audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) fg.connect (fm_demod, audio_filter) return ((fm_demod, 0), (audio_filter, 0))
def __init__(self, input_path, sample_rate, output_path): gr.top_block.__init__(self) # We don't use the existing NBFM demodulator block because it # contains a lowpass output filter which is unsuitable for 9600 # GMSK (it's designed for voice). self.source = gr.file_source(gr.sizeof_gr_complex * 1, input_path, False) self.low_pass_filter = gr.fir_filter_ccf( 4, firdes.low_pass(1, sample_rate, 15000, 100, firdes.WIN_HAMMING, 6.76) ) # High pass filter to remove the DC component. This is important # when the signal is near the SDR's local oscillator. # NOTE(tstranex): Disabled since we are now shifting the FCD # center frequency instead. # self.high_pass_filter = gr.fir_filter_ccf(1, firdes.high_pass( # 1, sample_rate/4, 100, 100, firdes.WIN_HAMMING, 6.76)) self.quadrature_demod = gr.quadrature_demod_cf(sample_rate / 4 / (2 * 3.14 * 3000)) self.fm_deemph = blks2.fm_deemph(fs=sample_rate / 4, tau=75e-6) self.boost_volume = gr.multiply_const_vff((1.52,)) self.sink = gr.wavfile_sink(output_path, 1, sample_rate / 4, 16) self.connect((self.source, 0), (self.low_pass_filter, 0)) # self.connect((self.low_pass_filter, 0), (self.high_pass_filter, 0)) # self.connect((self.high_pass_filter, 0), (self.quadrature_demod, 0)) self.connect((self.low_pass_filter, 0), (self.quadrature_demod, 0)) self.connect((self.quadrature_demod, 0), (self.fm_deemph, 0)) self.connect((self.fm_deemph, 0), (self.boost_volume, 0)) self.connect((self.boost_volume, 0), (self.sink, 0))
def __init__(self, input_path, sample_rate, output_path): gr.top_block.__init__(self) # We don't use the existing NBFM demodulator block because it # contains a lowpass output filter which is unsuitable for 9600 # GMSK (it's designed for voice). self.source = gr.file_source(gr.sizeof_gr_complex * 1, input_path, False) self.low_pass_filter = gr.fir_filter_ccf( 4, firdes.low_pass(1, sample_rate, 15000, 100, firdes.WIN_HAMMING, 6.76)) # High pass filter to remove the DC component. This is important # when the signal is near the SDR's local oscillator. # NOTE(tstranex): Disabled since we are now shifting the FCD # center frequency instead. #self.high_pass_filter = gr.fir_filter_ccf(1, firdes.high_pass( # 1, sample_rate/4, 100, 100, firdes.WIN_HAMMING, 6.76)) self.quadrature_demod = gr.quadrature_demod_cf(sample_rate / 4 / (2 * 3.14 * 3000)) self.fm_deemph = blks2.fm_deemph(fs=sample_rate / 4, tau=75e-6) self.boost_volume = gr.multiply_const_vff((1.52, )) self.sink = gr.wavfile_sink(output_path, 1, sample_rate / 4, 16) self.connect((self.source, 0), (self.low_pass_filter, 0)) #self.connect((self.low_pass_filter, 0), (self.high_pass_filter, 0)) #self.connect((self.high_pass_filter, 0), (self.quadrature_demod, 0)) self.connect((self.low_pass_filter, 0), (self.quadrature_demod, 0)) self.connect((self.quadrature_demod, 0), (self.fm_deemph, 0)) self.connect((self.fm_deemph, 0), (self.boost_volume, 0)) self.connect((self.boost_volume, 0), (self.sink, 0))
def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq, max_dev, ctcss): gr.hier_block2.__init__(self, "rx_channel_nfm", gr.io_signature(1, 1, gr.sizeof_gr_complex), # gr.io_signature(0, 0, 0)) gr.io_signature(1, 1, gr.sizeof_float)) output_sample_rate = 8000 chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps, lo_freq, usrp_rate) nphases = 32 frac_bw = 0.45 rs_taps = gr.firdes.low_pass(nphases, nphases, frac_bw, 0.5-frac_bw) resampler = blks2.pfb_arb_resampler_ccf( float(output_sample_rate)/channel_rate, (rs_taps), nphases ) # FM Demodulator input: complex; output: float k = output_sample_rate/(2*math.pi*max_dev) fm_demod = gr.quadrature_demod_cf(k) self.connect (self, chan, resampler, fm_demod) if ctcss > 0: level = 5.0 len = 0 ramp = 0 gate = True ctcss = repeater.ctcss_squelch_ff(output_sample_rate, ctcss, level, len, ramp, gate) self.connect (fm_demod, ctcss, self) else: self.connect (fm_demod, self)
def __init__(self, channel_rate, audio_decim, deviation, audio_pass, audio_stop, gain=1.0, tau=75e-6): gr.hier_block2.__init__( self, "fm_demod_cf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature k = channel_rate / (2 * pi * deviation) QUAD = gr.quadrature_demod_cf(k) audio_taps = optfir.low_pass( gain, # Filter gain channel_rate, # Sample rate audio_pass, # Audio passband audio_stop, # Audio stopband 0.1, # Passband ripple 60) # Stopband attenuation LPF = gr.fir_filter_fff(audio_decim, audio_taps) if tau is not None: DEEMPH = fm_deemph(channel_rate, tau) self.connect(self, QUAD, DEEMPH, LPF, self) else: self.connect(self, QUAD, LPF, self)
def _setup_top_block(self): self.tb = gr.top_block() samp_rate = 96000 oversample = 10 center_freq = 868.280e6 # Radio receiver, initial downsampling args = str("nchan=1 rtl=%s,buffers=16,offset_tune=1" % self.device) osmosdr_source = osmosdr.source_c(args=args) osmosdr_source.set_sample_rate(samp_rate*oversample) osmosdr_source.set_center_freq(center_freq, 0) osmosdr_source.set_freq_corr(0, 0) osmosdr_source.set_gain_mode(1, 0) osmosdr_source.set_gain(0, 0) low_pass_filter = gr.fir_filter_ccf(oversample, firdes.low_pass(1, samp_rate*oversample, 90e3, 8e3, firdes.WIN_HAMMING, 6.76)) self.tb.connect((osmosdr_source, 0), (low_pass_filter, 0)) # Squelch self.noise_probe = gr.probe_avg_mag_sqrd_c(0, 1.0/samp_rate/1e2) self.squelch = gr.simple_squelch_cc(self.noise_level, 1) noise_probe_thread = threading.Thread(target=self._noise_probe_thread) noise_probe_thread.start() self.threads.append(noise_probe_thread) self.tb.connect((low_pass_filter, 0), (self.noise_probe, 0)) self.tb.connect((low_pass_filter, 0), (self.squelch, 0)) # FM demodulation quadrature_demod = gr.quadrature_demod_cf(1) self.tb.connect((self.squelch, 0), (quadrature_demod, 0)) # Binary slicing, transformation into capture-compatible format add_offset = gr.add_const_vff((-1e-3, )) binary_slicer = digital.binary_slicer_fb() char_to_float = gr.char_to_float(1, 1) multiply_const = gr.multiply_const_vff((255, )) float_to_uchar = gr.float_to_uchar() pipe_sink = gr.file_sink(gr.sizeof_char*1, self.pipe) pipe_sink.set_unbuffered(False) self.tb.connect((quadrature_demod, 0), (add_offset, 0)) self.tb.connect((add_offset, 0), (binary_slicer, 0)) self.tb.connect((binary_slicer, 0), (char_to_float, 0)) self.tb.connect((char_to_float, 0), (multiply_const, 0)) self.tb.connect((multiply_const, 0), (float_to_uchar, 0)) self.tb.connect((float_to_uchar, 0), (pipe_sink, 0))
def __init__(self, *args, **kwargs): """ Hierarchical block for O-QPSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of bytes. @param sps: samples per symbol @type sps: integer """ try: self.sps = kwargs.pop('sps') self.log = kwargs.pop('log') except KeyError: pass gr.hier_block2.__init__( self, "ieee802_15_4_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input gr.io_signature(1, 1, gr.sizeof_float)) # Output # Demodulate FM sensitivity = (pi / 2) / self.sps #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.fmdemod = gr.quadrature_demod_cf(1) # Low pass the output of fmdemod to allow us to remove # the DC offset resulting from frequency offset alpha = 0.0008 / self.sps self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.connect(self, self.fmdemod) self.connect(self.fmdemod, (self.sub, 0)) self.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) # recover the clock omega = self.sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff( omega, gain_omega, mu, gain_mu, omega_relative_limit) # Connect self.connect(self.sub, self.clock_recovery, self) if self.log: self.connect(self.fmdemod, gr.file_sink(gr.sizeof_float, 'rx-fmdemod.dat')) self.connect(self.freq_offset, gr.file_sink(gr.sizeof_float, 'rx-fo.dat')) self.connect(self.sub, gr.file_sink(gr.sizeof_float, 'rx-sub.dat')) self.connect(self.clock_recovery, gr.file_sink(gr.sizeof_float, 'rx-recovery.dat'))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 1000000 self.dec_rate = dec_rate = 2 ################################################## # Blocks ################################################## self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_source_0.set_samp_rate(1000000) self.uhd_usrp_source_0.set_center_freq(2400490000, 0) self.uhd_usrp_source_0.set_gain(0, 0) self.low_pass_filter_0_0 = gr.interp_fir_filter_ccf( 1, firdes.low_pass(1, samp_rate, 500000, 10000, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = gr.fir_filter_fff( 1, firdes.low_pass(1, samp_rate, 500000, 10000, firdes.WIN_HAMMING, 6.76)) self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(1) self.gr_pwr_squelch_xx_0 = gr.pwr_squelch_cc(-100, 0.001, 0, True) self.flysky_dumpsync_0 = flysky.dumpsync() self.digital_correlate_access_code_bb_0_1 = digital.correlate_access_code_bb( "010101010101010101010101010101010101010001110101", 1) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff( 2, 0.0076562, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() ################################################## # Connections ################################################## self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.gr_quadrature_demod_cf_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.gr_pwr_squelch_xx_0, 0), (self.gr_quadrature_demod_cf_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.low_pass_filter_0_0, 0)) self.connect((self.low_pass_filter_0_0, 0), (self.gr_pwr_squelch_xx_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.digital_correlate_access_code_bb_0_1, 0)) self.connect((self.digital_correlate_access_code_bb_0_1, 0), (self.flysky_dumpsync_0, 0))
def __build_graph(self, source, capture_rate): # tell the scope the source rate self.spectrum.set_sample_rate(capture_rate) # channel filter self.channel_offset = 0.0 channel_decim = capture_rate // self.channel_rate channel_rate = capture_rate // channel_decim trans_width = 12.5e3 / 2 trans_centre = trans_width + (trans_width / 2) # discriminator tap doesn't do freq. xlation, FM demodulation, etc. if not self.baseband_input: coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre, trans_width, gr.firdes.WIN_HANN) self.channel_filter = gr.freq_xlating_fir_filter_ccf( channel_decim, coeffs, 0.0, capture_rate) self.set_channel_offset(0.0, 0, self.spectrum.win._units) # power squelch squelch_db = 0 self.squelch = gr.pwr_squelch_cc(squelch_db, 1e-3, 0, True) self.set_squelch_threshold(squelch_db) # FM demodulator fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) fm_demod = gr.quadrature_demod_cf(fm_demod_gain) # symbol filter symbol_decim = 1 #symbol_coeffs = gr.firdes.root_raised_cosine(1.0, channel_rate, self.symbol_rate, 0.2, 500) # boxcar coefficients for "integrate and dump" filter samples_per_symbol = channel_rate // self.symbol_rate symbol_coeffs = (1.0 / samples_per_symbol, ) * samples_per_symbol self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # C4FM demodulator autotuneq = gr.msg_queue(2) demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, self.symbol_rate) # for now no audio output sink = gr.null_sink(gr.sizeof_float) # connect it all up if self.baseband_input: self.rescaler = gr.multiply_const_ff(1) sinkx = gr.file_sink(gr.sizeof_float, "rx.dat") self.__connect([[ source, self.rescaler, self.symbol_filter, demod_fsk4, self.slicer, self.p25_decoder, sink ], [self.symbol_filter, self.signal_scope], [demod_fsk4, sinkx], [demod_fsk4, self.symbol_scope]]) self.connect_data_scope(not self.datascope_raw_input) else: self.demod_watcher = demod_watcher(autotuneq, self.adjust_channel_offset) self.__connect([[ source, self.channel_filter, self.squelch, fm_demod, self.symbol_filter, demod_fsk4, self.slicer, self.p25_decoder, sink ], [source, self.spectrum], [self.symbol_filter, self.signal_scope], [demod_fsk4, self.symbol_scope]])
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Ais Demod Grc") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.sps = sps = 6 self.samp_rate = samp_rate = 100e3 self.nfilts = nfilts = 32 self.data_rate = data_rate = 9600 ################################################## # Blocks ################################################## self.wxgui_scopesink2_2 = scopesink2.scope_sink_f( self.GetWin(), title="Scope Plot", sample_rate=samp_rate / sps, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_2.win) self.random_source_x_0 = gr.vector_source_b( list(map(int, numpy.random.randint(0, 2, 1000))), True) self.gr_throttle_0 = gr.throttle(gr.sizeof_gr_complex * 1, samp_rate * sps) self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(1) self.gr_map_bb_0 = gr.map_bb(([-1, 1])) self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf( sps, 0.004, (gr.firdes.gaussian(nfilts, float(nfilts) / sps, 0.4, int(11 * nfilts * sps))), nfilts, nfilts / 2, 1.5, 1) self.digital_pfb_clock_sync_xxx_0.set_beta((0.004**2) * 0.25) self.digital_gmskmod_bc_0 = digital.gmskmod_bc(sps, 0.4, 4) ################################################## # Connections ################################################## self.connect((self.gr_quadrature_demod_cf_0, 0), (self.wxgui_scopesink2_2, 0)) self.connect((self.gr_throttle_0, 0), (self.digital_pfb_clock_sync_xxx_0, 0)) self.connect((self.digital_gmskmod_bc_0, 0), (self.gr_throttle_0, 0)) self.connect((self.random_source_x_0, 0), (self.gr_map_bb_0, 0)) self.connect((self.gr_map_bb_0, 0), (self.digital_gmskmod_bc_0, 0)) self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.gr_quadrature_demod_cf_0, 0))
def __init__(self, options, args): gr.top_block.__init__(self) self.options = options self.args = args frekvens = options.freq # u = usrp.source_c(0) # u.set_decim_rate(256) # subdev_spec = (1,0) # u.set_mux(usrp.determine_rx_mux_value(u,subdev_spec)) # subdev = usrp.selected_subdev(u,subdev_spec) # subdev.set_auto_tr(True) # subdev.set_gain(57) # usrp.tune(u,0,subdev,frekvens)#106.3e6) # samplerate = 64000000/256 # 250000 self.u = uhd.usrp_source("", uhd.io_type_t.COMPLEX_FLOAT32, 1) self.u.set_subdev_spec("") # default should be good? self.u.set_samp_rate(250e3) samplerate = self.u.get_samp_rate() # Retrieve what it actually does self.u.set_antenna("RX2", 0) if options.gain is None: # set to halfway g = self.u.get_gain_range() options.gain = (g.start() + g.stop()) / 2.0 if not (self.u.set_center_freq(frekvens, 0)): print "Failed to set frequency" sys.exit(1) print "Setting gain to %i" % options.gain self.u.set_gain(options.gain) coeffs = gr.firdes.low_pass(1, samplerate, 10000, 10000) filter = gr.fir_filter_ccf(5, coeffs) gang = gr.multiply_const_ff(10) lpcoeffs = gr.firdes.low_pass(1, samplerate, 8000, 3000) lpfilter = gr.fir_filter_fff(1, lpcoeffs) demod = gr.quadrature_demod_cf(0.5) clockrec = gr.clock_recovery_mm_ff( float(samplerate) / 5 / 9600, 0.25 * 0.175 * 0.175, 0.5, 0.175, 0.005) #datadec = ais.ais_decoder_mysql("localhost","diverse","aisblock","elgelg") self.datadec = ais.ais_decoder_gearth(30003) slicer = gr.binary_slicer_fb() diff = gr.diff_decoder_bb(2) invert = ais.invert10_bb() # print subdev.name() self.connect(self.u, filter, demod, lpfilter, gang, clockrec, slicer, diff, invert, self.datadec)
def __init__(self, *args, **kwargs): """ Hierarchical block for O-QPSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of bytes. @param sps: samples per symbol @type sps: integer """ try: self.sps = kwargs.pop('sps') self.log = kwargs.pop('log') except KeyError: pass gr.hier_block2.__init__(self, "ieee802_15_4_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input gr.io_signature(1, 1, gr.sizeof_float)) # Output # Demodulate FM sensitivity = (pi / 2) / self.sps #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.fmdemod = gr.quadrature_demod_cf(1) # Low pass the output of fmdemod to allow us to remove # the DC offset resulting from frequency offset alpha = 0.0008/self.sps self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.connect(self, self.fmdemod) self.connect(self.fmdemod, (self.sub, 0)) self.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) # recover the clock omega = self.sps gain_mu=0.03 mu=0.5 omega_relative_limit=0.0002 freq_error=0.0 gain_omega = .25*gain_mu*gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit) # Connect self.connect(self.sub, self.clock_recovery, self) if self.log: self.connect(self.fmdemod, gr.file_sink(gr.sizeof_float, 'rx-fmdemod.dat')) self.connect(self.freq_offset, gr.file_sink(gr.sizeof_float, 'rx-fo.dat')) self.connect(self.sub, gr.file_sink(gr.sizeof_float, 'rx-sub.dat')) self.connect(self.clock_recovery, gr.file_sink(gr.sizeof_float, 'rx-recovery.dat'))
def __init__(self): gr.top_block.__init__(self, "FSK Demod Demo") # Variables self.symbol_rate = symbol_rate = 125e3 self.samp_rate = samp_rate = symbol_rate self.f_center = f_center = 868e6 self.sps = sps = 2 self.sensitivity = sensitivity = (pi / 2) / sps self.alpha = alpha = 0.0512 / sps self.bandwidth = bandwidth = 100e3 # Blocks self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_source_0.set_samp_rate(samp_rate) self.uhd_usrp_source_0.set_center_freq(f_center, 0) self.uhd_usrp_source_0.set_gain(0, 0) self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0) self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity) self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.add = gr.add_ff() self.multiply = gr.multiply_ff() self.invert = gr.multiply_const_vff((-1, )) # recover the clock omega = sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff( omega, gain_omega, mu, gain_mu, omega_relative_limit) self.slice = digital.binary_slicer_fb() self.sink = gr.vector_sink_b(1) self.file_sink = gr.file_sink(gr.sizeof_char, 'fsk_dump.log') # Connections self.connect(self.fm_demod, (self.add, 0)) self.connect(self.fm_demod, self.freq_offset, (self.add, 1)) self.connect(self.uhd_usrp_source_0, self.fm_demod) self.connect(self.add, self.clock_recovery, self.invert, self.slice, self.file_sink) self.connect(self.slice, self.sink)
def __init__(self): gr.top_block.__init__(self) #build graph now #usrp_source self.usrp = usrp.source_c() adc_rate = self.usrp.adc_rate() #64MHz hw_decim = 16 #so Sample rate into host is 4MHz self.usrp.set_decim_rate(hw_decim) self.subdev = usrp.selected_subdev(self.usrp, usrp.pick_rx_subdevice(self.usrp)) self.usrp.set_mux( usrp.determine_rx_mux_value(self.usrp, usrp.pick_rx_subdevice(self.usrp))) print "Using RX d'board %s" % (self.subdev.side_and_name(), ) self.subdev.set_gain(30) rf_freq = 106800000 # 106.8MHz self.set_freq(rf_freq) print "Freq: ", rf_freq self.subdev.select_rx_antenna("TX/RX") #low pass filter self.sample_rate = adc_rate / hw_decim self.lpf_decim = 20 # so after channel filter, the sample rate is 200KHz self.lp_filter = gr.fir_filter_ccf( self.lpf_decim, gr.firdes.low_pass( 1, self.sample_rate, 100e3, # cut off freq 10e3, # transition band gr.firdes.WIN_BLACKMAN, # Window function 6.76 # not used )) # WBFM receiver quad_rate = self.sample_rate #input rate of demodulator max_dev = 75e3 #max deviation of FM Broadcast fm_demod_gain = quad_rate / (2 * math.pi * max_dev) self.fm_decoder = gr.quadrature_demod_cf(fm_demod_gain) # Rational Resampler self.audio_sample_rate = 96000 self.rational_resampler = blks2.rational_resampler_fff( interpolation=int(self.audio_sample_rate / 1000), decimation=int(self.sample_rate / self.lpf_decim / 1000), taps=None, fractional_bw=None, ) self.audio_sink = audio.sink(int(self.audio_sample_rate), "", True) #connections self.connect(self.usrp, self.lp_filter, self.fm_decoder, self.rational_resampler, self.audio_sink)
def __init__(self, options, args): gr.top_block.__init__(self) self.options = options self.args = args frekvens = options.freq # u = usrp.source_c(0) # u.set_decim_rate(256) # subdev_spec = (1,0) # u.set_mux(usrp.determine_rx_mux_value(u,subdev_spec)) # subdev = usrp.selected_subdev(u,subdev_spec) # subdev.set_auto_tr(True) # subdev.set_gain(57) # usrp.tune(u,0,subdev,frekvens)#106.3e6) # samplerate = 64000000/256 # 250000 self.u = uhd.usrp_source("", uhd.io_type_t.COMPLEX_FLOAT32,1) self.u.set_subdev_spec(""); # default should be good? self.u.set_samp_rate(250e3); samplerate = self.u.get_samp_rate() # Retrieve what it actually does self.u.set_antenna("RX2",0) if options.gain is None: # set to halfway g = self.u.get_gain_range() options.gain = (g.start()+g.stop()) / 2.0 if not(self.u.set_center_freq(frekvens, 0)): print "Failed to set frequency" sys.exit(1) print "Setting gain to %i" % options.gain self.u.set_gain(options.gain) coeffs = gr.firdes.low_pass(1,samplerate,10000,10000) filter = gr.fir_filter_ccf(5,coeffs) gang = gr.multiply_const_ff(10) lpcoeffs = gr.firdes.low_pass(1,samplerate,8000,3000) lpfilter = gr.fir_filter_fff(1,lpcoeffs) demod = gr.quadrature_demod_cf(0.5) clockrec = gr.clock_recovery_mm_ff(float(samplerate)/5/9600,0.25*0.175*0.175,0.5,0.175,0.005) #datadec = ais.ais_decoder_mysql("localhost","diverse","aisblock","elgelg") self.datadec = ais.ais_decoder_gearth(30003) slicer = gr.binary_slicer_fb() diff = gr.diff_decoder_bb(2) invert = ais.invert10_bb() # print subdev.name() self.connect(self.u,filter,demod,lpfilter,gang,clockrec, slicer,diff,invert,self.datadec)
def __init__(self, fg, sps=8, symbol_rate=38400, p_size=13): """ Hierarchical block for FSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of bytes. @param fg: flow graph @type fg: flow graph @param sps: samples per symbol @type sps: integer @param symbol_rate: symbols per second @type symbol_rate: float @param p_size: packet size @type p_size: integer """ # Demodulate FM sensitivity = (pi / 2) / sps #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.fmdemod = gr.quadrature_demod_cf(1 / sensitivity) # Low pass the output of fmdemod to allow us to remove # the DC offset resulting from frequency offset alpha = 0.0512 / sps self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() fg.connect(self.fmdemod, (self.sub, 0)) fg.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) # recover the clock omega = sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = gr.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit) # Connect fg.connect(self.sub, self.clock_recovery) #filesink = gr.file_sink(gr.sizeof_float, 'rx_fsk_test.dat') #fg.connect(self.clock_recovery, filesink) # Initialize base class gr.hier_block.__init__(self, fg, self.fmdemod, self.clock_recovery)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="RTTY decoder example") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 44100 ################################################## # Blocks ################################################## self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.GetWin(), title="Scope Plot", sample_rate=samp_rate/40, v_scale=1, v_offset=0, t_scale=25e-3, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_0.win) self.rtty_decode_ff_0 = rtty.decode_ff( samp_rate=samp_rate/40, baud_rate=45.45, polarity=True, ) self.low_pass_filter_0 = gr.fir_filter_fff(40, firdes.low_pass( 100, samp_rate, 45.45*3, 20, firdes.WIN_HANN, 6.76)) self.gr_wavfile_source_0 = gr.wavfile_source("/home/nick/Downloads/ksm_rtty.wav", False) self.gr_sub_xx_0 = gr.sub_ff(1) self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(1) self.gr_moving_average_xx_0 = gr.moving_average_ff(5000, 1.0/5000, 20000) self.gr_hilbert_fc_0 = gr.hilbert_fc(64) self.gr_file_sink_0 = gr.file_sink(gr.sizeof_char*1, "/home/nick/Desktop/rtty/test.dat") self.gr_file_sink_0.set_unbuffered(False) ################################################## # Connections ################################################## self.connect((self.low_pass_filter_0, 0), (self.gr_moving_average_xx_0, 0)) self.connect((self.gr_moving_average_xx_0, 0), (self.gr_sub_xx_0, 1)) self.connect((self.gr_sub_xx_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.gr_sub_xx_0, 0)) self.connect((self.rtty_decode_ff_0, 0), (self.gr_file_sink_0, 0)) self.connect((self.gr_sub_xx_0, 0), (self.rtty_decode_ff_0, 0)) self.connect((self.gr_quadrature_demod_cf_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.gr_hilbert_fc_0, 0), (self.gr_quadrature_demod_cf_0, 0)) self.connect((self.gr_wavfile_source_0, 0), (self.gr_hilbert_fc_0, 0))
def __init__(self, fg, sps = 8, symbol_rate = 38400, p_size = 13): """ Hierarchical block for FSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of bytes. @param fg: flow graph @type fg: flow graph @param sps: samples per symbol @type sps: integer @param symbol_rate: symbols per second @type symbol_rate: float @param p_size: packet size @type p_size: integer """ # Demodulate FM sensitivity = (pi / 2) / sps #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.fmdemod = gr.quadrature_demod_cf(1 / sensitivity) # Low pass the output of fmdemod to allow us to remove # the DC offset resulting from frequency offset alpha = 0.0512/sps self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() fg.connect(self.fmdemod, (self.sub, 0)) fg.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) # recover the clock omega = sps gain_mu=0.03 mu=0.5 omega_relative_limit=0.0002 freq_error=0.0 gain_omega = .25*gain_mu*gain_mu # critically damped self.clock_recovery = gr.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit) # Connect fg.connect(self.sub, self.clock_recovery) #filesink = gr.file_sink(gr.sizeof_float, 'rx_fsk_test.dat') #fg.connect(self.clock_recovery, filesink) # Initialize base class gr.hier_block.__init__(self, fg, self.fmdemod, self.clock_recovery)
def __init__(self): gr.top_block.__init__(self, "FSK Demod Demo") # Variables self.symbol_rate = symbol_rate = 125e3 self.samp_rate = samp_rate = symbol_rate self.f_center = f_center = 868e6 self.sps = sps = 2 self.sensitivity = sensitivity = (pi / 2) / sps self.alpha = alpha = 0.0512/sps self.bandwidth = bandwidth = 100e3 # Blocks self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_source_0.set_samp_rate(samp_rate) self.uhd_usrp_source_0.set_center_freq(f_center, 0) self.uhd_usrp_source_0.set_gain(0, 0) self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0) self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity) self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.add = gr.add_ff() self.multiply = gr.multiply_ff() self.invert = gr.multiply_const_vff((-1, )) # recover the clock omega = sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit) self.slice = digital.binary_slicer_fb() self.sink = gr.vector_sink_b(1) self.file_sink = gr.file_sink(gr.sizeof_char, 'fsk_dump.log') # Connections self.connect(self.fm_demod, (self.add, 0)) self.connect(self.fm_demod, self.freq_offset, (self.add, 1)) self.connect(self.uhd_usrp_source_0, self.fm_demod) self.connect(self.add, self.clock_recovery, self.invert, self.slice, self.file_sink) self.connect(self.slice, self.sink)
def __init__(self, samples_per_symbol=_def_samples_per_symbol, gain_mu=_def_gain_mu, mu=_def_mu, omega_relative_limit=_def_omega_relative_limit, freq_error=_def_freq_error, verbose=_def_verbose, log=_def_log): gr.hier_block2.__init__(self, "gmsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self._samples_per_symbol = samples_per_symbol self._gain_mu = gain_mu self._mu = mu self._omega_relative_limit = omega_relative_limit self._freq_error = freq_error self._differential = False if samples_per_symbol < 2: raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol self._omega = samples_per_symbol*(1+self._freq_error) if not self._gain_mu: self._gain_mu = 0.175 self._gain_omega = .25 * self._gain_mu * self._gain_mu # critically damped # Demodulate FM sensitivity = (pi / 2) / samples_per_symbol self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) # the clock recovery block tracks the symbol clock and resamples as needed. # the output of the block is a stream of soft symbols (float) self.clock_recovery = digital.clock_recovery_mm_ff(self._omega, self._gain_omega, self._mu, self._gain_mu, self._omega_relative_limit) # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample self.slicer = digital.binary_slicer_fb() if verbose: self._print_verbage() if log: self._setup_logging() # Connect & Initialize base class self.connect(self, self.fmdemod, self.clock_recovery, self.slicer, self)
def __build_graph(self, source, capture_rate): # tell the scope the source rate self.spectrum.set_sample_rate(capture_rate) # channel filter self.channel_offset = 0.0 channel_decim = capture_rate // self.channel_rate channel_rate = capture_rate // channel_decim trans_width = 12.5e3 / 2 trans_centre = trans_width + (trans_width / 2) coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre, trans_width, gr.firdes.WIN_HANN) self.channel_filter = gr.freq_xlating_fir_filter_ccf( channel_decim, coeffs, 0.0, capture_rate) self.set_channel_offset(0.0, 0, self.spectrum.win._units) # power squelch squelch_db = 0 self.squelch = gr.pwr_squelch_cc(squelch_db, 1e-3, 0, True) self.set_squelch_threshold(squelch_db) # FM demodulator fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) fm_demod = gr.quadrature_demod_cf(fm_demod_gain) # symbol filter symbol_decim = 1 # symbol_coeffs = gr.firdes.root_raised_cosine(1.0, channel_rate, self.symbol_rate, 0.2, 500) # boxcar coefficients for "integrate and dump" filter samples_per_symbol = channel_rate // self.symbol_rate symbol_coeffs = (1.0 / samples_per_symbol, ) * samples_per_symbol symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # C4FM demodulator autotuneq = gr.msg_queue(2) self.demod_watcher = demod_watcher(autotuneq, self.adjust_channel_offset) demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, self.symbol_rate) # symbol slicer levels = [-2.0, 0.0, 2.0, 4.0] slicer = op25.fsk4_slicer_fb(levels) # ALSA output device (if not locked) try: sink = audio.sink(8000, "plughw:0,0", True) # ToDo: get actual device from prefs except Exception: sink = gr.null_sink(gr.sizeof_float) # connect it all up self.__connect([[ source, self.channel_filter, self.squelch, fm_demod, symbol_filter, demod_fsk4, slicer, self.p25_decoder, sink ], [source, self.spectrum], [symbol_filter, self.signal_scope], [demod_fsk4, self.symbol_scope]])
def setup_f_flowgraph(self): # configure demodulator # adjust the phase gain for sampling rate self.demod = gr.quadrature_demod_cf(self.sps); #configure clock recovery gain_mu = 0.01 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clocker = gr.clock_recovery_mm_ff( self.sps, gain_omega, 0.5, #mu gain_mu, 0.5) #omega_relative_limit, self.burst = gsm.burst_ff(self.burst_cb) self.connect(self.filter, self.demod, self.clocker, self.burst)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Ais Demod Grc") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.sps = sps = 6 self.samp_rate = samp_rate = 100e3 self.nfilts = nfilts = 32 self.data_rate = data_rate = 9600 ################################################## # Blocks ################################################## self.wxgui_scopesink2_2 = scopesink2.scope_sink_f( self.GetWin(), title="Scope Plot", sample_rate=samp_rate/sps, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_2.win) self.random_source_x_0 = gr.vector_source_b(map(int, numpy.random.randint(0, 2, 1000)), True) self.gr_throttle_0 = gr.throttle(gr.sizeof_gr_complex*1, samp_rate*sps) self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(1) self.gr_map_bb_0 = gr.map_bb(([-1, 1])) self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf(sps, 0.004, (gr.firdes.gaussian(nfilts, float(nfilts)/sps, 0.4, int(11*nfilts*sps))), nfilts, nfilts/2, 1.5, 1) self.digital_pfb_clock_sync_xxx_0.set_beta((0.004**2)*0.25) self.digital_gmskmod_bc_0 = digital.gmskmod_bc(sps, 0.4, 4) ################################################## # Connections ################################################## self.connect((self.gr_quadrature_demod_cf_0, 0), (self.wxgui_scopesink2_2, 0)) self.connect((self.gr_throttle_0, 0), (self.digital_pfb_clock_sync_xxx_0, 0)) self.connect((self.digital_gmskmod_bc_0, 0), (self.gr_throttle_0, 0)) self.connect((self.random_source_x_0, 0), (self.gr_map_bb_0, 0)) self.connect((self.gr_map_bb_0, 0), (self.digital_gmskmod_bc_0, 0)) self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.gr_quadrature_demod_cf_0, 0))
def __init__ (self, fg, quad_rate, audio_decimation): """ Hierarchical block for demodulating a broadcast FM signal. The input is the downconverted complex baseband signal (gr_complex). The output is the demodulated audio (float). @param fg: flow graph. @type fg: flow graph @param quad_rate: input sample rate of complex baseband input. @type quad_rate: float @param audio_decimation: how much to decimate quad_rate to get to audio. @type audio_decimation: integer """ volume = 20. max_dev = 75e3 fm_demod_gain = quad_rate/(2*math.pi*max_dev) audio_rate = quad_rate / audio_decimation # We assign to self so that outsiders can grab the demodulator # if they need to. E.g., to plot its output. # # input: complex; output: float self.fm_demod = gr.quadrature_demod_cf (fm_demod_gain) # input: float; output: float self.deemph = fm_deemph (fg, audio_rate) # compute FIR filter taps for audio filter width_of_transition_band = audio_rate / 32 audio_coeffs = gr.firdes.low_pass (1.0, # gain quad_rate, # sampling rate audio_rate/2 - width_of_transition_band, width_of_transition_band, gr.firdes.WIN_HAMMING) # input: float; output: float self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) fg.connect (self.fm_demod, self.audio_filter, self.deemph) gr.hier_block.__init__(self, fg, self.fm_demod, # head of the pipeline self.deemph) # tail of the pipeline
def __init__(self): gr.top_block.__init__(self) #build graph now #usrp_source self.usrp = usrp.source_c() adc_rate = self.usrp.adc_rate() #64MHz hw_decim = 16 #so Sample rate into host is 4MHz self.usrp.set_decim_rate(hw_decim) self.subdev = usrp.selected_subdev(self.usrp, usrp.pick_rx_subdevice(self.usrp)) self.usrp.set_mux(usrp.determine_rx_mux_value(self.usrp, usrp.pick_rx_subdevice(self.usrp))) print "Using RX d'board %s" % (self.subdev.side_and_name(),) self.subdev.set_gain(30) rf_freq = 106800000 # 106.8MHz self.set_freq(rf_freq) print "Freq: ", rf_freq self.subdev.select_rx_antenna("TX/RX") #low pass filter self.sample_rate = adc_rate / hw_decim self.lpf_decim = 20 # so after channel filter, the sample rate is 200KHz self.lp_filter = gr.fir_filter_ccf( self.lpf_decim, gr.firdes.low_pass ( 1, self.sample_rate, 100e3, # cut off freq 10e3, # transition band gr.firdes.WIN_BLACKMAN, # Window function 6.76 # not used )) # WBFM receiver quad_rate = self.sample_rate #input rate of demodulator max_dev = 75e3 #max deviation of FM Broadcast fm_demod_gain = quad_rate/(2 * math.pi * max_dev) self.fm_decoder = gr.quadrature_demod_cf (fm_demod_gain) # Rational Resampler self.audio_sample_rate = 96000 self.rational_resampler = blks2.rational_resampler_fff ( interpolation = int(self.audio_sample_rate/1000), decimation = int(self.sample_rate/self.lpf_decim/1000), taps = None, fractional_bw = None, ) self.audio_sink = audio.sink (int(self.audio_sample_rate), "", True) #connections self.connect ( self.usrp, self.lp_filter, self.fm_decoder, self.rational_resampler, self.audio_sink )
def __init__(self, quad_rate, audio_decimation): """ Hierarchical block for demodulating a broadcast FM signal. The input is the downconverted complex baseband signal (gr_complex). The output is the demodulated audio (float). @param quad_rate: input sample rate of complex baseband input. @type quad_rate: float @param audio_decimation: how much to decimate quad_rate to get to audio. @type audio_decimation: integer """ gr.hier_block2.__init__( self, "wfm_rcv", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature volume = 20. max_dev = 75e3 fm_demod_gain = quad_rate / (2 * math.pi * max_dev) audio_rate = quad_rate / audio_decimation # We assign to self so that outsiders can grab the demodulator # if they need to. E.g., to plot its output. # # input: complex; output: float self.fm_demod = gr.quadrature_demod_cf(fm_demod_gain) # input: float; output: float self.deemph = fm_deemph(audio_rate) # compute FIR filter taps for audio filter width_of_transition_band = audio_rate / 32 audio_coeffs = gr.firdes.low_pass( 1.0, # gain quad_rate, # sampling rate audio_rate / 2 - width_of_transition_band, width_of_transition_band, gr.firdes.WIN_HAMMING) # input: float; output: float self.audio_filter = gr.fir_filter_fff(audio_decimation, audio_coeffs) self.connect(self, self.fm_demod, self.audio_filter, self.deemph, self)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 1000000 self.dec_rate = dec_rate = 2 ################################################## # Blocks ################################################## self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="", stream_args=uhd.stream_args(cpu_format="fc32", channels=range(1)) ) self.uhd_usrp_source_0.set_samp_rate(1000000) self.uhd_usrp_source_0.set_center_freq(2400490000, 0) self.uhd_usrp_source_0.set_gain(0, 0) self.low_pass_filter_0_0 = gr.interp_fir_filter_ccf( 1, firdes.low_pass(1, samp_rate, 500000, 10000, firdes.WIN_HAMMING, 6.76) ) self.low_pass_filter_0 = gr.fir_filter_fff( 1, firdes.low_pass(1, samp_rate, 500000, 10000, firdes.WIN_HAMMING, 6.76) ) self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(1) self.gr_pwr_squelch_xx_0 = gr.pwr_squelch_cc(-100, 0.001, 0, True) self.flysky_dumpsync_0 = flysky.dumpsync() self.digital_correlate_access_code_bb_0_1 = digital.correlate_access_code_bb( "010101010101010101010101010101010101010001110101", 1 ) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.0076562, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() ################################################## # Connections ################################################## self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.gr_quadrature_demod_cf_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.gr_pwr_squelch_xx_0, 0), (self.gr_quadrature_demod_cf_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.low_pass_filter_0_0, 0)) self.connect((self.low_pass_filter_0_0, 0), (self.gr_pwr_squelch_xx_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.digital_correlate_access_code_bb_0_1, 0)) self.connect((self.digital_correlate_access_code_bb_0_1, 0), (self.flysky_dumpsync_0, 0))
def __build_graph(self, source, capture_rate): # tell the scope the source rate self.spectrum.set_sample_rate(capture_rate) # channel filter self.channel_offset = 0.0 channel_decim = capture_rate // self.channel_rate channel_rate = capture_rate // channel_decim trans_width = 12.5e3 / 2; trans_centre = trans_width + (trans_width / 2) coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre, trans_width, gr.firdes.WIN_HANN) self.channel_filter = gr.freq_xlating_fir_filter_ccf(channel_decim, coeffs, 0.0, capture_rate) self.set_channel_offset(0.0) # power squelch squelch_db = 0 self.squelch = gr.pwr_squelch_cc(squelch_db, 1e-3, 0, True) self.set_squelch_threshold(squelch_db) # FM demodulator fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) fm_demod = gr.quadrature_demod_cf(fm_demod_gain) # symbol filter symbol_decim = 1 # symbol_coeffs = gr.firdes.root_raised_cosine(1.0, channel_rate, self.symbol_rate, 0.2, 500) # boxcar coefficients for "integrate and dump" filter samples_per_symbol = channel_rate // self.symbol_rate symbol_coeffs = (1.0/samples_per_symbol,)*samples_per_symbol symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # C4FM demodulator autotuneq = gr.msg_queue(2) self.demod_watcher = demod_watcher(autotuneq, self.adjust_channel_offset) demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, self.symbol_rate) # symbol slicer levels = [ -2.0, 0.0, 2.0, 4.0 ] slicer = op25.fsk4_slicer_fb(levels) # ALSA output device (if not locked) try: sink = audio.sink(8000, "plughw:0,0", True) # ToDo: get actual device from prefs except Exception: sink = gr.null_sink(gr.sizeof_float) # connect it all up self.__connect([[source, self.channel_filter, self.squelch, fm_demod, symbol_filter, demod_fsk4, slicer, self.p25_decoder, sink], [source, self.spectrum], [symbol_filter, self.signal_scope], [demod_fsk4, self.symbol_scope]])
def __init__(self): """ Hierarchical block for FSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of floats. """ # Initialize base class gr.hier_block2.__init__(self, "fsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) # Variables self.sps = sps = 2 self.sensitivity = sensitivity = (pi / 2) / sps self.alpha = alpha = 0.0512 / sps self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity) self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.add = gr.add_ff() self.multiply = gr.multiply_ff() self.invert = gr.multiply_const_vff((-1, )) # recover the clock omega = sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff( omega, gain_omega, mu, gain_mu, omega_relative_limit) self.slice = digital.binary_slicer_fb() # Connections self.connect(self.fm_demod, (self.add, 0)) self.connect(self.fm_demod, self.freq_offset, (self.add, 1)) self.connect(self, self.fm_demod) self.connect(self.add, self.clock_recovery, self.invert, self)
def __init__(self, samp_rate=1600000, samp_per_sym=16, freq_error=-0.0025000): gr.hier_block2.__init__( self, "Wireless M-Bus Demod", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signature(1, 1, gr.sizeof_char*1), ) ################################################## # Parameters ################################################## self.samp_rate = samp_rate self.samp_per_sym = samp_per_sym self.freq_error = freq_error ################################################## # Variables ################################################## self.cutoff = cutoff = 120e3 self.chip_rate = chip_rate = samp_rate/samp_per_sym ################################################## # Blocks ################################################## self.low_pass_filter_0 = gr.fir_filter_ccf(1, firdes.low_pass( 1, samp_rate, cutoff, cutoff/2, firdes.WIN_HAMMING, 6.76)) self.gr_sub_xx_0 = gr.sub_ff(1) self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff(0.0512/samp_per_sym, 1) self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(1) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(samp_per_sym*(1+freq_error), .25 *0.06*0.06*4, 0.5, 0.06*2, 0.002*2) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() ################################################## # Connections ################################################## self.connect((self.gr_quadrature_demod_cf_0, 0), (self.gr_single_pole_iir_filter_xx_0, 0)) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_sub_xx_0, 1)) self.connect((self.gr_quadrature_demod_cf_0, 0), (self.gr_sub_xx_0, 0)) self.connect((self.gr_sub_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.gr_quadrature_demod_cf_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self, 0)) self.connect((self, 0), (self.low_pass_filter_0, 0))
def __init__ (self, quad_rate, audio_decimation): """ Hierarchical block for demodulating a broadcast FM signal. The input is the downconverted complex baseband signal (gr_complex). The output is the demodulated audio (float). Args: quad_rate: input sample rate of complex baseband input. (float) audio_decimation: how much to decimate quad_rate to get to audio. (integer) """ gr.hier_block2.__init__(self, "wfm_rcv", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature volume = 20. max_dev = 75e3 fm_demod_gain = quad_rate/(2*math.pi*max_dev) audio_rate = quad_rate / audio_decimation # We assign to self so that outsiders can grab the demodulator # if they need to. E.g., to plot its output. # # input: complex; output: float self.fm_demod = gr.quadrature_demod_cf (fm_demod_gain) # input: float; output: float self.deemph = fm_deemph (audio_rate) # compute FIR filter taps for audio filter width_of_transition_band = audio_rate / 32 audio_coeffs = gr.firdes.low_pass (1.0, # gain quad_rate, # sampling rate audio_rate/2 - width_of_transition_band, width_of_transition_band, gr.firdes.WIN_HAMMING) # input: float; output: float self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) self.connect (self, self.fm_demod, self.audio_filter, self.deemph, self)
def __init__(self): """ Hierarchical block for FSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of floats. """ # Initialize base class gr.hier_block2.__init__( self, "fsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float) ) # Variables self.sps = sps = 2 self.sensitivity = sensitivity = (pi / 2) / sps self.alpha = alpha = 0.0512 / sps self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity) self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.add = gr.add_ff() self.multiply = gr.multiply_ff() self.invert = gr.multiply_const_vff((-1,)) # recover the clock omega = sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = 0.25 * gain_mu * gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit) self.slice = digital.binary_slicer_fb() # Connections self.connect(self.fm_demod, (self.add, 0)) self.connect(self.fm_demod, self.freq_offset, (self.add, 1)) self.connect(self, self.fm_demod) self.connect(self.add, self.clock_recovery, self.invert, self)
def __init__(self): """ Hierarchical block for MSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of floats. """ # Initialize base class gr.hier_block2.__init__(self, "msk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) self.sps = 2 self.bt = 0.35 self.mu = 0.5 self.gain_mu = 0.175 self.freq_error = 0.0 self.omega_relative_limit = 0.005 self.omega = self.sps * (1 + self.freq_error) self.gain_omega = .25 * self.gain_mu * self.gain_mu # critically damped # Demodulate FM sensitivity = (pi / 2) / self.sps self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.invert = gr.multiply_const_vff((-1, )) # TODO: this is hardcoded, how to figure out this value? self.offset = gr.add_const_vff((-1.4, )) # the clock recovery block tracks the symbol clock and resamples as needed. # the output of the block is a stream of soft symbols (float) self.clock_recovery = digital.clock_recovery_mm_ff( self.omega, self.gain_omega, self.mu, self.gain_mu, self.omega_relative_limit) self.slicer = digital.binary_slicer_fb() self.connect(self, self.fmdemod, self.invert, self.clock_recovery, self.offset, self)
def __init__(self, channel_rate, audio_decim, deviation, audio_pass, audio_stop, gain=1.0, tau=75e-6): gr.hier_block2.__init__(self, "fm_demod_cf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature k = channel_rate/(2*pi*deviation) QUAD = gr.quadrature_demod_cf(k) audio_taps = optfir.low_pass(gain, # Filter gain channel_rate, # Sample rate audio_pass, # Audio passband audio_stop, # Audio stopband 0.1, # Passband ripple 60) # Stopband attenuation LPF = gr.fir_filter_fff(audio_decim, audio_taps) if tau is not None: DEEMPH = fm_deemph(channel_rate, tau) self.connect(self, QUAD, DEEMPH, LPF, self) else: self.connect(self, QUAD, LPF, self)
def __init__(self): gr.hier_block2.__init__(self, "HierBlock_data", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, 1)) fsk = gr.hilbert_fc((AUDIO_RATE/300)+1) bp_coeff = gr.firdes.band_pass(1,AUDIO_RATE,BP_START,BP_STOP,100) bpf = gr.fir_filter_fff(1,bp_coeff) quad_demod = gr.quadrature_demod_cf(1.0) hpf_coeff = gr.firdes.high_pass(10, AUDIO_RATE, 10, 5) dc_block = gr.fir_filter_fff (1, hpf_coeff) mm = gr.clock_recovery_mm_ff(REPEAT_TIME,0.000625,0.5,0.01,0.05) slicer = gr.binary_slicer_fb() sync_corr = gr.correlate_access_code_bb("0100011101111000",0) self.connect(self,bpf,fsk,quad_demod,dc_block,mm,slicer,sync_corr,self)
def __init__(self): gr.top_block.__init__(self) self.rcvd_pktq = gr.msg_queue() audio_rate = 48000 src = audio.source (audio_rate,"plughw:0,0") mult = gr.multiply_const_ff(10) # multiply raw_wave = gr.wavfile_sink(filename, 1, audio_rate,16) raw_wave1 = gr.wavfile_sink(filename2, 1, audio_rate,16) fsk_c = gr.hilbert_fc((audio_rate/300)+1) bp_coeff = gr.firdes.band_pass(1,audio_rate,BandPass,BandStop,100) bpf = gr.fir_filter_fff(1,bp_coeff) quad_demod = gr.quadrature_demod_cf(1)#originally 1 hpf_coeff = gr.firdes.high_pass(10, audio_rate, 10, 5) dc_block = gr.add_const_ff(-2.225) mm = gr.clock_recovery_mm_ff(RepeatTime,0.000625,0.5,0.01,0.1) slicer = gr.binary_slicer_fb() sync_corr = gr.correlate_access_code_bb("0100011101111000",0) file_sink = gr.file_sink(1, "decoded-bits.dat") sink = goodney.sink2(self.rcvd_pktq) self.connect(bpf,raw_wave1) self.connect(src,raw_wave) self.connect(src,bpf,fsk_c,quad_demod,dc_block,mm,slicer,sync_corr,sink) self.watcher = _queue_watcher_thread(self.rcvd_pktq, message_callback)
def __init__(self): """ Hierarchical block for MSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of floats. """ # Initialize base class gr.hier_block2.__init__( self, "msk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float) ) self.sps = 2 self.bt = 0.35 self.mu = 0.5 self.gain_mu = 0.175 self.freq_error = 0.0 self.omega_relative_limit = 0.005 self.omega = self.sps * (1 + self.freq_error) self.gain_omega = 0.25 * self.gain_mu * self.gain_mu # critically damped # Demodulate FM sensitivity = (pi / 2) / self.sps self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.invert = gr.multiply_const_vff((-1,)) # TODO: this is hardcoded, how to figure out this value? self.offset = gr.add_const_vff((-1.2,)) # the clock recovery block tracks the symbol clock and resamples as needed. # the output of the block is a stream of soft symbols (float) self.clock_recovery = digital.clock_recovery_mm_ff( self.omega, self.gain_omega, self.mu, self.gain_mu, self.omega_relative_limit ) self.slicer = digital.binary_slicer_fb() self.connect(self, self.fmdemod, self.invert, self.clock_recovery, self.offset, self)
def __init__(self, options): gr.flow_graph.__init__(self) # bandwidth = 12.5e3 # symbol_rate = 4800 # output_sample_rate = options.samples_per_symbol * symbol_rate # lcm = gru.lcm(options.sample_rate, output_sample_rate) # intrp = int(lcm // options.sample_rate) # decim = int(lcm // output_sample_rate) if options.input_file == '-': src = gr.file_descriptor_source(gr.sizeof_gr_complex, 0) else: src = gr.file_source(gr.sizeof_gr_complex, options.input_file) # ddc_coeffs = \ # gr.firdes.low_pass (1.0, # options.sample_rate, # bandwidth/2, # bandwidth/2, # gr.firdes.WIN_HANN) # ddc = gr.freq_xlating_fir_filter_ccf (1,ddc_coeffs,-options.frequency,options.sample_rate) # resampler = blks.rational_resampler_ccc(self, intrp, decim) qdemod = gr.quadrature_demod_cf(1.0) if options.output_file == '-': sink = gr.file_descriptor_sink(gr.sizeof_float, 1) else: sink = gr.file_sink(gr.sizeof_float, options.output_file) # if options.invert: # inverter = gr.multiply_const_ff(-1.0) # self.connect(src,qdemod,inverter,sink) # else: self.connect(src,qdemod,sink)
def __init__(self, samplerate, symbolrate=SYMRATE, channel_str=None, sendmsg=True, debug=False, samplepersymbol=SPS, fmdeviation=FM_DEVIATION): gr.hier_block2.__init__(self, "pocsag", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, 1)) self.samplerate = samplerate self.symbolrate = symbolrate self.sendmsg = sendmsg self.debug = debug self.samplepersymbol = samplepersymbol self.fmdeviation = fmdeviation self.fractional_interpolator = gr.fractional_interpolator_cc( 0, 1.0 * samplerate / (symbolrate * samplepersymbol)) self.quadrature_demod = gr.quadrature_demod_cf( (symbolrate * samplepersymbol) / (fmdeviation * 4.0)) self.low_pass_filter = gr.fir_filter_fff( 1, gr.firdes.low_pass(1, symbolrate * samplepersymbol, symbolrate * 2, symbolrate / 2.0, gr.firdes.WIN_HAMMING, 6.76)) self.digital_clock_recovery_mm = digital.clock_recovery_mm_ff( samplepersymbol, 0.03 * 0.03 * 0.3, 0.4, 0.03, 1e-4) self.digital_binary_slicer_fb = digital.binary_slicer_fb() self.pktdecoder = pocsag_pktdecoder(channel_str=channel_str, sendmsg=sendmsg, debug=debug) self.connect(self, self.fractional_interpolator, self.quadrature_demod, self.low_pass_filter, self.digital_clock_recovery_mm, self.digital_binary_slicer_fb, self.pktdecoder, self)
def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq, max_dev, ctcss): gr.hier_block2.__init__( self, "rx_channel_nfm", gr.io_signature(1, 1, gr.sizeof_gr_complex), # gr.io_signature(0, 0, 0)) gr.io_signature(1, 1, gr.sizeof_float)) output_sample_rate = 8000 chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps, lo_freq, usrp_rate) nphases = 32 frac_bw = 0.45 rs_taps = gr.firdes.low_pass(nphases, nphases, frac_bw, 0.5 - frac_bw) resampler = blks2.pfb_arb_resampler_ccf( float(output_sample_rate) / channel_rate, (rs_taps), nphases) # FM Demodulator input: complex; output: float k = output_sample_rate / (2 * math.pi * max_dev) fm_demod = gr.quadrature_demod_cf(k) self.connect(self, chan, resampler, fm_demod) if ctcss > 0: level = 5.0 len = 0 ramp = 0 gate = True ctcss = repeater.ctcss_squelch_ff(output_sample_rate, ctcss, level, len, ramp, gate) self.connect(fm_demod, ctcss, self) else: self.connect(fm_demod, self)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Op25 Grc") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self._config_freq_config = ConfigParser.ConfigParser() self._config_freq_config.read(".grc_op25") try: config_freq = self._config_freq_config.getfloat("main", "freq") except: config_freq = 489075000 self.config_freq = config_freq self.freq = freq = config_freq self._config_xlate_offset_config = ConfigParser.ConfigParser() self._config_xlate_offset_config.read(".grc_op25") try: config_xlate_offset = self._config_xlate_offset_config.getfloat( "main", "xlate_offset") except: config_xlate_offset = 0 self.config_xlate_offset = config_xlate_offset self.click_freq = click_freq = freq - config_xlate_offset self.xlate_offset_fine = xlate_offset_fine = 0 self.xlate_offset = xlate_offset = freq - click_freq self.samp_rate = samp_rate = 2000000 self.samp_per_sym = samp_per_sym = 6 self.decim = decim = 20 self._config_xlate_bandwidth_config = ConfigParser.ConfigParser() self._config_xlate_bandwidth_config.read(".grc_op25") try: config_xlate_bandwidth = self._config_xlate_bandwidth_config.getfloat( "main", "xlate_bandwidth") except: config_xlate_bandwidth = 24000 self.config_xlate_bandwidth = config_xlate_bandwidth self.auto_tune_offset = auto_tune_offset = 0 self.xlate_bandwidth = xlate_bandwidth = config_xlate_bandwidth self.variable_static_text_0 = variable_static_text_0 = freq + xlate_offset + xlate_offset_fine + auto_tune_offset self.pre_channel_rate = pre_channel_rate = samp_rate / decim self.gain = gain = 20 self.fine_click_freq = fine_click_freq = 0 self.channel_rate = channel_rate = op25.SYMBOL_RATE * samp_per_sym self.auto_tune_offset_freq = auto_tune_offset_freq = auto_tune_offset * op25.SYMBOL_DEVIATION self.audio_mul = audio_mul = 0 ################################################## # Message Queues ################################################## op25_decoder_simple_0_msgq_out = op25_traffic_pane_0_msgq_in = gr.msg_queue( 2) op25_fsk4_0_msgq_out = baz_message_callback_0_msgq_in = gr.msg_queue(2) ################################################## # Blocks ################################################## _xlate_offset_fine_sizer = wx.BoxSizer(wx.VERTICAL) self._xlate_offset_fine_text_box = forms.text_box( parent=self.GetWin(), sizer=_xlate_offset_fine_sizer, value=self.xlate_offset_fine, callback=self.set_xlate_offset_fine, label="Fine Offset", converter=forms.float_converter(), proportion=0, ) self._xlate_offset_fine_slider = forms.slider( parent=self.GetWin(), sizer=_xlate_offset_fine_sizer, value=self.xlate_offset_fine, callback=self.set_xlate_offset_fine, minimum=-10000, maximum=10000, num_steps=1000, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_xlate_offset_fine_sizer) self._xlate_offset_text_box = forms.text_box( parent=self.GetWin(), value=self.xlate_offset, callback=self.set_xlate_offset, label="Xlate Offset", converter=forms.float_converter(), ) self.Add(self._xlate_offset_text_box) _xlate_bandwidth_sizer = wx.BoxSizer(wx.VERTICAL) self._xlate_bandwidth_text_box = forms.text_box( parent=self.GetWin(), sizer=_xlate_bandwidth_sizer, value=self.xlate_bandwidth, callback=self.set_xlate_bandwidth, label="Xlate BW", converter=forms.float_converter(), proportion=0, ) self._xlate_bandwidth_slider = forms.slider( parent=self.GetWin(), sizer=_xlate_bandwidth_sizer, value=self.xlate_bandwidth, callback=self.set_xlate_bandwidth, minimum=5000, maximum=50000, num_steps=1000, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_xlate_bandwidth_sizer) self.nb = self.nb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.nb.AddPage(grc_wxgui.Panel(self.nb), "BB-1") self.nb.AddPage(grc_wxgui.Panel(self.nb), "BB-2") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Xlate-1") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Xlate-2") self.nb.AddPage(grc_wxgui.Panel(self.nb), "4FSK") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Dibits") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Traffic") self.Add(self.nb) _gain_sizer = wx.BoxSizer(wx.VERTICAL) self._gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, label="Gain", converter=forms.float_converter(), proportion=0, ) self._gain_slider = forms.slider( parent=self.GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, minimum=0, maximum=50, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_gain_sizer) self._freq_text_box = forms.text_box( parent=self.GetWin(), value=self.freq, callback=self.set_freq, label="Frequency", converter=forms.float_converter(), ) self.Add(self._freq_text_box) self._auto_tune_offset_freq_static_text = forms.static_text( parent=self.GetWin(), value=self.auto_tune_offset_freq, callback=self.set_auto_tune_offset_freq, label="Auto tune", converter=forms.float_converter(), ) self.Add(self._auto_tune_offset_freq_static_text) _audio_mul_sizer = wx.BoxSizer(wx.VERTICAL) self._audio_mul_text_box = forms.text_box( parent=self.GetWin(), sizer=_audio_mul_sizer, value=self.audio_mul, callback=self.set_audio_mul, label="Audio mul", converter=forms.float_converter(), proportion=0, ) self._audio_mul_slider = forms.slider( parent=self.GetWin(), sizer=_audio_mul_sizer, value=self.audio_mul, callback=self.set_audio_mul, minimum=-30, maximum=10, num_steps=40, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_audio_mul_sizer) self.wxgui_waterfallsink2_0_0 = waterfallsink2.waterfall_sink_c( self.nb.GetPage(3).GetWin(), baseband_freq=0, dynamic_range=100, ref_level=50, ref_scale=2.0, sample_rate=channel_rate, fft_size=512, fft_rate=15, average=False, avg_alpha=None, title="Waterfall Plot", ) self.nb.GetPage(3).Add(self.wxgui_waterfallsink2_0_0.win) self.wxgui_waterfallsink2_0 = waterfallsink2.waterfall_sink_c( self.nb.GetPage(1).GetWin(), baseband_freq=freq, dynamic_range=100, ref_level=50, ref_scale=2.0, sample_rate=samp_rate, fft_size=512, fft_rate=15, average=False, avg_alpha=None, title="Waterfall Plot", ) self.nb.GetPage(1).Add(self.wxgui_waterfallsink2_0.win) self.wxgui_scopesink2_1 = scopesink2.scope_sink_f( self.nb.GetPage(4).GetWin(), title="Scope Plot", sample_rate=channel_rate, v_scale=1.5, v_offset=0, t_scale=0.05, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.nb.GetPage(4).Add(self.wxgui_scopesink2_1.win) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.nb.GetPage(5).GetWin(), title="Scope Plot", sample_rate=op25.SYMBOL_RATE, v_scale=1, v_offset=0, t_scale=0.05, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.nb.GetPage(5).Add(self.wxgui_scopesink2_0.win) self.wxgui_fftsink2_0_0 = fftsink2.fft_sink_c( self.nb.GetPage(2).GetWin(), baseband_freq=fine_click_freq, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=channel_rate, fft_size=1024, fft_rate=30, average=True, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.nb.GetPage(2).Add(self.wxgui_fftsink2_0_0.win) def wxgui_fftsink2_0_0_callback(x, y): self.set_fine_click_freq(x) self.wxgui_fftsink2_0_0.set_callback(wxgui_fftsink2_0_0_callback) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.nb.GetPage(0).GetWin(), baseband_freq=freq, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=30, average=True, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.nb.GetPage(0).Add(self.wxgui_fftsink2_0.win) def wxgui_fftsink2_0_callback(x, y): self.set_click_freq(x) self.wxgui_fftsink2_0.set_callback(wxgui_fftsink2_0_callback) self._variable_static_text_0_static_text = forms.static_text( parent=self.GetWin(), value=self.variable_static_text_0, callback=self.set_variable_static_text_0, label="Final freq", converter=forms.float_converter(), ) self.Add(self._variable_static_text_0_static_text) self.osmosdr_source_c_0 = osmosdr.source_c(args="nchan=" + str(1) + " " + "hackrf=0") self.osmosdr_source_c_0.set_sample_rate(samp_rate) self.osmosdr_source_c_0.set_center_freq(freq, 0) self.osmosdr_source_c_0.set_freq_corr(0, 0) self.osmosdr_source_c_0.set_dc_offset_mode(0, 0) self.osmosdr_source_c_0.set_iq_balance_mode(0, 0) self.osmosdr_source_c_0.set_gain_mode(0, 0) self.osmosdr_source_c_0.set_gain(14, 0) self.osmosdr_source_c_0.set_if_gain(gain, 0) self.osmosdr_source_c_0.set_bb_gain(gain, 0) self.osmosdr_source_c_0.set_antenna("", 0) self.osmosdr_source_c_0.set_bandwidth(0, 0) self.op25_traffic_pane_0 = op25_traffic_pane.TrafficPane( parent=self.nb.GetPage(6).GetWin(), msgq=op25_traffic_pane_0_msgq_in) self.nb.GetPage(6).Add(self.op25_traffic_pane_0) self.op25_fsk4_0 = op25.op25_fsk4( channel_rate=channel_rate, auto_tune_msgq=op25_fsk4_0_msgq_out, ) self.op25_decoder_simple_0 = op25.op25_decoder_simple( key="", traffic_msgq=op25_decoder_simple_0_msgq_out, ) self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf( (channel_rate / (2.0 * math.pi * op25.SYMBOL_DEVIATION))) self.gr_freq_xlating_fir_filter_xxx_0 = gr.freq_xlating_fir_filter_ccc( decim, (firdes.low_pass(1, samp_rate, xlate_bandwidth / 2, 6000)), xlate_offset + xlate_offset_fine - fine_click_freq - auto_tune_offset_freq, samp_rate) self.gr_fir_filter_xxx_0 = gr.fir_filter_fff( 1, ((1.0 / samp_per_sym, ) * samp_per_sym)) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff( (10.**(audio_mul / 10.), )) self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_ccc( interpolation=channel_rate, decimation=pre_channel_rate, taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff( interpolation=44100, decimation=8000, taps=None, fractional_bw=None, ) self.baz_message_callback_0 = message_callback.message_callback( msgq=baz_message_callback_0_msgq_in, callback=auto_tune_offset, msg_part="arg1", custom_parts="", dummy=False) self.audio_sink_0 = audio.sink(44100, "", True) ################################################## # Connections ################################################## self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.wxgui_fftsink2_0_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.wxgui_waterfallsink2_0_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_quadrature_demod_cf_0, 0)) self.connect((self.gr_quadrature_demod_cf_0, 0), (self.gr_fir_filter_xxx_0, 0)) self.connect((self.gr_fir_filter_xxx_0, 0), (self.wxgui_scopesink2_1, 0)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.audio_sink_0, 0)) self.connect((self.gr_fir_filter_xxx_0, 0), (self.op25_fsk4_0, 0)) self.connect((self.op25_decoder_simple_0, 0), (self.blks2_rational_resampler_xxx_0, 0)) self.connect((self.op25_fsk4_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.osmosdr_source_c_0, 0), (self.wxgui_waterfallsink2_0, 0)) self.connect((self.osmosdr_source_c_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.osmosdr_source_c_0, 0), (self.gr_freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.op25_fsk4_0, 0), (self.op25_decoder_simple_0, 0))
def __init__(self, talkgroup, options): gr.hier_block2.__init__(self, "fsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(0, 0, gr.sizeof_char)) # Output signature #print "Starting log_receiver init()" self.samp_rate = samp_rate = int(options.rate) self.samp_per_sym = samp_per_sym = 5+1 self.decim = decim = 20 self.xlate_bandwidth = xlate_bandwidth = 24260.0 self.xlate_offset = xlate_offset = 0 self.channel_rate = channel_rate = op25.SYMBOL_RATE*samp_per_sym self.audio_mul = audio_mul = 2 self.pre_channel_rate = pre_channel_rate = int(samp_rate/decim) self.auto_tune_offset = auto_tune_offset = 0 self.audiorate = 44100 #options.audiorate self.rate = options.rate self.talkgroup = talkgroup self.directory = options.directory if options.squelch is None: options.squelch = 28 if options.volume is None: options.volume = 3.0 ################################################## # Message Queues ################################################## op25_fsk4_0_msgq_out = baz_message_callback_0_msgq_in = gr.msg_queue(2) op25_decoder_simple_0_msgq_out = op25_traffic_pane_0_msgq_in = gr.msg_queue(2) ################################################## # Blocks ################################################## self.op25_fsk4_0 = op25.op25_fsk4(channel_rate=channel_rate, auto_tune_msgq=op25_fsk4_0_msgq_out,) self.op25_decoder_simple_0 = op25.op25_decoder_simple(key="",traffic_msgq=op25_decoder_simple_0_msgq_out,) self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf((channel_rate/(2.0 * math.pi * op25.SYMBOL_DEVIATION))) self.gr_freq_xlating_fir_filter_xxx_0 = gr.freq_xlating_fir_filter_ccc(decim, (firdes.low_pass(1, samp_rate, xlate_bandwidth/2, 4000)), 0, samp_rate) self.gr_fir_filter_xxx_0 = gr.fir_filter_fff(1, ((1.0/samp_per_sym,)*samp_per_sym)) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((10.**(audio_mul/10.), )) self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_ccc( interpolation=channel_rate, decimation=pre_channel_rate, taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff( interpolation=self.audiorate, decimation=8000, taps=None, fractional_bw=None, ) self.baz_message_callback_0 = message_callback.message_callback(msgq=baz_message_callback_0_msgq_in, callback=auto_tune_offset , msg_part="arg1", custom_parts="", dummy=False) #here we generate a random filename in the form /tmp/[random].wav, and then use it for the wavstamp block. this avoids collisions later on. remember to clean up these files when deallocating. self.tmpfilename = "/tmp/%s.wav" % ("".join([random.choice(string.letters+string.digits) for x in range(8)])) #if this looks glaringly different, it's because i totally cribbed it from a blog. self.valve = grc_blks2.valve(gr.sizeof_float, bool(1)) #open the logfile for appending self.timestampfilename = "%s/%i.txt" % (self.directory, self.talkgroup) self.timestampfile = open(self.timestampfilename, 'a'); self.filename = "%s/%i.wav" % (self.directory, self.talkgroup) self.audiosink = smartnet.wavsink(self.filename, 1, self.audiorate, 8) #this version allows appending to existing files. self.audio_sink_0 = audio.sink(44100, "", True) self.timestamp = 0.0 #print "Finishing logging receiver init()." self.mute() #start off muted. ################################################## # Connections ################################################## self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_quadrature_demod_cf_0, 0)) self.connect((self.gr_quadrature_demod_cf_0, 0), (self.gr_fir_filter_xxx_0, 0)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.gr_fir_filter_xxx_0, 0), (self.op25_fsk4_0, 0)) self.connect((self.op25_fsk4_0, 0), (self.op25_decoder_simple_0, 0)) self.connect((self.op25_decoder_simple_0, 0), (self.blks2_rational_resampler_xxx_0, 0)) ## Start self.connect(self, (self.gr_freq_xlating_fir_filter_xxx_0, 0)) ## End self.connect((self.blocks_multiply_const_vxx_0, 0), (self.audio_sink_0,0))
def __init__(self): gr.top_block.__init__(self) usage = "%prog: [options] [input file]" parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option("-c", "--channel", type="string", default='AA', help="two-letter channel code (default: AA)") parser.add_option("-a", "--automatic", action="store_true", default=False, help="automatically determine and transmit reponse") parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0), help="select USRP Rx side A or B (default=A)") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set USRP gain in dB (default is midpoint)") parser.add_option("-s", "--squelch", type="eng_float", default=20, help="set squelch in dB") (options, args) = parser.parse_args() inf_str = None decim = 64 #1M Samp/sec symbol_rate = 152.34e3 sample_rate = 64e6 / decim if len(args) != 0: inf_str = args[0] squelch = gr.pwr_squelch_cc(float(options.squelch), 0.1, 0, True) demod = gr.quadrature_demod_cf(1.0) #cr = gr.clock_recovery_mm_ff(6.5643, 0.00765625, 0, 0.175, 0.005) cr = gr.clock_recovery_mm_ff(sample_rate / symbol_rate, 0.00765625, 0, 0.175, 0.005) slicer = gr.binary_slicer_fb() corr = gr.correlate_access_code_bb(AC, 0) sink = clicker.sniffer() if inf_str is not None: print "Reading from: " + inf_str src = gr.file_source(gr.sizeof_gr_complex, inf_str, False) else: freqs = { 'AA': 917.0e6, 'AB': 913.0e6, 'AC': 914.0e6, 'AD': 915.0e6, 'BA': 916.0e6, 'BB': 919.0e6, 'BC': 920.0e6, 'BD': 921.0e6, 'CA': 922.0e6, 'CB': 923.0e6, 'CC': 907.0e6, 'CD': 908.0e6, 'DA': 905.5e6, 'DB': 909.0e6, 'DC': 911.0e6, 'DD': 910.0e6 } frequency = freqs[options.channel] print "Channel: " + options.channel + " (" + str( frequency / 1e6) + "MHz)" src = usrp.source_c(decim_rate=decim) subdev = usrp.selected_subdev(src, options.rx_subdev_spec) print "Using RX board %s" % (subdev.side_and_name()) r = src.tune(0, subdev, frequency) if not r: raise SystemExit, "Failed to tune USRP. Are you using a 900MHz board?" if options.gain is None: # if no gain was specified, use the mid-point in dB g = subdev.gain_range() options.gain = float(g[0] + g[1]) / 2 subdev.set_gain(options.gain) print "Gain: " + str(options.gain) + "dB" self.connect(src, squelch, demod, cr, slicer, corr, sink)
def __init__(self, samples_per_symbol=_def_samples_per_symbol, gain_mu=_def_gain_mu, mu=_def_mu, costas_alpha=_def_costas_alpha, omega_relative_limit=_def_omega_relative_limit, freq_error=_def_freq_error, verbose=_def_verbose, log=_def_log): """ Hierarchical block for Gaussian Minimum Shift Key (GMSK) demodulation. The input is the complex modulated signal at baseband. The output is a stream of bits packed 1 bit per byte (the LSB) @param samples_per_symbol: samples per baud @type samples_per_symbol: integer @param verbose: Print information about modulator? @type verbose: bool @param log: Print modualtion data to files? @type log: bool Clock recovery parameters. These all have reasonble defaults. @param gain_mu: controls rate of mu adjustment @type gain_mu: float @param mu: fractional delay [0.0, 1.0] @type mu: float @param omega_relative_limit: sets max variation in omega @type omega_relative_limit: float, typically 0.000200 (200 ppm) @param freq_error: bit rate error as a fraction @param float """ gr.hier_block2.__init__( self, "gmsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self._samples_per_symbol = samples_per_symbol self._gain_mu = gain_mu self._mu = mu self._omega_relative_limit = omega_relative_limit self._freq_error = freq_error self._costas_alpha = costas_alpha if samples_per_symbol < 2: raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol self._omega = samples_per_symbol * (1 + self._freq_error) if not self._gain_mu: self._gain_mu = 0.175 self._gain_omega = .25 * self._gain_mu * self._gain_mu # critically damped # Demodulate FM sensitivity = (pi / 2) / samples_per_symbol self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) # the clock recovery block tracks the symbol clock and resamples as needed. # the output of the block is a stream of soft symbols (float) self.clock_recovery = gr.clock_recovery_mm_ff( self._omega, self._gain_omega, self._mu, self._gain_mu, self._omega_relative_limit) # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample self.slicer = gr.binary_slicer_fb() if verbose: self._print_verbage() if log: self._setup_logging() # Costas loop (carrier tracking) # FIXME: need to decide how to handle this more generally; do we pull it from higher layer? costas_order = 2 beta = .25 * self._costas_alpha * self._costas_alpha self.costas_loop = gr.costas_loop_cc(self._costas_alpha, beta, 0.002, -0.002, costas_order) # Connect & Initialize base class self.unpack = gr.unpacked_to_packed_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) #self.connect(self, self.fmdemod, self.clock_recovery, self.slicer,self.unpack, self) self.connect(self, self.fmdemod, self.slicer, self.unpack, self)
def __init__(self, samples_per_symbol=_def_samples_per_symbol, sensitivity=_def_sensitivity, gain_mu=_def_gain_mu, mu=_def_mu, omega_relative_limit=_def_omega_relative_limit, freq_error=_def_freq_error, verbose=_def_verbose, log=_def_log): """ Hierarchical block for Gaussian Minimum Shift Key (GFSK) demodulation. The input is the complex modulated signal at baseband. The output is a stream of bits packed 1 bit per byte (the LSB) @param samples_per_symbol: samples per baud @type samples_per_symbol: integer @param verbose: Print information about modulator? @type verbose: bool @param log: Print modualtion data to files? @type log: bool Clock recovery parameters. These all have reasonble defaults. @param gain_mu: controls rate of mu adjustment @type gain_mu: float @param mu: fractional delay [0.0, 1.0] @type mu: float @param omega_relative_limit: sets max variation in omega @type omega_relative_limit: float, typically 0.000200 (200 ppm) @param freq_error: bit rate error as a fraction @param float """ gr.hier_block2.__init__(self, "gfsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self._samples_per_symbol = samples_per_symbol self._gain_mu = gain_mu self._mu = mu self._omega_relative_limit = omega_relative_limit self._freq_error = freq_error self._differential = False if samples_per_symbol < 2: raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol self._omega = samples_per_symbol*(1+self._freq_error) if not self._gain_mu: self._gain_mu = 0.175 self._gain_omega = .25 * self._gain_mu * self._gain_mu # critically damped # Demodulate FM #sensitivity = (pi / 2) / samples_per_symbol self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) # the clock recovery block tracks the symbol clock and resamples as needed. # the output of the block is a stream of soft symbols (float) self.clock_recovery = digital.clock_recovery_mm_ff(self._omega, self._gain_omega, self._mu, self._gain_mu, self._omega_relative_limit) # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample self.slicer = digital.binary_slicer_fb() if verbose: self._print_verbage() if log: self._setup_logging() # Connect & Initialize base class self.connect(self, self.fmdemod, self.clock_recovery, self.slicer, self)
def __init__(self, options, queue): gr.top_block.__init__(self, "usrp_flex") self.options = options self.offset = 0.0 self.file_offset = 0.0 self.adj_time = time.time() self.verbose = options.verbose if options.from_file is None: self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + '' ) self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_center_freq(options.frequency, 0) self.rtlsdr_source_0.set_freq_corr(0, 0) self.rtlsdr_source_0.set_dc_offset_mode(0, 0) self.rtlsdr_source_0.set_iq_balance_mode(0, 0) self.rtlsdr_source_0.set_gain_mode(True, 0) self.rtlsdr_source_0.set_gain(50, 0) self.rtlsdr_source_0.set_if_gain(20, 0) self.rtlsdr_source_0.set_bb_gain(20, 0) self.rtlsdr_source_0.set_antenna('', 0) self.rtlsdr_source_0.set_bandwidth(0, 0) else: # Use supplied file as source of samples self.file_offset = options.calibration print "File input offset", self.offset self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file) if options.verbose: print "Reading samples from", options.from_file if options.log and not options.from_file: usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat') self.connect(self.src, usrp_sink) # following is rig to allow fast and easy swapping of signal configuration # blocks between this example and the oscope example which uses self.msgq self.msgq = queue #------------------------------------------------------------------------------- if options.protocol == 0: # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, self.symbol_rate = 9600 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 10 # decimation (final rate should be at least several symbol rate) self.max_frequency_offset = 12000.0 # coarse carrier tracker leash, ~ half a channel either way self.symbol_deviation = 1200.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.rdlap_f(self.msgq, 0) # desired protocol processing block selected here self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter characteristics channel_taps = optfir.low_pass(1.0, # Filter gain self.input_sample_rate, # Sample rate 10000, # One-sided modulation bandwidth 12000, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter characteristics symbol_coeffs = gr.firdes.root_raised_cosine (1.0, # gain self.channel_rate , # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type if options.protocol == 1: # ---------- APCO-25 C4FM Test Data self.symbol_rate = 4800 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 20 # decimation self.max_frequency_offset = 6000.0 # coarse carrier tracker leash self.symbol_deviation = 600.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.apco25_f(self.msgq, 0) self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter channel_taps = optfir.low_pass(1.0, # Filter gain self.input_sample_rate, # Sample rate 5000, # One-sided modulation bandwidth 6500, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter symbol_coeffs = gr.firdes.root_raised_cosine (1.0, # gain self.channel_rate , # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type # ---------- End of configuration if options.verbose: print "Channel filter has", len(channel_taps), "taps." self.chan = gr.freq_xlating_fir_filter_ccf(self.channel_decimation , # Decimation rate channel_taps, # Filter taps 0.0, # Offset frequency self.input_sample_rate) # Sample rate # also note: # this specifies the nominal frequency deviation for the 4-level fsk signal self.fm_demod_gain = self.channel_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = gr.quadrature_demod_cf (self.fm_demod_gain) symbol_decim = 1 self.symbol_filter = gr.fir_filter_fff (symbol_decim, symbol_coeffs) # eventually specify: sample rate, symbol rate self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate , self.symbol_rate) if options.log: chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat') self.connect(self.chan, chan_sink) if options.log: chan_sink2 = gr.file_sink(gr.sizeof_float, 'demod.dat') self.connect(self.demod_fsk4, chan_sink2) self.connect(self.src, self.chan, self.fm_demod, self.symbol_filter, self.demod_fsk4, self.protocol_processing)