fm_radio.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #
  4. # SPDX-License-Identifier: GPL-3.0
  5. #
  6. # GNU Radio Python Flow Graph
  7. # Title: FM Radio Receiver
  8. # GNU Radio version: 3.10.5.1
  9. from packaging.version import Version as StrictVersion
  10. if __name__ == '__main__':
  11. import ctypes
  12. import sys
  13. if sys.platform.startswith('linux'):
  14. try:
  15. x11 = ctypes.cdll.LoadLibrary('libX11.so')
  16. x11.XInitThreads()
  17. except:
  18. print("Warning: failed to XInitThreads()")
  19. from gnuradio import analog
  20. from gnuradio import audio
  21. from gnuradio import filter
  22. from gnuradio.filter import firdes
  23. from gnuradio import gr
  24. from gnuradio.fft import window
  25. import sys
  26. import signal
  27. from PyQt5 import Qt
  28. from argparse import ArgumentParser
  29. from gnuradio.eng_arg import eng_float, intx
  30. from gnuradio import eng_notation
  31. import osmosdr
  32. import time
  33. from gnuradio import qtgui
  34. class fm_radio(gr.top_block, Qt.QWidget):
  35. def __init__(self):
  36. gr.top_block.__init__(self, "FM Radio Receiver", catch_exceptions=True)
  37. Qt.QWidget.__init__(self)
  38. self.setWindowTitle("FM Radio Receiver")
  39. qtgui.util.check_set_qss()
  40. try:
  41. self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
  42. except:
  43. pass
  44. self.top_scroll_layout = Qt.QVBoxLayout()
  45. self.setLayout(self.top_scroll_layout)
  46. self.top_scroll = Qt.QScrollArea()
  47. self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
  48. self.top_scroll_layout.addWidget(self.top_scroll)
  49. self.top_scroll.setWidgetResizable(True)
  50. self.top_widget = Qt.QWidget()
  51. self.top_scroll.setWidget(self.top_widget)
  52. self.top_layout = Qt.QVBoxLayout(self.top_widget)
  53. self.top_grid_layout = Qt.QGridLayout()
  54. self.top_layout.addLayout(self.top_grid_layout)
  55. self.settings = Qt.QSettings("GNU Radio", "fm_radio")
  56. try:
  57. if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
  58. self.restoreGeometry(self.settings.value("geometry").toByteArray())
  59. else:
  60. self.restoreGeometry(self.settings.value("geometry"))
  61. except:
  62. pass
  63. ##################################################
  64. # Variables
  65. ##################################################
  66. self.samp_rate = samp_rate = 2560000
  67. self.channel_width_hertz = channel_width_hertz = 250000
  68. self.audio_sample_rate_hertz = audio_sample_rate_hertz = 48000
  69. ##################################################
  70. # Blocks
  71. ##################################################
  72. self.rtlsdr_source_0 = osmosdr.source(
  73. args="numchan=" + str(1) + " " + ""
  74. )
  75. self.rtlsdr_source_0.set_time_unknown_pps(osmosdr.time_spec_t())
  76. self.rtlsdr_source_0.set_sample_rate(samp_rate)
  77. self.rtlsdr_source_0.set_center_freq((98.3*1e6), 0)
  78. self.rtlsdr_source_0.set_freq_corr(0, 0)
  79. self.rtlsdr_source_0.set_dc_offset_mode(0, 0)
  80. self.rtlsdr_source_0.set_iq_balance_mode(0, 0)
  81. self.rtlsdr_source_0.set_gain_mode(False, 0)
  82. self.rtlsdr_source_0.set_gain(20, 0)
  83. self.rtlsdr_source_0.set_if_gain(20, 0)
  84. self.rtlsdr_source_0.set_bb_gain(20, 0)
  85. self.rtlsdr_source_0.set_antenna('', 0)
  86. self.rtlsdr_source_0.set_bandwidth(0, 0)
  87. self.rational_resampler_xxx_0 = filter.rational_resampler_fff(
  88. interpolation=audio_sample_rate_hertz,
  89. decimation=channel_width_hertz,
  90. taps=[],
  91. fractional_bw=0)
  92. self.low_pass_filter_0 = filter.fir_filter_ccf(
  93. (int(samp_rate/channel_width_hertz)),
  94. firdes.low_pass(
  95. 2,
  96. samp_rate,
  97. 100000,
  98. 10000,
  99. window.WIN_KAISER,
  100. 6.76))
  101. self.audio_sink_0 = audio.sink(audio_sample_rate_hertz, '', True)
  102. self.analog_wfm_rcv_0 = analog.wfm_rcv(
  103. quad_rate=channel_width_hertz,
  104. audio_decimation=1,
  105. )
  106. ##################################################
  107. # Connections
  108. ##################################################
  109. self.connect((self.analog_wfm_rcv_0, 0), (self.rational_resampler_xxx_0, 0))
  110. self.connect((self.low_pass_filter_0, 0), (self.analog_wfm_rcv_0, 0))
  111. self.connect((self.rational_resampler_xxx_0, 0), (self.audio_sink_0, 0))
  112. self.connect((self.rtlsdr_source_0, 0), (self.low_pass_filter_0, 0))
  113. def closeEvent(self, event):
  114. self.settings = Qt.QSettings("GNU Radio", "fm_radio")
  115. self.settings.setValue("geometry", self.saveGeometry())
  116. self.stop()
  117. self.wait()
  118. event.accept()
  119. def get_samp_rate(self):
  120. return self.samp_rate
  121. def set_samp_rate(self, samp_rate):
  122. self.samp_rate = samp_rate
  123. self.low_pass_filter_0.set_taps(firdes.low_pass(2, self.samp_rate, 100000, 10000, window.WIN_KAISER, 6.76))
  124. self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
  125. def get_channel_width_hertz(self):
  126. return self.channel_width_hertz
  127. def set_channel_width_hertz(self, channel_width_hertz):
  128. self.channel_width_hertz = channel_width_hertz
  129. def get_audio_sample_rate_hertz(self):
  130. return self.audio_sample_rate_hertz
  131. def set_audio_sample_rate_hertz(self, audio_sample_rate_hertz):
  132. self.audio_sample_rate_hertz = audio_sample_rate_hertz
  133. def main(top_block_cls=fm_radio, options=None):
  134. if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
  135. style = gr.prefs().get_string('qtgui', 'style', 'raster')
  136. Qt.QApplication.setGraphicsSystem(style)
  137. qapp = Qt.QApplication(sys.argv)
  138. tb = top_block_cls()
  139. tb.start()
  140. tb.show()
  141. def sig_handler(sig=None, frame=None):
  142. tb.stop()
  143. tb.wait()
  144. Qt.QApplication.quit()
  145. signal.signal(signal.SIGINT, sig_handler)
  146. signal.signal(signal.SIGTERM, sig_handler)
  147. timer = Qt.QTimer()
  148. timer.start(500)
  149. timer.timeout.connect(lambda: None)
  150. qapp.exec_()
  151. if __name__ == '__main__':
  152. main()