#!/usr/bin/env python3 # # SPDX-License-Identifier: GPL-3.0 # # GNU Radio Python Flow Graph # Title: FM Radio Receiver import gnuradio.analog import gnuradio.audio import gnuradio.filter import gnuradio.gr import osmosdr class fm_radio(gnuradio.gr.top_block): def __init__(self): gnuradio.gr.top_block.__init__(self, "FM Radio Receiver", catch_exceptions=True) audio_sample_rate_hertz = 48000 channel_width_hertz = ( 250000 // audio_sample_rate_hertz ) * audio_sample_rate_hertz rtlsdr_source = osmosdr.source() # `rtlsdr_source.get_sample_rates().values()`: # > TypeError: Unregistered type : std::vector > # minimum for raspberry pi 1B: rtlsdr_source.set_sample_rate(rtlsdr_source.get_sample_rates().start()) print(f"RTL-SDR sampling rate: {rtlsdr_source.get_sample_rate():.0f} Hz") rtlsdr_source.set_center_freq((98.3 * 1e6), 0) resampler = gnuradio.filter.rational_resampler_ccf( interpolation=channel_width_hertz, decimation=int(rtlsdr_source.get_sample_rate()), ) self.connect((rtlsdr_source, 0), (resampler, 0)) assert channel_width_hertz % audio_sample_rate_hertz == 0 wbfm_demodulator = gnuradio.analog.wfm_rcv( quad_rate=channel_width_hertz, audio_decimation=channel_width_hertz // audio_sample_rate_hertz, ) self.connect((resampler, 0), (wbfm_demodulator, 0)) audio_sink = gnuradio.audio.sink(audio_sample_rate_hertz, "", False) self.connect((wbfm_demodulator, 0), (audio_sink, 0)) # for raspberry pi 1B: # > RuntimeError: check topology failed on audio_alsa_sink(11) using ninputs=1, noutputs=0 self.connect((wbfm_demodulator, 0), (audio_sink, 1)) def _main(): top_block = fm_radio() top_block.start() input("Press Enter to quit: ") top_block.stop() top_block.wait() if __name__ == "__main__": _main()