いいですね…そこに行きましたか 😄
AM → FM は、今日の流れの「正統進化ルート」です。
しかもやることは意外とシンプルで、
**「どこを変えるか」**が分かると一気に腑に落ちます。
まず概念の違い(超重要)
AM(振幅変調)
振幅が揺れる
sAM(t)=(1+μcos(2πfmt))cos(2πfct)
FM(周波数変調)
周波数(位相の進み方)が揺れる
sFM(t)=cos(2πfct+βsin(2πfmt))
-
β(ベータ)= 変調指数
-
AM の μ に対応する“効きの強さ”
👉 振幅は一定、でも中身は激しく変化
ipynb での最小変更ポイント
あなたの AM ノート、
③セルまでは ほぼそのまま使えます。
③セル(FM 信号生成)
AM の代わりに、ここだけ変えます👇
# 時間軸
t = np.arange(0, T, 1/fs)# パラメータbeta = 5.0 # FM変調指数(ここを変えて遊ぶ)
# FM信号
fm_signal = np.cos(
2*np.pi*fc*t + beta * np.sin(2*np.pi*fm*t)
)
※ carrier や message を分けて書いてもOKですが、
FMは「位相に直接入る」のがポイントです。
④セル(時間波形表示)
AM のときと 全く同じ書き方でOK:
plt.figure(figsize=(8, 4))
plt.plot(t[:2000], fm_signal[:2000])
plt.xlabel("Time [s]")
plt.ylabel("Amplitude")
plt.title("FM waveform (time domain)")
plt.grid()
plt.show()
👉 見た目は
**「AMよりずっとゴチャッとしてる」**はず。
でも振幅は一定。
⑤セル(FFT)
これも AM と同じで、変数名だけ変更:
S = np.fft.fft(fm_signal)
freq = np.fft.fftfreq(len(S), d=1/fs)
amp = np.abs(S) / len(S)
⑥セル(スペクトル表示)
plt.figure(figsize=(8, 4))
plt.plot(freq, amp)
plt.xlim(0, 2_000_000)
plt.xlabel("Frequency [Hz]")
plt.ylabel("Amplitude")
plt.title("FM spectrum")
plt.grid()
plt.show()
見える世界の違い(ここが感動ポイント)
AM
-
中心:fc
-
両脇:fc ± fm(細い)
FM
-
fc の周りに 無数の側波帯
-
β を上げると 一気に広帯域化
👉
「FM は音質がいいが、帯域を食う」
という教科書の一文が 目で分かる瞬間です。
まず試してほしい β の値
beta = 0.5 # ほぼAMっぽい
beta = 2.0
beta = 5.0
beta = 10.0 # 完全に広帯域
FFT を並べて見ると、
通信方式の思想の違いが一気に見えてきます。
今日のあなたに起きていること(ちょっとだけ)
もうこれは
「Python の勉強」ではなく、
信号処理を“自分の手で再発見している”状態
です。
次はきっと
-
Carson の帯域幅
-
Bessel 関数
-
FM 復調
あたりが自然に気になってきます 😄
また一歩進みたくなったら、
どこでも一緒に掘り下げましょう。
「窓関数って何だ?」
来ましたね、その疑問。
**「窓関数って何だ?」**と自然に思った時点で、もう“本物の入口”です。
今日は FFTを使って実感できるレベルで説明します。
数式より なぜ必要か → 何が変わるか を重視します。
まず直感から
FFT するとき、実はあなたはこういうことをしています👇
「信号を、ある区間でブツッと切り取って周波数解析」
この「ブツッ」が問題の正体です。

問題:矩形窓(何もしない状態)
今までやっていた FFT は、暗黙的に:
信号 × 矩形窓(0 or 1)
つまり、
| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
という窓で切っています。
何が起きるか?
-
端で 急激に 0 になる
-
→ 高周波成分が大量発生
-
→ スペクトルがにじむ(リーケージ)
👉 これが
「側波帯が分離しない」
「ピークが太い」
正体です。
窓関数とは?
「端をなめらかにしてから FFT しよう」
という工夫です。
代表例:Hann(ハン)窓
形はこんな感じ👇
/\
/ \
/ \
-
両端が 0
-
中央が最大
-
急な変化が無い
👉 高周波ノイズが激減します。
ipynb で一発体験
窓なし(今まで)
S = np.fft.fft(fm_signal)
Hann 窓あり
window = np.hanning(len(fm_signal))
S = np.fft.fft(fm_signal * window)
👉 これだけです。
スペクトルの違い(見どころ)
窓なし
-
ピークが太い
-
にじむ
-
偽の成分が多い
窓あり
-
ピークが細い
-
側波帯が分離
-
見た目が「きれい」
※ ただし振幅は少し下がります(副作用)
よく使う窓関数(実用)
| 窓 | 特徴 |
|---|---|
| Rectangular | 何もしない(リーケージ最大) |
| Hann | 万能・まずこれ |
| Hamming | 低サイドローブ |
| Blackman | 超きれい・分解能低下 |
👉 迷ったら Hann
なぜ通信・音声で重要?
-
FM / 音声解析
-
スペクトラムアナライザ
-
SDR
全部
👉 窓あり前提で設計されています。
今日の一言まとめ
-
FFT は「有限区間を切る」解析
-
切り方が悪いと周波数が汚れる
-
窓関数 = 切り口をなめらかにする技
次にやると感動するのは:
-
同じ信号で「窓なし vs Hann」を並べて比較
-
β を変えた FM に窓をかける
「なんか FFT きれいになった気がする」
から
**「理屈が分かって使ってる」**に変わる瞬間です。


コメント