Skip to content

Instantly share code, notes, and snippets.

@edy555
Last active Jan 22, 2022
Embed
What would you like to do?
Python based FM Receiver -- Experiment of Realtime Signal Processing in Python
#!/usr/bin/env python
#
# RTL FM Receiver - Python based realtime RF signal processing experiment
# @edy555 2016
# requirement: numpy, scipy, pyaudio, pyrtlsdr
import numpy as np
import scipy.signal
import array
import rtlsdr
import pyaudio
import Queue
import signal
def signal_handler(signum, frame):
exit(-1)
signal.signal(signal.SIGINT, signal_handler)
Fs=1.2e6 # sampling rate
tune=82.5e6 # tuning frequency
gain = 30 # LNA gain
length=1024*50
sdr = rtlsdr.RtlSdr(0)
sdr.set_sample_rate(Fs)
sdr.set_manual_gain_enabled(1)
sdr.set_gain(gain)
sdr.set_center_freq(tune)
pa = pyaudio.PyAudio()
que = Queue.Queue()
def callback(in_data, frame_count, time_info, status):
capture = que.get()
# decimate 1/5 from 1.2MHz to 240kHz
sigif = scipy.signal.decimate(capture, 5, ftype='iir')
# convert to continuous phase angle
phase = np.unwrap(np.angle(sigif))
# differentiate phase brings into frequency
pd = np.convolve(phase, [1,-1], mode='valid')
# decimate 1/10 from 240kHz to 24kHz
audio = scipy.signal.decimate(pd, 10, ftype='iir')
# make binary buffer from numpy array for pyaudio
buf = array.array('f', audio).tostring()
return (buf, pyaudio.paContinue)
# audio rate is 1.2MHz/(5*10) = 24kHz
stream = pa.open(format=pyaudio.paFloat32,
channels=1, rate=int(Fs/50), output=True, stream_callback = callback)
stream.start_stream()
def capture_callback(capture, rtlsdr_obj):
que.put(capture)
sdr.read_samples_async(capture_callback, length)
stream.stop_stream()
pa.close()
sdr.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment