Skip to content

Instantly share code, notes, and snippets.

@lebedov
Last active Sep 2, 2021
Embed
What would you like to do?
Frequency shift a signal using SSB modulation.
#!/usr/bin/env python
"""
Frequency shift a signal using SSB modulation.
"""
import numpy as np
import scipy as sp
import scipy.signal
import matplotlib.pyplot as plt
def nextpow2(x):
"""Return the first integer N such that 2**N >= abs(x)"""
return int(np.ceil(np.log2(np.abs(x))))
def freq_shift(x, f_shift, dt):
"""
Shift the specified signal by the specified frequency.
"""
# Pad the signal with zeros to prevent the FFT invoked by the transform from
# slowing down the computation:
N_orig = len(x)
N_padded = 2**nextpow2(N_orig)
t = np.arange(0, N_padded)
return (scipy.signal.hilbert(np.hstack((x, np.zeros(N_padded-N_orig, x.dtype))))*np.exp(2j*np.pi*f_shift*dt*t))[:N_orig].real
dt = 1e-3
fs = 1/dt
T = 1.0
t = np.arange(0, T, dt)
N = len(t)
# Construct original signal:
x = 3*np.cos(2*np.pi*t)+np.cos(2*np.pi*3*t)+2*np.cos(2*np.pi*5*t)
# Uncomment the code below to construct a more interesting signal:
# N_taps = 2500
# np.random.seed(1)
# b = sp.signal.remez(N_taps, [0.0, 14.5/fs, 15.5/fs, 19.5/fs, 20.5/fs, 0.5], [0, 1, 0])
# x = sp.signal.lfilter(b, 1.0, np.random.rand(len(t)))
# Frequency shift:
f_shift = 10.0
# Shift signal's frequency components by using the Hilbert transform
# to perform SSB modulation:
x_shift = freq_shift(x, f_shift, dt)
# Plot results:
f = np.fft.fftfreq(N, dt)
xf = np.fft.fft(x).real
xf_shift = np.fft.fft(x_shift).real
start = 0
stop = int((25.0/(fs/2.0))*(N/2.0))
plt.clf()
plt.subplot2grid((2, 3), (0, 0), rowspan=2, colspan=2)
plt.plot(t, x, 'b', t, x_shift, 'r-')
plt.xlabel('t (s)')
plt.ylabel('x(t)')
plt.legend(('original', 'shifted'))
plt.subplot2grid((2, 3), (0, 2))
plt.stem(f[start:stop], xf[start:stop])
plt.title('Original')
plt.subplot2grid((2, 3), (1, 2))
plt.stem(f[start:stop], xf_shift[start:stop])
plt.title('Shifted')
plt.xlabel('F (Hz)')
plt.tight_layout()
plt.suptitle('Frequency Shifting Using SSB Modulation')
plt.draw()
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment