ふと思い出した、Quadrifilar Helix アンテナ(QHA)とSDR。
上の写真がSDR。
そしてこれが自作のQuadrifilar Helix アンテナ。

以前、気象衛星NOAAの画像を取り込むために使っていた機器ですが、NOAAが停波したので使わずにいました。
それを使って、FMラジオを受信→AI文字起こし→QdrantベクターDB登録→AI塾長が利用、というNerveパイプラインを作ろうと思います。
今日のところは、FMラジオを受信して音声ファイルを保存し、それをcronで呼び出せるようにするところまでが完成。次回以降、Nerveパイプラインを実装します。
情報番組やニュース番組の時間に合わせて、定期的に実行すれば、世の中で何が起こっているかをAI塾長が知ることができます。
これが録音した音声をVLCメディアプレイヤーで聴いているときの様子。

これの何が嬉しいか?
災害時にはラジオは頼りになる情報収集手段です。
インターネットが切れても、情報収集手段がゼロにならない。
ZIKUUのAIシステムは、視覚はVisionモデルを使った画像解析、聴覚はWhisperを使ったYouTube文字起こしとこのラジオ受信。
すでにサーバーでこのラジオ受信システムの試験運用を始めています。
ここの山梨県上野原市は山間部であまり電波の受信状態が良くありません。
こんなPythonプログラムで電波の強い曲を探します。
import csv, math
from collections import defaultdict
path = "/tmp/fm_scan.csv"
# freq_hz -> max power observed
mx = defaultdict(lambda: -1e9)
with open(path, newline="") as f:
r = csv.reader(f)
for row in r:
if not row or row[0].startswith("#"):
continue
# row: date,time,start,end,bin,???, powers...
try:
start = float(row[2])
bin_hz = float(row[4])
powers = row[6:]
except Exception:
continue
for i, p in enumerate(powers):
try:
v = float(p)
except:
continue
freq = start + i * bin_hz
if v > mx[freq]:
mx[freq] = v
top = sorted(mx.items(), key=lambda x: x[1], reverse=True)[:30]
print("Top bins (approx):")
for f, v in top:
print(f"{f/1e6:8.3f} MHz {v:7.2f} dB")
この結果から選んだ局は以下のもの。(電波の強い順)
| FM局 | 周波数 | 地域 |
|---|---|---|
| 文化放送 | 91.6 | 東京 |
| 日本放送 | 93.0 | 東京 |
| TBSラジオ | 90.5 | 東京 |
| NHK-FM | 85.1 | 長野 |
| NHK-FM | 82.5 | 東京 |
| J-WAVE | 81.3 | 東京 |
| RADIO LUSH | 80.7 | 静岡 |
この中から文化放送とTBSラジオを使うことになると思います。