我正在尝试编写一个 Python 脚本,它可以解调 FSK 调制的音频文件并返回音频中编码的数据。传输的数据是作为音频通道嵌入视频文件中的 GPS NMEA 字符串。基本上,文本是用 FSK 调制编码的,我正在尝试使用 Python 检索文本。我用来编码数据的设备也可以解码它,所以我已经能够生成正确的输出,但我需要能够使用软件来完成。
我已经阅读了一些背景资料,向自己介绍了信号处理和 FSK,并查看了示例脚本(例如这个和minimodem)。
我设法编写了一个成功运行的 Python 脚本,尽管输出不正确。来自编码/解码设备的正确输出有 8,280 个原始二进制(0 和 1)字符,Python 输出有 1,344,786 个。我想我缺少一个符号同步器,但我不确定它是如何工作的。
我现在的问题是:如何将符号同步添加到脚本和/或符号计时?有没有更好的例子或解释如何在 Python 中进行 FSK 解调?我将不胜感激任何反馈或方向。谢谢你。
到目前为止,这是我的脚本:
from scipy.io.wavfile import read
import numpy as np
import wave
import matplotlib.pyplot as plt
import scipy.signal as signal
from scipy.signal import blackman, butter
from scipy.fftpack import fft, rfft, rfftfreq, irfft
import scipy.signal.signaltools as sigtool
import binascii
# Read in data; 'wav' allows getting paramters, 'wav1' is actual signal data
wavfile = 'Sample4_160224_mono.wav'
wavfile1 = open(wavfile, 'r')
wav = wave.open(wavfile, 'r')
wav_1 = read(wavfile1)
params = wav.getparams()
N = params[3] #Sample size
wav1 = read(wavfile1)
wav2 = wav1[1][0:N]
duration = float(params[3] / params[2])
n_samples = len(wav2)
Fs = params[2]
nyq = 0.5 * Fs #Nyquist rate
Fbit = (params[2]*params[0]*16)/100
print "Fbit", Fbit
# Windowing function
w = blackman(n_samples)
print "W is", w
# FFT
wfft = rfft(wav2 * w)
wfft_norm = wfft/N
wfft_norm = abs(wfft_norm[range(N/2)])
# Working with frequencies...
freqs = rfftfreq(len(wfft_norm))
index = np.argmax(np.abs(wfft)) #Returns the index of the maximum absolute value of the windowed FFT
freq = freqs[index] #Returns the frequency from the above index
freq_range = [freq - 0.01, freq + 0.01]
freq_in_Hz = abs(freq * params[2]) #Converts the Hz
freq_range_Hz = [abs(freq_range[0] * params[2]), abs(freq_range[1] * params[2])]
# Differentiator
diff = np.diff(wav2)
# Envelope detector
env = np.abs(sigtool.hilbert(diff))
print "ENV", len(env)
# Low-pass filter
h = signal.firwin(numtaps = 10, cutoff = freq_range[1], nyq = nyq)
filt = signal.lfilter(h, 1, env)
# Signal's mean
mean = np.mean(filt)
#Do some crazy stuff to get binary **maybe wrong**
rx_data = []
sampled_signal = env[Fs/Fbit/2:params[3]+1:]
for bit in sampled_signal:
if bit > mean:
rx_data.append(int(1))
else:
rx_data.append(int(0))
# Save raw binary output
rx_data1 = ''.join(map(str, (rx_data)))
outfile1 = open('FSK_wav6_output_binary.txt', 'w')
outfile1.write(rx_data1)
outfile1.close()