Created
September 2, 2020 08:50
-
-
Save rudrathegreat/3a70161da65565b8d9fd20f68b73ab64 to your computer and use it in GitHub Desktop.
Catch FM stations using Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rtlsdr import RtlSdr | |
import numpy as np | |
import scipy.signal as signal | |
from scipy.io.wavfile import write | |
sdr = RtlSdr() | |
F_station = int(105.9e6) # FM Station | |
duration = 10 | |
F_offset = 250000 # Offset to capture at | |
# We capture at an offset to avoid DC spike | |
Fc = F_station - F_offset # Capture center frequency | |
Fs = int(1140000) # Sample rate | |
N = int(8192000) # Samples to capture | |
# configure device | |
sdr.sample_rate = Fs # Hz | |
sdr.center_freq = Fc # Hz | |
sdr.gain = 'auto' | |
# Read samples | |
samples = sdr.read_samples(N) | |
# Clean up the SDR device | |
sdr.close() | |
del(sdr) | |
# Convert samples to a numpy array | |
x1 = np.array(samples).astype("complex64") | |
# Get a baseband signal, a signal with no modulation | |
fc1 = np.exp(-1.0j*2.0*np.pi* F_offset/Fs*np.arange(len(x1))) | |
x2 = x1 * fc1 | |
# Decimate data | |
f_bw = 200000 | |
dec_rate = int(Fs / f_bw) | |
x4 = signal.decimate(x2, dec_rate) | |
# Calculate the new sampling rate | |
Fs_y = Fs/dec_rate | |
# Turn changes in frequency into changes in amplitude | |
y5 = x4[1:] * np.conj(x4[:-1]) | |
x5 = np.angle(y5) | |
#Filter and remove noise | |
d = Fs_y * 75e-6 # Calculate the # of samples to hit the -3dB point | |
x = np.exp(-1/d) # Calculate the decay between each sample | |
b = [1-x] # Create the filter coefficients | |
a = [1,-x] | |
x6 = signal.lfilter(b,a,x5) | |
audio_freq = 44100.0 | |
dec_audio = int(Fs_y/audio_freq) | |
Fs_audio = int(Fs_y / dec_audio) | |
x7 = signal.decimate(x6, dec_audio) | |
#Convert to real numbers | |
x7 *= 10000 / np.max(np.abs(x7)) | |
# Save to file as 16-bit signed single-channel audio samples | |
x7 = x7.astype('int16') | |
#Save audio | |
write('audio.wav', Fs_audio, x7) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment