I try do dedodulate a signal, saved in complex64 in a .brut file. I have 2 functions, one to automatically identify the frequencies and the other to demodulate, based on the frequencies detected.
Here the code :
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks
from tkinter import filedialog
def estimate_frequencies(signal, fs, niveau_fsk):
fft_result = np.fft.fft(signal)
fft_freq = np.fft.fftfreq(len(signal), 1/fs)
half_spectrum = fft_result[:len(fft_result)//2]
half_freqs = fft_freq[:len(fft_freq)//2]
peaks, _ = find_peaks(np.abs(half_spectrum), height=np.max(np.abs(half_spectrum))/10)
peaks = peaks[half_freqs[peaks] > 0]
important_peaks = np.argsort(-np.abs(half_spectrum[peaks]))[:niveau_fsk]
estimated_freqs = half_freqs[peaks[important_peaks]]
return estimated_freqs
def demodulate_fsk(signal, fs, freqs, symbol_duration):
instantaneous_phase = np.angle(signal)
instantaneous_frequency = np.diff(instantaneous_phase) * fs / (2.0 * np.pi)
decoded_bits = []
step_size = int(symbol_duration * fs)
for i in range(0, len(instantaneous_frequency), step_size):
segment = instantaneous_frequency[i:i+step_size]
mean_freq = np.mean(segment)
distances = [abs(mean_freq - f) for f in freqs]
decoded_bits.append(np.argmin(distances))
return np.array(decoded_bits)
filename = filedialog.askopenfilename(title="Selection d'un fichier IQ")
signal = np.fromfile(filename, dtype=np.int16).astype(np.float32).view(npplex64)
fs = 46242 # I use the bandwith of my signal
niveau_fsk = 2
symbol_duration = 1 / 19608.5 # Modulation speed = 19608.5 Bd
freqs = estimate_frequencies(signal, fs, niveau_fsk)
print("Fréquences estimées :", freqs)
decoded_bits = demodulate_fsk(signal, fs, freqs, symbol_duration)
print(decoded_bits)
The problem is that frequencies don't seem to be properly detected, and the demodulation doesn't work as expected (the binary train is wrong).