Pythonで周波数変調

とりあえずwikipediaセンセー頼みです。
周波数変調(wikipedia)

理論はいまいち理解できていなくても、式さえわかれば実装レベルに落としこむのはそんなに難しくはないはず。

スポンサーリンク

式を展開する

まんま、wikipediaセンセーに書いてある通りです。

搬送波

\(V_c = V_{cm} \cos 2 \pi f_c t\)

\(V_c: 搬送波, V_{cm}: 搬送波最大値, f_c: 中心周波数\)

信号波

\(V_s = V_{sm} \cos 2 \pi f_s t\)

\(V_s:信号波, V_{sm}: 信号波最大値, f_s: 信号周波数\)

被変調波

\(V_m = V_{cm} \sin \theta_m\)

これを時間積分すると、

\(V_m = V_{cm} \sin (\omega_c t + m \sin \omega_s t)\)

\(m\): 変調指数

\(m = \frac{\Delta f}{f_s}\)

\(\Delta f\): 最大周波数偏移 (FM放送は75KHz)

\(\omega = 2 \pi f\) なので、

\(V_m = V_{cm} \sin (2 \pi f_c t + \frac{\Delta f}{f_s} \sin 2 \pi f_s t)\)

これを実装していきます。

実装する

信号最大値は正規化されているので 1 です。見た目わかりやすくするために極端な数字でやっています。ちなみに、実際にFM放送に使われる搬送波は 47〜108MHzです。

import numpy as np
import matplotlib.pylab as plt
 
sampling_rate = 100000.0 #サンプリング周波数 100KHz
t = np.arange(0.5 * sampling_rate)/sampling_rate # 0.5秒
fc = 2000   # 搬送波 2KHz
fs = 250    # 信号波 250Hz
df = 1000   # 最大周波数偏移 1KHz
 
# 信号波 Vs を生成
Vs = np.cos(2*np.pi*fs*t)
 
# 被変調波 Vm を生成
Vm = np.sin(2*np.pi*fc*t + (df/fs) * np.sin(2*np.pi*fs*t))
 
#信号波と被変調波をプロット
plt.plot(Vs[:1500])
plt.plot(Vm[:1500])
plt.show()

おぉ、なんかそれっぽくなった。

被変調波の周波数スペクトラムを表示してみます。

N = 4096 # FFTのサンプル数
freqs = np.fft.fft(Vm[:N] * np.hanning(N)) #hanning窓をかけてFFT
 
freqs_list = np.fft.fftfreq(N,d=1.0/sampling_rate)
 
amplitude = [np.sqrt(c.real**2 + c.imag**2) for c in freqs]
plt.axis([0,4000, 0, 500])
plt.plot(freqs_list, amplitude)
plt.show()

スペクトラム間隔は変調信号周波数 \(f_s\)(ここでは 250Hz) になります。実際には周波数スペクトラムは無限に広がります。そのため、実際の放送波では帯域制限がかけられています。

日本のFM放送の場合、占有帯域幅は200KHzと決められています。

次回これを復調してみます。

スポンサーリンク

フォローする