def __init__(self, sps, gain_mu): gr.hier_block2.__init__(self, "fsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self._sps = float(sps) self._gain_mu = gain_mu # for the clock recovery block self._mu = 0.5 self._omega_relative_limit = 0.35 #first bring that input stream down to a manageable level self._clockrec_oversample = 3.0 self._decim = self._sps / self._clockrec_oversample print "Demodulator decimation: %f" % self._decim self._downsampletaps = filter.firdes.low_pass(1.0/self._decim, 1.0, 0.4, 0.05, filter.firdes.WIN_HANN) # self._downsample = filter.fft_filter_ccc(self._decim, # self._downsampletaps) #sure this works but it's a little heavy on the CPU at high rates self._downsample = pfb.arb_resampler_ccf(1/self._decim) self._clockrec_sps = self._sps / self._decim #using a pll to demod gets you a nice IIR LPF response for free self._demod = analog.pll_freqdet_cf(2.0 / self._clockrec_sps, #gain alpha, rad/samp 2*pi/self._clockrec_sps, #max freq, rad/samp -2*pi/self._clockrec_sps) #min freq, rad/samp #band edge filter FLL with a low bandwidth is very good #at synchronizing to continuous FSK signals self._carriertrack = digital.fll_band_edge_cc(self._clockrec_sps, 0.6, #rolloff factor 64, #taps 1.0) #loop bandwidth print "Samples per symbol: %f" % (self._clockrec_sps,) self._softbits = digital.clock_recovery_mm_ff(self._clockrec_sps, 0.25*self._gain_mu*self._gain_mu, #gain omega, = mu/2 * mu_gain^2 self._mu, #mu (decision threshold) self._gain_mu, #mu gain self._omega_relative_limit) #omega relative limit self._slicer = digital.binary_slicer_fb() if self._decim > 1: self.connect(self, self._downsample, self._carriertrack, self._demod, self._softbits, self._slicer, self) else: self.connect(self, self._carriertrack, self._demod, self._softbits, self._slicer, self)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 44100 ################################################## # Blocks ################################################## self.wxgui_numbersink2_0 = numbersink2.number_sink_f( self.GetWin(), unit="Hz", minval=50, maxval=280, factor=1, decimal_places=2, ref_level=0, sample_rate=samp_rate, number_rate=15, average=False, avg_alpha=None, label="Number Plot", peak_hold=False, show_gauge=True, ) self.Add(self.wxgui_numbersink2_0.win) self.blocks_moving_average_xx_0 = blocks.moving_average_ff(samp_rate / 50, 25 / pi, 200) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float * 1, 10) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.band_pass_filter_0 = filter.fir_filter_ccc( 1, firdes.complex_band_pass(1, samp_rate, 60, 255, 100, firdes.WIN_BLACKMAN, 6.76) ) self.audio_source_0 = audio.source(samp_rate, "default", True) self.analog_pll_freqdet_cf_0 = analog.pll_freqdet_cf( 200 * 2.0 * pi / samp_rate, 260 * 2.0 * pi / samp_rate, 60 * 2.0 * pi / samp_rate ) ################################################## # Connections ################################################## self.connect((self.blocks_moving_average_xx_0, 0), (self.wxgui_numbersink2_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.band_pass_filter_0, 0), (self.analog_pll_freqdet_cf_0, 0)) self.connect((self.audio_source_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_moving_average_xx_0, 0))
def test_pll_freqdet(self): expected_result = (0.0, 4.338889228818161e-08, 0.3776331578612825, 1.0993741049896133, 2.1332509128284287, 3.448827166947317, 5.017193050406445, 6.810936277840595, 8.804128662605573, 10.972292025122194, 13.292363360097312, 15.742678902380248, 18.302902979158944, 20.954030233328815, 23.678333003762834, 26.459293141999492, 29.2815901542755, 32.13105969864019, 34.99462836613535, 37.860284035876894, 40.71702547869386, 43.5548208542428, 46.364569172614004, 49.138038040003174, 51.86783994277676, 54.547378886619114, 57.17080592915505, 59.73298657053974, 62.229444428114014, 64.65634937843706, 67.01044048049889, 69.28902004673668, 71.48990028218192, 73.61137363954212, 75.65217724529884, 77.61146325478951, 79.48876920728905, 81.28396466515709, 82.9972452848542, 84.62912095897468, 86.18033873945902, 87.65188876657749, 89.0449983399466, 90.36106669970881, 91.6016768844999, 92.76854829957963, 93.86354857479924, 94.88865206171563, 95.84592204664062, 96.73751075064077, 97.56564154258655, 98.33257336525031, 99.04061259327368, 99.69208931723288, 100.28935141465512, 100.83475862103487, 101.33065881389933, 101.77937615484109, 102.18323480545271, 102.54452335342484, 102.8654948125462, 103.14836662270359, 103.39530879191456, 103.6084320383601, 103.78982336428665, 103.94148676616939, 104.06536695064705, 104.16337305045634, 104.23733119256288, 104.28900821409572, 104.32008794641274, 104.33220678900258, 104.32694185151738, 104.30578723783803, 104.27016590404165, 104.22144151636876, 104.16091845122337, 104.08982993720561, 104.00932619714447, 103.9205337379343, 103.82447234476369, 103.72213808688659, 103.6144440277858, 103.50225579907487, 103.38636788456353, 103.26755105212685, 103.14649306386876, 103.02383425002395, 102.90019122489248, 102.7761213129379, 102.65211069081985, 102.5286218192634, 102.40608158509168, 102.28486944325857, 102.16532927481605, 102.04778124488143, 101.93248622873554, 101.81969324369186, 101.70961573316195, 101.60243156665544) sampling_freq = 10e3 freq = sampling_freq / 100 loop_bw = math.pi/100.0 maxf = 1 minf = -1 src = analog.sig_source_c(sampling_freq, analog.GR_COS_WAVE, freq, 1.0) pll = analog.pll_freqdet_cf(loop_bw, maxf, minf) head = blocks.head(gr.sizeof_float, int (freq)) dst = blocks.vector_sink_f() self.tb.connect(src, pll, head) self.tb.connect(head, dst) self.tb.run() dst_data = dst.data() # convert it from normalized frequency to absolute frequency (Hz) dst_data = [i*(sampling_freq/(2*math.pi)) for i in dst_data] self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 3)
def __init__(self): gr.top_block.__init__(self, "Stereo Fm") Qt.QWidget.__init__(self) self.setWindowTitle("Stereo Fm") try: self.setWindowIcon(Qt.QIcon.fromTheme("gnuradio-grc")) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "stereo_fm") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.demod_rate = demod_rate = 192000 self.audio_decimation = audio_decimation = 4 self.audio_rate = audio_rate = demod_rate / audio_decimation self.width_of_transition_band = width_of_transition_band = audio_rate / 32 self.volume = volume = 1 self.stereo_carr_loop_bw = stereo_carr_loop_bw = 2.0 * math.pi * 10 / 100 self.samp_rate = samp_rate = 1000e3 self.range1 = range1 = 88.1 self.max_freq = max_freq = 2.0 * math.pi * (80) * 1e3 / demod_rate self.loop_bw = loop_bw = 2.0 * math.pi * 28 / 100 ################################################## # Blocks ################################################## self._range1_layout = Qt.QVBoxLayout() self._range1_tool_bar = Qt.QToolBar(self) self._range1_layout.addWidget(self._range1_tool_bar) self._range1_tool_bar.addWidget(Qt.QLabel("Tune" + ": ")) class qwt_counter_pyslot(Qwt.QwtCounter): def __init__(self, parent=None): Qwt.QwtCounter.__init__(self, parent) @pyqtSlot("double") def setValue(self, value): super(Qwt.QwtCounter, self).setValue(value) self._range1_counter = qwt_counter_pyslot() self._range1_counter.setRange(88, 108, 0.1) self._range1_counter.setNumButtons(2) self._range1_counter.setValue(self.range1) self._range1_tool_bar.addWidget(self._range1_counter) self._range1_counter.valueChanged.connect(self.set_range1) self._range1_slider = Qwt.QwtSlider(None, Qt.Qt.Horizontal, Qwt.QwtSlider.BottomScale, Qwt.QwtSlider.BgSlot) self._range1_slider.setRange(88, 108, 0.1) self._range1_slider.setValue(self.range1) self._range1_slider.setMinimumWidth(200) self._range1_slider.valueChanged.connect(self.set_range1) self._range1_layout.addWidget(self._range1_slider) self.top_layout.addLayout(self._range1_layout) self._volume_layout = Qt.QVBoxLayout() self._volume_tool_bar = Qt.QToolBar(self) self._volume_layout.addWidget(self._volume_tool_bar) self._volume_tool_bar.addWidget(Qt.QLabel("Volume" + ": ")) class qwt_counter_pyslot(Qwt.QwtCounter): def __init__(self, parent=None): Qwt.QwtCounter.__init__(self, parent) @pyqtSlot("double") def setValue(self, value): super(Qwt.QwtCounter, self).setValue(value) self._volume_counter = qwt_counter_pyslot() self._volume_counter.setRange(0.000001, 100, 0.01) self._volume_counter.setNumButtons(2) self._volume_counter.setValue(self.volume) self._volume_tool_bar.addWidget(self._volume_counter) self._volume_counter.valueChanged.connect(self.set_volume) self._volume_slider = Qwt.QwtSlider(None, Qt.Qt.Horizontal, Qwt.QwtSlider.BottomScale, Qwt.QwtSlider.BgSlot) self._volume_slider.setRange(0.000001, 100, 0.01) self._volume_slider.setValue(self.volume) self._volume_slider.setMinimumWidth(200) self._volume_slider.valueChanged.connect(self.set_volume) self._volume_layout.addWidget(self._volume_slider) self.top_layout.addLayout(self._volume_layout) self.stereo_carrier_pll_recovery = analog.pll_refout_cc( stereo_carr_loop_bw, -2.0 * math.pi * 18990 / demod_rate, -2.0 * math.pi * 19010 / demod_rate ) self.stereo_carrier__filter = filter.fir_filter_fcc( 1, firdes.complex_band_pass(1, demod_rate, -19020, -18980, width_of_transition_band, firdes.WIN_HAMMING, 6.76), ) self.stereo_carr_gen = blocks.multiply_vcc(1) self.rtl2832_source_0 = baz.rtl_source_c(defer_creation=True, output_size=gr.sizeof_gr_complex) self.rtl2832_source_0.set_verbose(True) self.rtl2832_source_0.set_vid(0x0) self.rtl2832_source_0.set_pid(0x0) self.rtl2832_source_0.set_tuner_name("") self.rtl2832_source_0.set_default_timeout(0) self.rtl2832_source_0.set_use_buffer(True) self.rtl2832_source_0.set_fir_coefficients(([])) self.rtl2832_source_0.set_read_length(0) if self.rtl2832_source_0.create() == False: raise Exception("Failed to create RTL2832 Source: rtl2832_source_0") self.rtl2832_source_0.set_sample_rate(samp_rate) self.rtl2832_source_0.set_frequency(range1 * 1e6) self.rtl2832_source_0.set_auto_gain_mode(True) self.rtl2832_source_0.set_relative_gain(True) self.rtl2832_source_0.set_gain(1) self.root_raised_cosine_filter_0 = filter.fir_filter_ccf( 1, firdes.root_raised_cosine(1, 192000, 2375 / 2, 0.4, 100) ) self.rational_resampler_xxx_0_0 = filter.rational_resampler_ccc( interpolation=demod_rate, decimation=int(samp_rate), taps=None, fractional_bw=None ) self.qtgui_const_sink_x_1 = qtgui.const_sink_c(1024, "", 1) # size # name # number of inputs self.qtgui_const_sink_x_1.set_update_time(0.10) self.qtgui_const_sink_x_1.set_y_axis(-2, 2) self.qtgui_const_sink_x_1.set_x_axis(-2, 2) self.qtgui_const_sink_x_1.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, "") self.qtgui_const_sink_x_1.enable_autoscale(True) self.qtgui_const_sink_x_1.enable_grid(True) labels = ["", "", "", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "red", "red", "red", "red", "red", "red", "red", "red"] styles = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] markers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_const_sink_x_1.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_const_sink_x_1.set_line_label(i, labels[i]) self.qtgui_const_sink_x_1.set_line_width(i, widths[i]) self.qtgui_const_sink_x_1.set_line_color(i, colors[i]) self.qtgui_const_sink_x_1.set_line_style(i, styles[i]) self.qtgui_const_sink_x_1.set_line_marker(i, markers[i]) self.qtgui_const_sink_x_1.set_line_alpha(i, alphas[i]) self._qtgui_const_sink_x_1_win = sip.wrapinstance(self.qtgui_const_sink_x_1.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_const_sink_x_1_win) self.fm_demod = analog.pll_freqdet_cf(loop_bw, max_freq, -max_freq) self.digital_mpsk_receiver_cc_0 = digital.mpsk_receiver_cc( 2, 0, 1 * cmath.pi / 100.0, -0.06, 0.06, 0.5, 0.05, demod_rate / 2375.0, 0.001, 0.005 ) self.RDS_signal_gen = blocks.multiply_vcc(1) self.RDS_sig_filter = filter.fir_filter_fcc( 1, firdes.complex_band_pass( 1, demod_rate, 57000 - 1500, 57000 + 1500, width_of_transition_band, firdes.WIN_HAMMING, 6.76 ), ) self.RDS_carr_gen = blocks.multiply_vcc(1) ################################################## # Connections ################################################## self.connect((self.RDS_carr_gen, 0), (self.RDS_signal_gen, 0)) self.connect((self.RDS_sig_filter, 0), (self.RDS_signal_gen, 1)) self.connect((self.RDS_signal_gen, 0), (self.root_raised_cosine_filter_0, 0)) self.connect((self.digital_mpsk_receiver_cc_0, 0), (self.qtgui_const_sink_x_1, 0)) self.connect((self.fm_demod, 0), (self.RDS_sig_filter, 0)) self.connect((self.fm_demod, 0), (self.stereo_carrier__filter, 0)) self.connect((self.rational_resampler_xxx_0_0, 0), (self.fm_demod, 0)) self.connect((self.root_raised_cosine_filter_0, 0), (self.digital_mpsk_receiver_cc_0, 0)) self.connect((self.rtl2832_source_0, 0), (self.rational_resampler_xxx_0_0, 0)) self.connect((self.stereo_carr_gen, 0), (self.RDS_carr_gen, 1)) self.connect((self.stereo_carrier__filter, 0), (self.stereo_carrier_pll_recovery, 0)) self.connect((self.stereo_carrier_pll_recovery, 0), (self.RDS_carr_gen, 0)) self.connect((self.stereo_carrier_pll_recovery, 0), (self.stereo_carr_gen, 1)) self.connect((self.stereo_carrier_pll_recovery, 0), (self.stereo_carr_gen, 0))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Stereo FM receiver and RDS Decoder") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.xlate_decim = xlate_decim = 4 self.samp_rate = samp_rate = 1000000 self.freq_offset = freq_offset = 250e3 self.freq = freq = 88.5e6 self.baseband_rate = baseband_rate = samp_rate/xlate_decim self.audio_decim = audio_decim = 4 self.xlate_bandwidth = xlate_bandwidth = 250e3 self.volume = volume = 0 self.loop_bw = loop_bw = 16e3*0 + 18e3*1 self.gain = gain = 10 self.freq_tune = freq_tune = freq - freq_offset self.audio_rate = audio_rate = 48000 self.audio_decim_rate = audio_decim_rate = baseband_rate/audio_decim self.antenna = antenna = 'TX/RX' ################################################## # Message Queues ################################################## gr_rds_data_decoder_0_msgq_out = gr_rds_panel_0_msgq_in = gr.msg_queue(2) ################################################## # Blocks ################################################## _volume_sizer = wx.BoxSizer(wx.VERTICAL) self._volume_text_box = forms.text_box( parent=self.GetWin(), sizer=_volume_sizer, value=self.volume, callback=self.set_volume, label="Volume", converter=forms.float_converter(), proportion=0, ) self._volume_slider = forms.slider( parent=self.GetWin(), sizer=_volume_sizer, value=self.volume, callback=self.set_volume, minimum=-20, maximum=10, num_steps=300, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_volume_sizer) self.nb = self.nb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.nb.AddPage(grc_wxgui.Panel(self.nb), "BB") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Demod") self.nb.AddPage(grc_wxgui.Panel(self.nb), "L+R") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Pilot") self.nb.AddPage(grc_wxgui.Panel(self.nb), "DSBSC") self.nb.AddPage(grc_wxgui.Panel(self.nb), "RDS Raw") self.nb.AddPage(grc_wxgui.Panel(self.nb), "L-R") self.nb.AddPage(grc_wxgui.Panel(self.nb), "RDS") self.Add(self.nb) _loop_bw_sizer = wx.BoxSizer(wx.VERTICAL) self._loop_bw_text_box = forms.text_box( parent=self.GetWin(), sizer=_loop_bw_sizer, value=self.loop_bw, callback=self.set_loop_bw, label="Loop BW", converter=forms.float_converter(), proportion=0, ) self._loop_bw_slider = forms.slider( parent=self.GetWin(), sizer=_loop_bw_sizer, value=self.loop_bw, callback=self.set_loop_bw, minimum=0, maximum=baseband_rate, num_steps=1000, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_loop_bw_sizer) _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=50, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_gain_sizer) self._freq_offset_text_box = forms.text_box( parent=self.GetWin(), value=self.freq_offset, callback=self.set_freq_offset, label="Freq Offset", converter=forms.float_converter(), ) self.Add(self._freq_offset_text_box) _freq_sizer = wx.BoxSizer(wx.VERTICAL) self._freq_text_box = forms.text_box( parent=self.GetWin(), sizer=_freq_sizer, value=self.freq, callback=self.set_freq, label="Freq", converter=forms.float_converter(), proportion=0, ) self._freq_slider = forms.slider( parent=self.GetWin(), sizer=_freq_sizer, value=self.freq, callback=self.set_freq, minimum=87.5e6, maximum=108e6, num_steps=205, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_freq_sizer) self._antenna_chooser = forms.drop_down( parent=self.GetWin(), value=self.antenna, callback=self.set_antenna, label="Antenna", choices=['TX/RX', 'RX2'], labels=[], ) self.Add(self._antenna_chooser) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.nb.GetPage(3).GetWin(), title="Pilot", sample_rate=baseband_rate, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=wxgui.TRIG_MODE_AUTO, y_axis_label="Counts", ) self.nb.GetPage(3).Add(self.wxgui_scopesink2_0.win) self.wxgui_fftsink2_0_0_0_1_0_1 = fftsink2.fft_sink_f( self.nb.GetPage(7).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=-50, ref_scale=2.0, sample_rate=baseband_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="RDS", peak_hold=False, ) self.nb.GetPage(7).Add(self.wxgui_fftsink2_0_0_0_1_0_1.win) self.wxgui_fftsink2_0_0_0_1_0_0 = fftsink2.fft_sink_f( self.nb.GetPage(6).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=-50, ref_scale=2.0, sample_rate=baseband_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="L-R", peak_hold=False, ) self.nb.GetPage(6).Add(self.wxgui_fftsink2_0_0_0_1_0_0.win) self.wxgui_fftsink2_0_0_0_1_0 = fftsink2.fft_sink_f( self.nb.GetPage(5).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=baseband_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="RDS", peak_hold=False, ) self.nb.GetPage(5).Add(self.wxgui_fftsink2_0_0_0_1_0.win) self.wxgui_fftsink2_0_0_0_1 = fftsink2.fft_sink_f( self.nb.GetPage(4).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=baseband_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="DSBSC Sub-carrier", peak_hold=False, ) self.nb.GetPage(4).Add(self.wxgui_fftsink2_0_0_0_1.win) self.wxgui_fftsink2_0_0_0 = fftsink2.fft_sink_f( self.nb.GetPage(2).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=audio_decim_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="L+R", peak_hold=False, ) self.nb.GetPage(2).Add(self.wxgui_fftsink2_0_0_0.win) self.wxgui_fftsink2_0_0 = fftsink2.fft_sink_f( self.nb.GetPage(1).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=baseband_rate, fft_size=1024, fft_rate=15, average=True, avg_alpha=0.8, title="FM Demod", peak_hold=False, ) self.nb.GetPage(1).Add(self.wxgui_fftsink2_0_0.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.nb.GetPage(0).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=-30, ref_scale=2.0, sample_rate=baseband_rate, fft_size=1024, fft_rate=15, average=True, avg_alpha=0.8, title="Baseband", peak_hold=False, ) self.nb.GetPage(0).Add(self.wxgui_fftsink2_0.win) self.uhd_usrp_source_0 = uhd.usrp_source( ",".join(("", "")), 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(freq_tune, 0) self.uhd_usrp_source_0.set_gain(gain, 0) self.uhd_usrp_source_0.set_antenna(antenna, 0) self.rational_resampler_xxx_1 = filter.rational_resampler_fff( interpolation=audio_rate, decimation=audio_decim_rate, taps=None, fractional_bw=None, ) self.rational_resampler_xxx_0 = filter.rational_resampler_fff( interpolation=audio_rate, decimation=audio_decim_rate, taps=None, fractional_bw=None, ) self.gr_rds_panel_0 = rds.rdsPanel(gr_rds_panel_0_msgq_in, freq, self.GetWin()) self.Add(self.gr_rds_panel_0) self.gr_rds_freq_divider_0 = rds.freq_divider(16) self.gr_rds_data_decoder_0 = rds.data_decoder(gr_rds_data_decoder_0_msgq_out) self.gr_rds_bpsk_demod_0 = rds.bpsk_demod(audio_decim_rate) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(xlate_decim, (firdes.low_pass(1, samp_rate, xlate_bandwidth/2, 1000)), freq_offset, samp_rate) self.fir_filter_xxx_7 = filter.fir_filter_fff(audio_decim, (firdes.low_pass(1,baseband_rate,1.2e3,1.5e3,firdes.WIN_HAMMING))) self.fir_filter_xxx_7.declare_sample_delay(0) self.fir_filter_xxx_6 = filter.fir_filter_fff(audio_decim, (firdes.low_pass(1,baseband_rate,1.5e3,2e3,firdes.WIN_HAMMING))) self.fir_filter_xxx_6.declare_sample_delay(0) self.fir_filter_xxx_5 = filter.fir_filter_fff(audio_decim, (firdes.low_pass(1.0,baseband_rate,15e3,1e3,firdes.WIN_HAMMING))) self.fir_filter_xxx_5.declare_sample_delay(0) self.fir_filter_xxx_4 = filter.fir_filter_fff(1, (firdes.band_pass(1.0,baseband_rate,57e3-3e3,57e3+3e3,3e3,firdes.WIN_HAMMING))) self.fir_filter_xxx_4.declare_sample_delay(0) self.fir_filter_xxx_3 = filter.fir_filter_fff(1, (firdes.band_pass(1.0,baseband_rate,38e3-15e3/2,38e3+15e3/2,1e3,firdes.WIN_HAMMING))) self.fir_filter_xxx_3.declare_sample_delay(0) self.fir_filter_xxx_2 = filter.fir_filter_fff(1, (firdes.band_pass(1.0,baseband_rate,19e3-500,19e3+500,1e3,firdes.WIN_HAMMING))) self.fir_filter_xxx_2.declare_sample_delay(0) self.fir_filter_xxx_1 = filter.fir_filter_fff(audio_decim, (firdes.low_pass(1.0,baseband_rate,15e3,1e3,firdes.WIN_HAMMING))) self.fir_filter_xxx_1.declare_sample_delay(0) self.fir_filter_xxx_0 = filter.fir_filter_ccc(1, (firdes.low_pass(1.0, baseband_rate, 80e3,35e3,firdes.WIN_HAMMING))) self.fir_filter_xxx_0.declare_sample_delay(0) self.digital_diff_decoder_bb_0 = digital.diff_decoder_bb(2) self.blocks_sub_xx_0 = blocks.sub_ff(1) self.blocks_multiply_xx_0_0 = blocks.multiply_vff(1) self.blocks_multiply_xx_0 = blocks.multiply_vff(1) self.blocks_multiply_const_vxx_1 = blocks.multiply_const_vff((10**(1.*volume/10), )) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((10**(1.*volume/10), )) self.blocks_add_xx_0 = blocks.add_vff(1) self.audio_sink_0 = audio.sink(audio_rate, "", True) self.analog_pll_freqdet_cf_0 = analog.pll_freqdet_cf(1.0*0 + (loop_bw*2*math.pi/baseband_rate), +(2.0 * math.pi * 90e3 / baseband_rate), -(2.0 * math.pi * 90e3 / baseband_rate)) self.analog_fm_deemph_1 = analog.fm_deemph(fs=baseband_rate, tau=75e-6) self.analog_fm_deemph_0 = analog.fm_deemph(fs=baseband_rate, tau=75e-6) ################################################## # Connections ################################################## self.connect((self.uhd_usrp_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.fir_filter_xxx_0, 0)) self.connect((self.fir_filter_xxx_2, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.fir_filter_xxx_2, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.fir_filter_xxx_2, 0), (self.blocks_multiply_xx_0_0, 0)) self.connect((self.fir_filter_xxx_2, 0), (self.blocks_multiply_xx_0_0, 1)) self.connect((self.fir_filter_xxx_3, 0), (self.blocks_multiply_xx_0, 2)) self.connect((self.fir_filter_xxx_4, 0), (self.blocks_multiply_xx_0_0, 3)) self.connect((self.fir_filter_xxx_2, 0), (self.blocks_multiply_xx_0_0, 2)) self.connect((self.fir_filter_xxx_1, 0), (self.blocks_sub_xx_0, 0)) self.connect((self.fir_filter_xxx_2, 0), (self.gr_rds_freq_divider_0, 0)) self.connect((self.fir_filter_xxx_1, 0), (self.blocks_add_xx_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.fir_filter_xxx_5, 0)) self.connect((self.gr_rds_freq_divider_0, 0), (self.fir_filter_xxx_7, 0)) self.connect((self.fir_filter_xxx_7, 0), (self.gr_rds_bpsk_demod_0, 1)) self.connect((self.digital_diff_decoder_bb_0, 0), (self.gr_rds_data_decoder_0, 0)) self.connect((self.gr_rds_bpsk_demod_0, 0), (self.digital_diff_decoder_bb_0, 0)) self.connect((self.fir_filter_xxx_6, 0), (self.gr_rds_bpsk_demod_0, 0)) self.connect((self.fir_filter_xxx_2, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.fir_filter_xxx_1, 0), (self.wxgui_fftsink2_0_0_0, 0)) self.connect((self.fir_filter_xxx_3, 0), (self.wxgui_fftsink2_0_0_0_1, 0)) self.connect((self.fir_filter_xxx_4, 0), (self.wxgui_fftsink2_0_0_0_1_0, 0)) self.connect((self.blocks_multiply_xx_0_0, 0), (self.fir_filter_xxx_6, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.wxgui_fftsink2_0_0_0_1_0_0, 0)) self.connect((self.fir_filter_xxx_5, 0), (self.blocks_add_xx_0, 1)) self.connect((self.fir_filter_xxx_5, 0), (self.blocks_sub_xx_0, 1)) self.connect((self.fir_filter_xxx_0, 0), (self.analog_pll_freqdet_cf_0, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.wxgui_fftsink2_0_0, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.fir_filter_xxx_1, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.fir_filter_xxx_2, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.fir_filter_xxx_4, 0)) self.connect((self.blocks_add_xx_0, 0), (self.analog_fm_deemph_0, 0)) self.connect((self.blocks_multiply_xx_0_0, 0), (self.wxgui_fftsink2_0_0_0_1_0_1, 0)) self.connect((self.analog_fm_deemph_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.rational_resampler_xxx_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.audio_sink_0, 0)) self.connect((self.rational_resampler_xxx_1, 0), (self.audio_sink_0, 1)) self.connect((self.blocks_multiply_const_vxx_1, 0), (self.rational_resampler_xxx_1, 0)) self.connect((self.blocks_sub_xx_0, 0), (self.analog_fm_deemph_1, 0)) self.connect((self.analog_fm_deemph_1, 0), (self.blocks_multiply_const_vxx_1, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.fir_filter_xxx_3, 0))
def __init__(self): gr.top_block.__init__(self, "Top Block") Qt.QWidget.__init__(self) self.setWindowTitle("Top Block") try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "top_block") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.sr_rf = sr_rf = 2500000 self.decimate = decimate = 400 self.sr_lo = sr_lo = sr_rf/decimate self.f_rf = f_rf = 434645000 self.f_lo = f_lo = 455.2 ################################################## # Blocks ################################################## self.tab = Qt.QTabWidget() self.tab_widget_0 = Qt.QWidget() self.tab_layout_0 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tab_widget_0) self.tab_grid_layout_0 = Qt.QGridLayout() self.tab_layout_0.addLayout(self.tab_grid_layout_0) self.tab.addTab(self.tab_widget_0, "Tuning") self.tab_widget_1 = Qt.QWidget() self.tab_layout_1 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tab_widget_1) self.tab_grid_layout_1 = Qt.QGridLayout() self.tab_layout_1.addLayout(self.tab_grid_layout_1) self.tab.addTab(self.tab_widget_1, "IQ Display") self.tab_widget_2 = Qt.QWidget() self.tab_layout_2 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tab_widget_2) self.tab_grid_layout_2 = Qt.QGridLayout() self.tab_layout_2.addLayout(self.tab_grid_layout_2) self.tab.addTab(self.tab_widget_2, "PSK Output") self.top_layout.addWidget(self.tab) self._f_rf_layout = Qt.QVBoxLayout() self._f_rf_tool_bar = Qt.QToolBar(self) self._f_rf_layout.addWidget(self._f_rf_tool_bar) self._f_rf_tool_bar.addWidget(Qt.QLabel("RF Freq"+": ")) class qwt_counter_pyslot(Qwt.QwtCounter): def __init__(self, parent=None): Qwt.QwtCounter.__init__(self, parent) @pyqtSlot('double') def setValue(self, value): super(Qwt.QwtCounter, self).setValue(value) self._f_rf_counter = qwt_counter_pyslot() self._f_rf_counter.setRange(434644000, 434646000, 1) self._f_rf_counter.setNumButtons(2) self._f_rf_counter.setValue(self.f_rf) self._f_rf_tool_bar.addWidget(self._f_rf_counter) self._f_rf_counter.valueChanged.connect(self.set_f_rf) self._f_rf_slider = Qwt.QwtSlider(None, Qt.Qt.Horizontal, Qwt.QwtSlider.BottomScale, Qwt.QwtSlider.BgSlot) self._f_rf_slider.setRange(434644000, 434646000, 1) self._f_rf_slider.setValue(self.f_rf) self._f_rf_slider.setMinimumWidth(200) self._f_rf_slider.valueChanged.connect(self.set_f_rf) self._f_rf_layout.addWidget(self._f_rf_slider) self.tab_layout_0.addLayout(self._f_rf_layout) self._f_lo_layout = Qt.QVBoxLayout() self._f_lo_tool_bar = Qt.QToolBar(self) self._f_lo_layout.addWidget(self._f_lo_tool_bar) self._f_lo_tool_bar.addWidget(Qt.QLabel("LO Freq"+": ")) class qwt_counter_pyslot(Qwt.QwtCounter): def __init__(self, parent=None): Qwt.QwtCounter.__init__(self, parent) @pyqtSlot('double') def setValue(self, value): super(Qwt.QwtCounter, self).setValue(value) self._f_lo_counter = qwt_counter_pyslot() self._f_lo_counter.setRange(0, 2000, .1) self._f_lo_counter.setNumButtons(2) self._f_lo_counter.setValue(self.f_lo) self._f_lo_tool_bar.addWidget(self._f_lo_counter) self._f_lo_counter.valueChanged.connect(self.set_f_lo) self._f_lo_slider = Qwt.QwtSlider(None, Qt.Qt.Horizontal, Qwt.QwtSlider.BottomScale, Qwt.QwtSlider.BgSlot) self._f_lo_slider.setRange(0, 2000, .1) self._f_lo_slider.setValue(self.f_lo) self._f_lo_slider.setMinimumWidth(200) self._f_lo_slider.valueChanged.connect(self.set_f_lo) self._f_lo_layout.addWidget(self._f_lo_slider) self.tab_layout_0.addLayout(self._f_lo_layout) self.qtgui_time_sink_x_0 = qtgui.time_sink_c( sr_lo, #size sr_lo, #samp_rate "", #name 1 #number of inputs ) self.qtgui_time_sink_x_0.set_update_time(.03) self.qtgui_time_sink_x_0.set_y_axis(-.02, .02) self.qtgui_time_sink_x_0.set_y_label("Amplitude", "") self.qtgui_time_sink_x_0.enable_tags(-1, True) self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_0.enable_autoscale(False) self.qtgui_time_sink_x_0.enable_grid(True) labels = ["", "", "", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue"] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(2*1): if len(labels[i]) == 0: if(i % 2 == 0): self.qtgui_time_sink_x_0.set_line_label(i, "Re{{Data {0}}}".format(i/2)) else: self.qtgui_time_sink_x_0.set_line_label(i, "Im{{Data {0}}}".format(i/2)) else: self.qtgui_time_sink_x_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget) self.tab_layout_0.addWidget(self._qtgui_time_sink_x_0_win) self.qtgui_number_sink_1 = qtgui.number_sink( gr.sizeof_float, 0, qtgui.NUM_GRAPH_NONE, 1 ) self.qtgui_number_sink_1.set_update_time(0.10) self.qtgui_number_sink_1.set_title("") labels = ["Signal RMS", "", "", "", "", "", "", "", "", ""] units = ["", "", "", "", "", "", "", "", "", ""] colors = [("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black")] factor = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] for i in xrange(1): self.qtgui_number_sink_1.set_min(i, -1) self.qtgui_number_sink_1.set_max(i, 1) self.qtgui_number_sink_1.set_color(i, colors[i][0], colors[i][1]) if len(labels[i]) == 0: self.qtgui_number_sink_1.set_label(i, "Data {0}".format(i)) else: self.qtgui_number_sink_1.set_label(i, labels[i]) self.qtgui_number_sink_1.set_unit(i, units[i]) self.qtgui_number_sink_1.set_factor(i, factor[i]) self.qtgui_number_sink_1.enable_autoscale(False) self._qtgui_number_sink_1_win = sip.wrapinstance(self.qtgui_number_sink_1.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_number_sink_1_win) self.qtgui_number_sink_0 = qtgui.number_sink( gr.sizeof_float, 0, qtgui.NUM_GRAPH_HORIZ, 1 ) self.qtgui_number_sink_0.set_update_time(0.03) self.qtgui_number_sink_0.set_title("") labels = ["", "", "", "", "", "", "", "", "", ""] units = ["", "", "", "", "", "", "", "", "", ""] colors = [("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black")] factor = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] for i in xrange(1): self.qtgui_number_sink_0.set_min(i, -1) self.qtgui_number_sink_0.set_max(i, 1) self.qtgui_number_sink_0.set_color(i, colors[i][0], colors[i][1]) if len(labels[i]) == 0: self.qtgui_number_sink_0.set_label(i, "Data {0}".format(i)) else: self.qtgui_number_sink_0.set_label(i, labels[i]) self.qtgui_number_sink_0.set_unit(i, units[i]) self.qtgui_number_sink_0.set_factor(i, factor[i]) self.qtgui_number_sink_0.enable_autoscale(False) self._qtgui_number_sink_0_win = sip.wrapinstance(self.qtgui_number_sink_0.pyqwidget(), Qt.QWidget) self.tab_layout_0.addWidget(self._qtgui_number_sink_0_win) self.qtgui_const_sink_x_1 = qtgui.const_sink_c( 1024, #size "", #name 1 #number of inputs ) self.qtgui_const_sink_x_1.set_update_time(0.10) self.qtgui_const_sink_x_1.set_y_axis(-.02, .02) self.qtgui_const_sink_x_1.set_x_axis(-.02, .02) self.qtgui_const_sink_x_1.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, "") self.qtgui_const_sink_x_1.enable_autoscale(False) self.qtgui_const_sink_x_1.enable_grid(True) labels = ["", "", "", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "red", "red", "red", "red", "red", "red", "red", "red"] styles = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] markers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_const_sink_x_1.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_const_sink_x_1.set_line_label(i, labels[i]) self.qtgui_const_sink_x_1.set_line_width(i, widths[i]) self.qtgui_const_sink_x_1.set_line_color(i, colors[i]) self.qtgui_const_sink_x_1.set_line_style(i, styles[i]) self.qtgui_const_sink_x_1.set_line_marker(i, markers[i]) self.qtgui_const_sink_x_1.set_line_alpha(i, alphas[i]) self._qtgui_const_sink_x_1_win = sip.wrapinstance(self.qtgui_const_sink_x_1.pyqwidget(), Qt.QWidget) self.tab_layout_2.addWidget(self._qtgui_const_sink_x_1_win) self.qtgui_const_sink_x_0 = qtgui.const_sink_c( 1024, #size "", #name 1 #number of inputs ) self.qtgui_const_sink_x_0.set_update_time(0.10) self.qtgui_const_sink_x_0.set_y_axis(-.02, .02) self.qtgui_const_sink_x_0.set_x_axis(-.02, .02) self.qtgui_const_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, "") self.qtgui_const_sink_x_0.enable_autoscale(False) self.qtgui_const_sink_x_0.enable_grid(True) labels = ["", "", "", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "red", "red", "red", "red", "red", "red", "red", "red"] styles = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0] markers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_const_sink_x_0.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_const_sink_x_0.set_line_label(i, labels[i]) self.qtgui_const_sink_x_0.set_line_width(i, widths[i]) self.qtgui_const_sink_x_0.set_line_color(i, colors[i]) self.qtgui_const_sink_x_0.set_line_style(i, styles[i]) self.qtgui_const_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_const_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_const_sink_x_0_win = sip.wrapinstance(self.qtgui_const_sink_x_0.pyqwidget(), Qt.QWidget) self.tab_layout_0.addWidget(self._qtgui_const_sink_x_0_win) self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + "airspy=0" ) self.osmosdr_source_0.set_sample_rate(sr_rf) self.osmosdr_source_0.set_center_freq(f_rf, 0) self.osmosdr_source_0.set_freq_corr(0, 0) self.osmosdr_source_0.set_dc_offset_mode(0, 0) self.osmosdr_source_0.set_iq_balance_mode(0, 0) self.osmosdr_source_0.set_gain_mode(False, 0) self.osmosdr_source_0.set_gain(3, 0) self.osmosdr_source_0.set_if_gain(0, 0) self.osmosdr_source_0.set_bb_gain(0, 0) self.osmosdr_source_0.set_antenna("", 0) self.osmosdr_source_0.set_bandwidth(0, 0) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(100, (firdes.low_pass(1, sr_rf, 2000, 100)), f_lo, sr_rf) self.digital_mpsk_receiver_cc_0 = digital.mpsk_receiver_cc(2, 0, cmath.pi/100.0, -0.5, 0.5, 0.25, 0.01, 2, 0.001, 0.001) self.blocks_rms_xx_0 = blocks.rms_cf(0.0001) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((sr_lo / (2 * 3.14159), )) self.analog_pll_freqdet_cf_0 = analog.pll_freqdet_cf(.06, 0.6, -.6) ################################################## # Connections ################################################## self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.qtgui_time_sink_x_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.qtgui_const_sink_x_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.analog_pll_freqdet_cf_0, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.qtgui_number_sink_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.digital_mpsk_receiver_cc_0, 0)) self.connect((self.digital_mpsk_receiver_cc_0, 0), (self.qtgui_const_sink_x_1, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.blocks_rms_xx_0, 0)) self.connect((self.blocks_rms_xx_0, 0), (self.qtgui_number_sink_1, 0))
def test_pll_freqdet(self): expected_result = (0.0, 4.33888922882e-08, 0.367369994515, 1.08135249597, 2.10983253908, 3.42221529438, 4.98940390402, 6.78379190842, 8.77923286024, 10.9510106794, 13.2758363182, 15.7317829127, 18.2982902299, 20.9561068599, 23.6755271122, 26.452952094, 29.2731265301, 32.1219053479, 34.9862418188, 37.8540971414, 40.7144315483, 43.5571390869, 46.3730179743, 49.1537231663, 51.8917218889, 54.58026103, 57.2015358514, 59.7513664199, 62.2380533124, 64.657612252, 67.006640002, 69.2822432184, 71.4820384499, 73.6041047056, 75.6469478817, 77.6094829742, 79.4909866472, 81.2911031615, 83.0097850853, 84.6355598352, 86.1820937186, 87.6504420946, 89.0418441206, 90.3577286819, 91.5996432431, 92.7692775646, 93.8684162704, 94.8989269904, 95.8627662892, 96.7619381633, 97.598505899, 98.362769679, 99.0579904444, 99.6992633875, 100.288805948, 100.828805921, 101.321421457, 101.76878699, 102.17300138, 102.536116055, 102.860158727, 103.147085962, 103.398830608, 103.617254366, 103.792467691, 103.939387906, 104.060030865, 104.15631756, 104.230085975, 104.283067372, 104.316933727, 104.333238432, 104.333440018, 104.318914008, 104.290941063, 104.250742554, 104.187634452, 104.103822339, 104.013227468, 103.916810336, 103.815448432, 103.709936239, 103.600997093, 103.489283183, 103.375351833, 103.259712936, 103.142828952, 103.025091195, 102.90686726, 102.776726069, 102.648078982, 102.521459607, 102.397294831, 102.275999684, 102.157882471, 102.043215927, 101.93218978, 101.824958181, 101.72159228, 101.622151366) sampling_freq = 10e3 freq = sampling_freq / 100 loop_bw = math.pi/100.0 maxf = 1 minf = -1 src = analog.sig_source_c(sampling_freq, analog.GR_COS_WAVE, freq, 1.0) pll = analog.pll_freqdet_cf(loop_bw, maxf, minf) head = blocks.head(gr.sizeof_float, int (freq)) dst = blocks.vector_sink_f() self.tb.connect(src, pll, head) self.tb.connect(head, dst) self.tb.run() dst_data = dst.data() # convert it from normalized frequency to absolute frequency (Hz) dst_data = [i*(sampling_freq/(2*math.pi)) for i in dst_data] self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 3)
def __init__(self, demod_rate, audio_decimation): """ Hierarchical block for demodulating a broadcast FM signal. The input is the downconverted complex baseband signal (gr_complex). The output is two streams of the demodulated audio (float) 0=Left, 1=Right. Args: demod_rate: input sample rate of complex baseband input. (float) audio_decimation: how much to decimate demod_rate to get to audio. (integer) """ gr.hier_block2.__init__(self, "wfm_rcv_pll", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(2, 2, gr.sizeof_float)) # Output signature bandwidth = 250e3 audio_rate = demod_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 loop_bw = 2*math.pi/100.0 max_freq = 2.0*math.pi*90e3/demod_rate self.fm_demod = analog.pll_freqdet_cf(loop_bw, max_freq,-max_freq) # input: float; output: float self.deemph_Left = fm_deemph(audio_rate) self.deemph_Right = fm_deemph(audio_rate) # compute FIR filter taps for audio filter width_of_transition_band = audio_rate / 32 audio_coeffs = filter.firdes.low_pass(1.0 , # gain demod_rate, # sampling rate 15000 , width_of_transition_band, filter.firdes.WIN_HAMMING) # input: float; output: float self.audio_filter = filter.fir_filter_fff(audio_decimation, audio_coeffs) if 1: # Pick off the stereo carrier/2 with this filter. It attenuated 10 dB so apply 10 dB gain # We pick off the negative frequency half because we want to base band by it! ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO DEEMPHASIS stereo_carrier_filter_coeffs = \ filter.firdes.complex_band_pass(10.0, demod_rate, -19020, -18980, width_of_transition_band, filter.firdes.WIN_HAMMING) #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs) #print "stereo carrier filter ", stereo_carrier_filter_coeffs #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain stereo_dsbsc_filter_coeffs = \ filter.firdes.complex_band_pass(20.0, demod_rate, 38000-15000/2, 38000+15000/2, width_of_transition_band, filter.firdes.WIN_HAMMING) #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs # construct overlap add filter system from coefficients for stereo carrier self.stereo_carrier_filter = \ filter.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs) # carrier is twice the picked off carrier so arrange to do a commplex multiply self.stereo_carrier_generator = blocks.multiply_cc(); # Pick off the rds signal stereo_rds_filter_coeffs = \ filter.firdes.complex_band_pass(30.0, demod_rate, 57000 - 1500, 57000 + 1500, width_of_transition_band, filter.firdes.WIN_HAMMING) #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs # construct overlap add filter system from coefficients for stereo carrier self.rds_signal_filter = \ filter.fir_filter_fcc(audio_decimation, stereo_rds_filter_coeffs) self.rds_carrier_generator = blocks.multiply_cc(); self.rds_signal_generator = blocks.multiply_cc(); self_rds_signal_processor = blocks.null_sink(gr.sizeof_gr_complex); loop_bw = 2*math.pi/100.0 max_freq = -2.0*math.pi*18990/audio_rate; min_freq = -2.0*math.pi*19010/audio_rate; self.stereo_carrier_pll_recovery = \ analog.pll_refout_cc(loop_bw, max_freq, min_freq); #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now # set up mixer (multiplier) to get the L-R signal at baseband self.stereo_basebander = blocks.multiply_cc(); # pick off the real component of the basebanded L-R signal. The imaginary SHOULD be zero self.LmR_real = blocks.complex_to_real(); self.Make_Left = blocks.add_ff(); self.Make_Right = blocks.sub_ff(); self.stereo_dsbsc_filter = \ filter.fir_filter_fcc(audio_decimation, stereo_dsbsc_filter_coeffs) if 1: # send the real signal to complex filter to pick off the carrier and then to one side of a multiplier self.connect(self, self.fm_demod, self.stereo_carrier_filter, self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,0)) # send the already filtered carrier to the otherside of the carrier self.connect(self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1)) # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz. # send the new carrier to one side of the mixer (multiplier) self.connect(self.stereo_carrier_generator, (self.stereo_basebander,0)) # send the demphasized audio to the DSBSC pick off filter, the complex # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier self.connect(self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1)) # the result is BASEBANDED DSBSC with phase zero! # Pick off the real part since the imaginary is theoretically zero and then to one side of a summer self.connect(self.stereo_basebander, self.LmR_real, (self.Make_Left,0)) #take the same real part of the DSBSC baseband signal and send it to negative side of a subtracter self.connect(self.LmR_real,(self.Make_Right,1)) # Make rds carrier by taking the squared pilot tone and multiplying by pilot tone self.connect(self.stereo_basebander,(self.rds_carrier_generator,0)) self.connect(self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1)) # take signal, filter off rds, send into mixer 0 channel self.connect(self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0)) # take rds_carrier_generator output and send into mixer 1 channel self.connect(self.rds_carrier_generator,(self.rds_signal_generator,1)) # send basebanded rds signal and send into "processor" which for now is a null sink self.connect(self.rds_signal_generator,self_rds_signal_processor) if 1: # pick off the audio, L+R that is what we used to have and send it to the summer self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1)) # take the picked off L+R audio and send it to the PLUS side of the subtractor self.connect(self.audio_filter,(self.Make_Right, 0)) # The result of Make_Left gets (L+R) + (L-R) and results in 2*L # The result of Make_Right gets (L+R) - (L-R) and results in 2*R self.connect(self.Make_Left , self.deemph_Left, (self, 0)) self.connect(self.Make_Right, self.deemph_Right, (self, 1))
def __init__(self, meta_rate=1): gr.top_block.__init__(self, "Top Block") Qt.QWidget.__init__(self) self.setWindowTitle("Top Block") qtgui.util.check_set_qss() try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "top_block") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Parameters ################################################## self.meta_rate = meta_rate ################################################## # Variables ################################################## self.samp_rate = samp_rate = 500e3 self.decim = decim = 10 self.baud = baud = 4800 self.samps_per_symb = samps_per_symb = (samp_rate / decim * (24.0 / 25.0)) / baud ################################################## # Blocks ################################################## self.sarsat_sarp_msg_extract_0 = sarsat.sarp_msg_extract() self.sarsat_pds_frame_sync_0 = sarsat.pds_frame_sync('pds_sync') self.sarsat_biphase_l_decode_bb_0 = sarsat.biphase_l_decode_bb() self.rational_resampler_xxx_0_0 = filter.rational_resampler_ccc( interpolation=24, decimation=25, taps=None, fractional_bw=None, ) self.rational_resampler_xxx_0 = filter.rational_resampler_ccc( interpolation=1, decimation=10, taps=None, fractional_bw=None, ) self.qtgui_number_sink_0_0_0_0 = qtgui.number_sink( gr.sizeof_float, 0, qtgui.NUM_GRAPH_NONE, 1) self.qtgui_number_sink_0_0_0_0.set_update_time(0.010) self.qtgui_number_sink_0_0_0_0.set_title("") labels = ['Freq Offset', 'Phase', 'Error', '', '', '', '', '', '', ''] units = ['Hz', '', '', '', '', '', '', '', '', ''] colors = [("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black")] factor = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] for i in xrange(1): self.qtgui_number_sink_0_0_0_0.set_min(i, -32767) self.qtgui_number_sink_0_0_0_0.set_max(i, 32767) self.qtgui_number_sink_0_0_0_0.set_color(i, colors[i][0], colors[i][1]) if len(labels[i]) == 0: self.qtgui_number_sink_0_0_0_0.set_label( i, "Data {0}".format(i)) else: self.qtgui_number_sink_0_0_0_0.set_label(i, labels[i]) self.qtgui_number_sink_0_0_0_0.set_unit(i, units[i]) self.qtgui_number_sink_0_0_0_0.set_factor(i, factor[i]) self.qtgui_number_sink_0_0_0_0.enable_autoscale(False) self._qtgui_number_sink_0_0_0_0_win = sip.wrapinstance( self.qtgui_number_sink_0_0_0_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_number_sink_0_0_0_0_win, 3, 4, 1, 4) self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c( 2048, #size firdes.WIN_BLACKMAN_hARRIS, #wintype 0, #fc samp_rate / decim, #bw "", #name 1 #number of inputs ) self.qtgui_freq_sink_x_0.set_update_time(0.010) self.qtgui_freq_sink_x_0.set_y_axis(-80, 0) self.qtgui_freq_sink_x_0.set_y_label('Relative Gain', 'dB') self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "") self.qtgui_freq_sink_x_0.enable_autoscale(False) self.qtgui_freq_sink_x_0.enable_grid(True) self.qtgui_freq_sink_x_0.set_fft_average(1.0) self.qtgui_freq_sink_x_0.enable_axis_labels(True) self.qtgui_freq_sink_x_0.enable_control_panel(False) if not False: self.qtgui_freq_sink_x_0.disable_legend() if "complex" == "float" or "complex" == "msg_float": self.qtgui_freq_sink_x_0.set_plot_pos_half(not True) labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "dark blue" ] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_freq_sink_x_0.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_freq_sink_x_0.set_line_label(i, labels[i]) self.qtgui_freq_sink_x_0.set_line_width(i, widths[i]) self.qtgui_freq_sink_x_0.set_line_color(i, colors[i]) self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_freq_sink_x_0_win = sip.wrapinstance( self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_freq_sink_x_0_win, 0, 4, 3, 4) self.low_pass_filter_0 = filter.fir_filter_ccf( 1, firdes.low_pass(1, samp_rate / decim, 5e3, 1e3, firdes.WIN_HAMMING, 6.76)) self.fosphor_qt_sink_c_0 = fosphor.qt_sink_c() self.fosphor_qt_sink_c_0.set_fft_window(window.WIN_BLACKMAN_hARRIS) self.fosphor_qt_sink_c_0.set_frequency_range(0, samp_rate) self._fosphor_qt_sink_c_0_win = sip.wrapinstance( self.fosphor_qt_sink_c_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._fosphor_qt_sink_c_0_win, 0, 0, 4, 4) self.digital_correlate_access_code_tag_xx_0 = digital.correlate_access_code_tag_bb( '010000101011101100011111', 0, 'pds_sync') self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff( samps_per_symb * (1 + 0.0), 0.25 * 0.175 * 0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex * 1, samp_rate * 10, True) self.blocks_tagged_stream_to_pdu_0 = blocks.tagged_stream_to_pdu( blocks.float_t, 'rfo') self.blocks_stream_to_tagged_stream_0 = blocks.stream_to_tagged_stream( gr.sizeof_float, 1, 1, "rfo") self.blocks_socket_pdu_0_0 = blocks.socket_pdu("TCP_SERVER", '0.0.0.0', '8000', 10000, False) self.blocks_socket_pdu_0 = blocks.socket_pdu("TCP_SERVER", '0.0.0.0', '52001', 10000, False) self.blocks_multiply_const_vxx_1 = blocks.multiply_const_vff( (samp_rate / (2 * math.pi), )) self.blocks_moving_average_xx_0 = blocks.moving_average_ff( 10000, 0.0001, 4000, 1) self.blocks_message_debug_0 = blocks.message_debug() self.blocks_keep_one_in_n_0_0 = blocks.keep_one_in_n( gr.sizeof_float * 1, int(samp_rate * meta_rate)) self.blocks_file_source_0 = blocks.file_source( gr.sizeof_gr_complex * 1, '/home/zleffke/captures/sarsat/NOAA18_20161115_131537.305805540_UTC_500k.c32', True) self.blocks_file_source_0.set_begin_tag(pmt.PMT_NIL) self.analog_pll_freqdet_cf_0 = analog.pll_freqdet_cf( math.pi / 200, math.pi / 10, -math.pi / 10) self.analog_pll_carriertracking_cc_0 = analog.pll_carriertracking_cc( math.pi / 200, math.pi / 10, -math.pi / 10) self.analog_nbfm_rx_0 = analog.nbfm_rx( audio_rate=int(samp_rate / decim * 24 / 25), quad_rate=int(samp_rate / decim * 24 / 25), tau=75e-6, max_dev=5e3, ) self.analog_agc2_xx_0 = analog.agc2_cc(1e-1, 1e-2, 1.0, 1.0) self.analog_agc2_xx_0.set_max_gain(65536) ################################################## # Connections ################################################## self.msg_connect((self.blocks_tagged_stream_to_pdu_0, 'pdus'), (self.blocks_socket_pdu_0, 'pdus')) self.msg_connect((self.sarsat_pds_frame_sync_0, 'out'), (self.sarsat_sarp_msg_extract_0, 'in')) self.msg_connect((self.sarsat_sarp_msg_extract_0, 'valid'), (self.blocks_message_debug_0, 'print_pdu')) self.msg_connect((self.sarsat_sarp_msg_extract_0, 'valid'), (self.blocks_socket_pdu_0_0, 'pdus')) self.connect((self.analog_agc2_xx_0, 0), (self.analog_pll_carriertracking_cc_0, 0)) self.connect((self.analog_agc2_xx_0, 0), (self.analog_pll_freqdet_cf_0, 0)) self.connect((self.analog_agc2_xx_0, 0), (self.fosphor_qt_sink_c_0, 0)) self.connect((self.analog_nbfm_rx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.analog_pll_carriertracking_cc_0, 0), (self.rational_resampler_xxx_0, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.blocks_multiply_const_vxx_1, 0)) self.connect((self.blocks_file_source_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_keep_one_in_n_0_0, 0), (self.blocks_stream_to_tagged_stream_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_keep_one_in_n_0_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.qtgui_number_sink_0_0_0_0, 0)) self.connect((self.blocks_multiply_const_vxx_1, 0), (self.blocks_moving_average_xx_0, 0)) self.connect((self.blocks_stream_to_tagged_stream_0, 0), (self.blocks_tagged_stream_to_pdu_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.analog_agc2_xx_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.sarsat_biphase_l_decode_bb_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.digital_correlate_access_code_tag_xx_0, 0), (self.sarsat_pds_frame_sync_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.qtgui_freq_sink_x_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.rational_resampler_xxx_0_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.rational_resampler_xxx_0_0, 0), (self.analog_nbfm_rx_0, 0)) self.connect((self.sarsat_biphase_l_decode_bb_0, 0), (self.digital_correlate_access_code_tag_xx_0, 0))
def __init__(self, syms_per_sec, samples_per_sec, gain_mu, mu, omega_relative_limit, freq_offset): gr.hier_block2.__init__( self, "fsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self._syms_per_sec = syms_per_sec # ditto self._samples_per_second = samples_per_sec self._gain_mu = gain_mu # for the clock recovery block self._mu = mu self._omega_relative_limit = omega_relative_limit self._freqoffset = freq_offset self._filtdecim = 1 #first bring that input stream down to a manageable level, let's say 10 samples per bit. that's 36kS/s. self._clockrec_oversample = 10 self._downsampletaps = firdes.low_pass(1, self._samples_per_second, 10000, 1000, firdes.WIN_HANN) self._decim = int(self._samples_per_second / (self._syms_per_sec * self._clockrec_oversample)) print "Demodulator decimation: %i" % (self._decim, ) self._downsample = filter.freq_xlating_fir_filter_ccc( self._decim, #decimation self._downsampletaps, #taps self._freqoffset, #freq offset self._samples_per_second) #sampling rate #these coeffs were found experimentally self._demod = analog.pll_freqdet_cf( 0.8, #gain alpha, rad/samp 0.3, #gain beta, rad/samp 6, #max freq, rad/samp -6) #min freq, rad/samp #this pll is low phase gain to track the carrier itself, to cancel out freq error #it's a continuous carrier so you don't have to worry too much about it locking fast self._carriertrack = analog.pll_freqdet_cf(0.3, 10e-6, 6, -6) self._lpfcoeffs = firdes.low_pass( 1000, self._samples_per_second / self._decim, self._syms_per_sec, 100, firdes.WIN_HANN) self._lpf = filter.fir_filter_fff( self._filtdecim, #decimation self._lpfcoeffs) #coeffs print "Samples per symbol: %f" % (float(self._samples_per_second) / self._decim / self._syms_per_sec, ) self._softbits = gr.clock_recovery_mm_ff( float(self._samples_per_second) / self._decim / self._syms_per_sec, 0.25 * self._gain_mu * self._gain_mu, #gain omega, = mu/2 * mu_gain^2 self._mu, #mu (decision threshold) self._gain_mu, #mu gain self._omega_relative_limit) #omega relative limit self._subtract = gr.sub_ff() self._slicer = gr.binary_slicer_fb() self.connect(self, self._downsample, self._demod, (self._subtract, 0)) self.connect(self._downsample, self._carriertrack) self.connect(self._carriertrack, (self._subtract, 1)) self.connect(self._subtract, self._lpf, self._softbits, self._slicer, self)
def __init__(self): gr.top_block.__init__(self, "Top Block") Qt.QWidget.__init__(self) self.setWindowTitle("Top Block") qtgui.util.check_set_qss() try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "top_block") self.restoreGeometry( self.settings.value("geometry", type=QtCore.QByteArray)) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 32000 ################################################## # Blocks ################################################## self.qtgui_sink_x_0 = qtgui.sink_c( 1024, #fftsize firdes.WIN_BLACKMAN_hARRIS, #wintype 0, #fc samp_rate, #bw "", #name True, #plotfreq True, #plotwaterfall True, #plottime True, #plotconst ) self.qtgui_sink_x_0.set_update_time(1.0 / 10) self._qtgui_sink_x_0_win = sip.wrapinstance( self.qtgui_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_sink_x_0_win) self.qtgui_sink_x_0.enable_rf_freq(False) self.freqdet = qtgui.number_sink(gr.sizeof_float, 0, qtgui.NUM_GRAPH_HORIZ, 1) self.freqdet.set_update_time(0.10) self.freqdet.set_title("") labels = ['', '', '', '', '', '', '', '', '', ''] units = ['', '', '', '', '', '', '', '', '', ''] colors = [("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black")] factor = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] for i in xrange(1): self.freqdet.set_min(i, -1010) self.freqdet.set_max(i, 1010) self.freqdet.set_color(i, colors[i][0], colors[i][1]) if len(labels[i]) == 0: self.freqdet.set_label(i, "Data {0}".format(i)) else: self.freqdet.set_label(i, labels[i]) self.freqdet.set_unit(i, units[i]) self.freqdet.set_factor(i, factor[i]) self.freqdet.enable_autoscale(False) self._freqdet_win = sip.wrapinstance(self.freqdet.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._freqdet_win) self.channels_channel_model_0 = channels.channel_model( noise_voltage=0.001, frequency_offset=0.00001, epsilon=1.0, taps=(1.0 + 1.0j, ), noise_seed=0, block_tags=False) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex * 1, samp_rate, True) self.analog_sig_source_x_0 = analog.sig_source_c( samp_rate, analog.GR_COS_WAVE, 1000, 1, 0) self.analog_pll_freqdet_cf_0 = analog.pll_freqdet_cf(0, 1000, 9999) ################################################## # Connections ################################################## self.connect((self.analog_pll_freqdet_cf_0, 0), (self.freqdet, 0)) self.connect((self.analog_sig_source_x_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.channels_channel_model_0, 0)) self.connect((self.channels_channel_model_0, 0), (self.analog_pll_freqdet_cf_0, 0)) self.connect((self.channels_channel_model_0, 0), (self.qtgui_sink_x_0, 0))