import numpy as np import matplotlib.pyplot as plt import scipy as sp def add_noise(s, SNR): var_s = np.cov(s) var_noise = var_s/(10**(SNR/10)) noise = var_noise**0.5 * np.random.randn(len(s)) return s + noise def add_noise_db(s, noise_db): var_noise = 10**(noise_db/10) noise = var_noise**0.5 * np.random.randn(len(s)) return s + noise def lowpass(data, f_cutoff, f_s): nyq = 0.5*f_s normal_cutoff = f_cutoff/nyq b, a = sp.signal.butter(2, normal_cutoff, btype="low", analog=False) y = sp.signal.lfilter(b, a, data) return y def bandpass(data, f_pass, f_cutoff, f_s): nyq = 0.5*f_s normal_pass = f_pass/nyq normal_cutoff = f_cutoff/nyq b, a = sp.signal.butter(2, (normal_pass, normal_cutoff), btype="bandpass", analog=False) y = sp.signal.lfilter(b, a, data) return y def fm(m, f_c, beta_f, t): omega_c = 2*np.pi*f_c return np.cos(omega_c*t + beta_f*m) def product_demod(s, f_baseband, f_c, f_s, t): omega_c = 2*np.pi*f_c mixed = s*np.cos(omega_c*t) return lowpass(mixed, f_baseband, f_s) def fm_demod(s_fm, f_c, f_s, beta_f, t): diff_t = np.gradient(s_fm, t) envelope = np.abs(sp.signal.hilbert(diff_t)) omega_c = 2*np.pi*f_c dt = 1/f_s m_demod = np.empty_like(envelope) #err1 = dt*(envelope[0] + envelope[1] - 2*omega_c)/beta_f**2 #err2 = dt*(dm_dt[0] + dm_dt[1])/beta_f for i in range(len(envelope)): m_demod[i] = np.sum((envelope[:i+1] - omega_c)/(beta_f*f_s)) return m_demod def quad_demod(s_fm, bandwidth, f_s, f_c, t): iq = real_to_iq(s_fm, f_c, bandwidth, f_s, t) iq = np.conj(iq) return 0.5*np.angle(iq) def real_to_iq(s_fm, f_c, bandwidth, f_s, t): i = lowpass(s_fm * np.cos(2*np.pi*f_c*t), bandwidth, f_s) q = lowpass(s_fm * np.sin(2*np.pi*f_c*t), bandwidth, f_s) return i + 1j*q def m(t): f_m = 10 omega_m = 2*np.pi*f_m return 0.1*np.sin(omega_m*t) def dm_dt(t): f_m = 10 omega_m = 2*np.pi*f_m return 0.1*omega_m*np.cos(omega_m*t) def db(x): return 10*np.log10(x) def main(): T_s = 0.0001 f_s = 1/T_s f_m = 20 omega_m = 2*np.pi*f_m f_c = 500 beta_f = 2.40483 t = np.arange(0,1,T_s) f = np.linspace(-f_s/2, f_s/2, len(t)) #m = 0.5*(np.sin(omega_m*t) + np.sin(omega_m/2*t)) m = np.sin(omega_m*t) s_fm = fm(m, f_c, beta_f, t) omega_c = 2*np.pi*f_c #plt.plot(t, m, label="Original Message Signal") #plt.plot(t, quad_demod(s_fm, 2*f_m, f_s, f_c, t), label="Demodulated Message") #plt.legend() #plt.savefig("message-signals") #plt.show() #plt.plot(t, s_fm, label="Frequency Modulated Message") #plt.legend() #plt.savefig("fm-signal") #plt.show() spectrum = np.abs(sp.fft.fftshift(sp.fft.fft(s_fm)))**2 #spectrum_db = db(spectrum) plt.subplot(121) plt.plot(f, spectrum) #plt.vlines(f_c, -250, 100, color='r') plt.xlim(0,2*f_c) plt.title("Null Carrier Spectrum") plt.xlabel("Frequency [Hz]") beta_f = 5 m = np.sin(omega_m*t) s_fm = fm(m, f_c, beta_f, t) spectrum = np.abs(sp.fft.fftshift(sp.fft.fft(s_fm)))**2 plt.subplot(122) plt.title("Non-null Carrier Spectrum") plt.plot(f, spectrum) plt.xlim(0,2*f_c) plt.xlabel("Frequency [Hz]") plt.savefig("null-carrier-comp") plt.show() if __name__ == "__main__": main()