main application with tuning, playing, and GUI
This commit is contained in:
50
fmdemod_old.py
Normal file
50
fmdemod_old.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import numpy as np
|
||||
import scipy.signal
|
||||
import wave
|
||||
|
||||
def read_raw_iq_samples(file_path):
|
||||
with open(file_path, 'rb') as file:
|
||||
raw_data = file.read()
|
||||
iq_samples = np.frombuffer(raw_data, dtype=np.int8)
|
||||
return iq_samples
|
||||
|
||||
def fm_demodulation(iq_samples, sample_rate, fm_deviation=75e3):
|
||||
# Hilbert transform for FM demodulation
|
||||
analytic_signal = scipy.signal.hilbert(iq_samples)
|
||||
instantaneous_phase = np.unwrap(np.angle(analytic_signal))
|
||||
demodulated_signal = np.unwrap(np.angle(iq_samples[1:] * np.conj(iq_samples[:-1]))) / (2.0 * np.pi * 1.0/sample_rate * fm_deviation)
|
||||
return demodulated_signal
|
||||
|
||||
def decimate_audio(signal, decimation_factor):
|
||||
return scipy.signal.resample(signal, len(signal)//decimation_factor)
|
||||
|
||||
def low_pass_filter(signal, cutoff_frequency, sample_rate):
|
||||
nyquist = 0.5 * sample_rate
|
||||
normal_cutoff = cutoff_frequency / nyquist
|
||||
b, a = scipy.signal.butter(6, normal_cutoff, btype='low', analog=False)
|
||||
filtered_signal = scipy.signal.filtfilt(b, a, signal)
|
||||
return filtered_signal
|
||||
|
||||
def save_wav_file(signal, sample_rate, output_file):
|
||||
scaled_signal = np.int16(signal / np.max(np.abs(signal)) * 32767)
|
||||
with wave.open(output_file, 'wb') as wav_file:
|
||||
wav_file.setnchannels(1)
|
||||
wav_file.setsampwidth(2)
|
||||
wav_file.setframerate(sample_rate)
|
||||
wav_file.writeframes(scaled_signal.tobytes())
|
||||
|
||||
def main(input_file, output_file, sample_rate, channel_width, decimation_factor=10, cutoff_frequency=75e3):
|
||||
iq_samples = read_raw_iq_samples(input_file)
|
||||
demodulated_signal = fm_demodulation(iq_samples, sample_rate)
|
||||
decimated_signal = decimate_audio(demodulated_signal, decimation_factor)
|
||||
filtered_signal = low_pass_filter(decimated_signal, cutoff_frequency, sample_rate/decimation_factor)
|
||||
new_sample_rate = sample_rate / decimation_factor
|
||||
save_wav_file(filtered_signal, new_sample_rate, output_file)
|
||||
|
||||
if __name__ == "__main__":
|
||||
input_file_path = "fm_capture.bin"
|
||||
output_wav_path = "output.wav"
|
||||
sample_rate = 2e6 # Replace with the actual sample rate of your FM stream
|
||||
channel_width = 200e3 # Replace with the channel width of your FM signal
|
||||
|
||||
main(input_file_path, output_wav_path, sample_rate, channel_width)
|
||||
Reference in New Issue
Block a user