Advertisement
duggabe

Pluto_WBFM_stereo.py

Jun 4th, 2021
948
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.26 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3.  
  4. #
  5. # SPDX-License-Identifier: GPL-3.0
  6. #
  7. # GNU Radio Python Flow Graph
  8. # Title: Pluto_WBFM_stereo
  9. # Author: Barry Duggan
  10. # GNU Radio version: v3.10.0.0git-373-g7b25b39e
  11.  
  12. from distutils.version import StrictVersion
  13.  
  14. if __name__ == '__main__':
  15.     import ctypes
  16.     import sys
  17.     if sys.platform.startswith('linux'):
  18.         try:
  19.             x11 = ctypes.cdll.LoadLibrary('libX11.so')
  20.             x11.XInitThreads()
  21.         except:
  22.             print("Warning: failed to XInitThreads()")
  23.  
  24. from PyQt5 import Qt
  25. from gnuradio import qtgui
  26. from gnuradio.filter import firdes
  27. import sip
  28. from gnuradio import analog
  29. from gnuradio import audio
  30. from gnuradio import blocks
  31. from gnuradio import filter
  32. from gnuradio import gr
  33. from gnuradio.fft import window
  34. import sys
  35. import signal
  36. from argparse import ArgumentParser
  37. from gnuradio.eng_arg import eng_float, intx
  38. from gnuradio import eng_notation
  39. from gnuradio import iio
  40. from gnuradio.qtgui import Range, RangeWidget
  41. from PyQt5 import QtCore
  42.  
  43.  
  44.  
  45. from gnuradio import qtgui
  46.  
  47. class Pluto_WBFM_stereo(gr.top_block, Qt.QWidget):
  48.  
  49.     def __init__(self):
  50.         gr.top_block.__init__(self, "Pluto_WBFM_stereo", catch_exceptions=True)
  51.         Qt.QWidget.__init__(self)
  52.         self.setWindowTitle("Pluto_WBFM_stereo")
  53.         qtgui.util.check_set_qss()
  54.         try:
  55.             self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
  56.         except:
  57.             pass
  58.         self.top_scroll_layout = Qt.QVBoxLayout()
  59.         self.setLayout(self.top_scroll_layout)
  60.         self.top_scroll = Qt.QScrollArea()
  61.         self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
  62.         self.top_scroll_layout.addWidget(self.top_scroll)
  63.         self.top_scroll.setWidgetResizable(True)
  64.         self.top_widget = Qt.QWidget()
  65.         self.top_scroll.setWidget(self.top_widget)
  66.         self.top_layout = Qt.QVBoxLayout(self.top_widget)
  67.         self.top_grid_layout = Qt.QGridLayout()
  68.         self.top_layout.addLayout(self.top_grid_layout)
  69.  
  70.         self.settings = Qt.QSettings("GNU Radio", "Pluto_WBFM_stereo")
  71.  
  72.         try:
  73.             if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
  74.                 self.restoreGeometry(self.settings.value("geometry").toByteArray())
  75.             else:
  76.                 self.restoreGeometry(self.settings.value("geometry"))
  77.         except:
  78.             pass
  79.  
  80.         ##################################################
  81.         # Variables
  82.         ##################################################
  83.         self.samp_rate = samp_rate = 768000
  84.         self.demod_rate = demod_rate = 384000
  85.         self.volume = volume = 0.2
  86.         self.tuning = tuning = 102100000
  87.         self.sq_lvl = sq_lvl = -50
  88.         self.rf_gain = rf_gain = 50
  89.         self.rf_decim = rf_decim = (int)(samp_rate/demod_rate)
  90.         self.audio_decim = audio_decim = (int)(demod_rate/48000)
  91.  
  92.         ##################################################
  93.         # Blocks
  94.         ##################################################
  95.         self._volume_range = Range(0, 1.0, 0.05, 0.2, 200)
  96.         self._volume_win = RangeWidget(self._volume_range, self.set_volume, 'Volume', "slider", float, QtCore.Qt.Horizontal)
  97.         self.top_layout.addWidget(self._volume_win)
  98.         self._tuning_range = Range(88000000, 148000000, 200000, 102100000, 200)
  99.         self._tuning_win = RangeWidget(self._tuning_range, self.set_tuning, 'Frequency', "counter_slider", float, QtCore.Qt.Horizontal)
  100.         self.top_layout.addWidget(self._tuning_win)
  101.         self._sq_lvl_range = Range(-100, 0, 5, -50, 200)
  102.         self._sq_lvl_win = RangeWidget(self._sq_lvl_range, self.set_sq_lvl, 'Squelch', "counter_slider", float, QtCore.Qt.Horizontal)
  103.         self.top_layout.addWidget(self._sq_lvl_win)
  104.         self._rf_gain_range = Range(0, 70, 1, 50, 200)
  105.         self._rf_gain_win = RangeWidget(self._rf_gain_range, self.set_rf_gain, 'RF Gain', "slider", float, QtCore.Qt.Horizontal)
  106.         self.top_layout.addWidget(self._rf_gain_win)
  107.         self.qtgui_waterfall_sink_x_0 = qtgui.waterfall_sink_c(
  108.             1024, #size
  109.             window.WIN_BLACKMAN_hARRIS, #wintype
  110.             tuning, #fc
  111.             demod_rate, #bw
  112.             "", #name
  113.             1, #number of inputs
  114.             None # parent
  115.         )
  116.         self.qtgui_waterfall_sink_x_0.set_update_time(0.10)
  117.         self.qtgui_waterfall_sink_x_0.enable_grid(False)
  118.         self.qtgui_waterfall_sink_x_0.enable_axis_labels(True)
  119.  
  120.  
  121.  
  122.         labels = ['', '', '', '', '',
  123.                   '', '', '', '', '']
  124.         colors = [0, 0, 0, 0, 0,
  125.                   0, 0, 0, 0, 0]
  126.         alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
  127.                   1.0, 1.0, 1.0, 1.0, 1.0]
  128.  
  129.         for i in range(1):
  130.             if len(labels[i]) == 0:
  131.                 self.qtgui_waterfall_sink_x_0.set_line_label(i, "Data {0}".format(i))
  132.             else:
  133.                 self.qtgui_waterfall_sink_x_0.set_line_label(i, labels[i])
  134.             self.qtgui_waterfall_sink_x_0.set_color_map(i, colors[i])
  135.             self.qtgui_waterfall_sink_x_0.set_line_alpha(i, alphas[i])
  136.  
  137.         self.qtgui_waterfall_sink_x_0.set_intensity_range(-140, 10)
  138.  
  139.         self._qtgui_waterfall_sink_x_0_win = sip.wrapinstance(self.qtgui_waterfall_sink_x_0.pyqwidget(), Qt.QWidget)
  140.         self.top_layout.addWidget(self._qtgui_waterfall_sink_x_0_win)
  141.         self.iio_pluto_source_0 = iio.pluto_source('ip:192.168.3.1', 32768)
  142.         self.iio_pluto_source_0.set_frequency(int(tuning))
  143.         self.iio_pluto_source_0.set_samplerate(samp_rate)
  144.         self.iio_pluto_source_0.set_gain_mode('manual')
  145.         self.iio_pluto_source_0.set_gain(64)
  146.         self.iio_pluto_source_0.set_quadrature(True)
  147.         self.iio_pluto_source_0.set_rfdc(True)
  148.         self.iio_pluto_source_0.set_bbdc(True)
  149.         self.iio_pluto_source_0.set_filter_params('Auto', '', samp_rate/4, samp_rate/3)
  150.         self.filter_fft_low_pass_filter_0 = filter.fft_filter_ccc(rf_decim, firdes.low_pass(1, samp_rate, 90000, 20000, window.WIN_HAMMING, 6.76), 1)
  151.         self.blocks_multiply_const_vxx_0_0_0 = blocks.multiply_const_ff(volume)
  152.         self.blocks_multiply_const_vxx_0_0 = blocks.multiply_const_ff(volume)
  153.         self.audio_sink_0 = audio.sink(48000, '', False)
  154.         self.analog_wfm_rcv_pll_0 = analog.wfm_rcv_pll(
  155.             demod_rate=demod_rate,
  156.             audio_decimation=audio_decim,
  157.             deemph_tau=75e-6,
  158.         )
  159.         self.analog_simple_squelch_cc_0 = analog.simple_squelch_cc(sq_lvl, 1)
  160.  
  161.  
  162.  
  163.         ##################################################
  164.         # Connections
  165.         ##################################################
  166.         self.connect((self.analog_simple_squelch_cc_0, 0), (self.analog_wfm_rcv_pll_0, 0))
  167.         self.connect((self.analog_wfm_rcv_pll_0, 0), (self.blocks_multiply_const_vxx_0_0, 0))
  168.         self.connect((self.analog_wfm_rcv_pll_0, 1), (self.blocks_multiply_const_vxx_0_0_0, 0))
  169.         self.connect((self.blocks_multiply_const_vxx_0_0, 0), (self.audio_sink_0, 0))
  170.         self.connect((self.blocks_multiply_const_vxx_0_0_0, 0), (self.audio_sink_0, 1))
  171.         self.connect((self.filter_fft_low_pass_filter_0, 0), (self.analog_simple_squelch_cc_0, 0))
  172.         self.connect((self.filter_fft_low_pass_filter_0, 0), (self.qtgui_waterfall_sink_x_0, 0))
  173.         self.connect((self.iio_pluto_source_0, 0), (self.filter_fft_low_pass_filter_0, 0))
  174.  
  175.  
  176.     def closeEvent(self, event):
  177.         self.settings = Qt.QSettings("GNU Radio", "Pluto_WBFM_stereo")
  178.         self.settings.setValue("geometry", self.saveGeometry())
  179.         self.stop()
  180.         self.wait()
  181.  
  182.         event.accept()
  183.  
  184.     def get_samp_rate(self):
  185.         return self.samp_rate
  186.  
  187.     def set_samp_rate(self, samp_rate):
  188.         self.samp_rate = samp_rate
  189.         self.set_rf_decim((int)(self.samp_rate/self.demod_rate))
  190.         self.filter_fft_low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 90000, 20000, window.WIN_HAMMING, 6.76))
  191.         self.iio_pluto_source_0.set_samplerate(self.samp_rate)
  192.         self.iio_pluto_source_0.set_filter_params('Auto', '', self.samp_rate/4, self.samp_rate/3)
  193.  
  194.     def get_demod_rate(self):
  195.         return self.demod_rate
  196.  
  197.     def set_demod_rate(self, demod_rate):
  198.         self.demod_rate = demod_rate
  199.         self.set_audio_decim((int)(self.demod_rate/48000))
  200.         self.set_rf_decim((int)(self.samp_rate/self.demod_rate))
  201.         self.qtgui_waterfall_sink_x_0.set_frequency_range(self.tuning, self.demod_rate)
  202.  
  203.     def get_volume(self):
  204.         return self.volume
  205.  
  206.     def set_volume(self, volume):
  207.         self.volume = volume
  208.         self.blocks_multiply_const_vxx_0_0.set_k(self.volume)
  209.         self.blocks_multiply_const_vxx_0_0_0.set_k(self.volume)
  210.  
  211.     def get_tuning(self):
  212.         return self.tuning
  213.  
  214.     def set_tuning(self, tuning):
  215.         self.tuning = tuning
  216.         self.iio_pluto_source_0.set_frequency(int(self.tuning))
  217.         self.qtgui_waterfall_sink_x_0.set_frequency_range(self.tuning, self.demod_rate)
  218.  
  219.     def get_sq_lvl(self):
  220.         return self.sq_lvl
  221.  
  222.     def set_sq_lvl(self, sq_lvl):
  223.         self.sq_lvl = sq_lvl
  224.         self.analog_simple_squelch_cc_0.set_threshold(self.sq_lvl)
  225.  
  226.     def get_rf_gain(self):
  227.         return self.rf_gain
  228.  
  229.     def set_rf_gain(self, rf_gain):
  230.         self.rf_gain = rf_gain
  231.  
  232.     def get_rf_decim(self):
  233.         return self.rf_decim
  234.  
  235.     def set_rf_decim(self, rf_decim):
  236.         self.rf_decim = rf_decim
  237.  
  238.     def get_audio_decim(self):
  239.         return self.audio_decim
  240.  
  241.     def set_audio_decim(self, audio_decim):
  242.         self.audio_decim = audio_decim
  243.  
  244.  
  245.  
  246.  
  247. def main(top_block_cls=Pluto_WBFM_stereo, options=None):
  248.  
  249.     if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
  250.         style = gr.prefs().get_string('qtgui', 'style', 'raster')
  251.         Qt.QApplication.setGraphicsSystem(style)
  252.     qapp = Qt.QApplication(sys.argv)
  253.  
  254.     tb = top_block_cls()
  255.  
  256.     tb.start()
  257.  
  258.     tb.show()
  259.  
  260.     def sig_handler(sig=None, frame=None):
  261.         tb.stop()
  262.         tb.wait()
  263.  
  264.         Qt.QApplication.quit()
  265.  
  266.     signal.signal(signal.SIGINT, sig_handler)
  267.     signal.signal(signal.SIGTERM, sig_handler)
  268.  
  269.     timer = Qt.QTimer()
  270.     timer.start(500)
  271.     timer.timeout.connect(lambda: None)
  272.  
  273.     qapp.exec_()
  274.  
  275. if __name__ == '__main__':
  276.     main()
  277.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement