Morse

前回から始めた GNURadioという無線機の作成ソフト。部品をボード上に置いて配線するだけで、色々な機能を実現出来る。年取って、眼がおぼつかない、指が震えて、半田ブリッジの心配もいらないので、思いつく間に色々とやってる。

無線の教科書に出て来る、DSBの変調波を見たいので、タイムドメインで観測するオシロスコープと周波数ドメインで見るスペクトラムアナライザと、それらを総合して見るwaterfall装置を 付けたりしてる。

で、DSBの波形が教科書通りになるか? 搬送波を30KHzぐらいにし、被変調波は音声を模したものにしたい。音声の第一フォルマントは200Hzぐらい? その倍音を数種用意したいな。となると、audio帯のミクサーが必要になるな。audio帯なんで、単純に足し算回路でいいんだな。

これ、ちょいと面倒。で、手抜きしよう。三角波とかノコギリ波には、倍音が豊富に含まれているはず。ならば、被変調波はこれらでいいじゃん。

実際にやってみると、サイドバンドが豊富に出すぎちゃって、コム(櫛)ジェネレータになっちまったよ。音声発生の原理に従って、各種のフィルターを突っ込んで、倍音を減衰させればいいんだな。これもちょいと面倒そう。ファイルからの入力も受け付けてくれるようなので、ラジコあたりの番組を録音して使えばいいのか? どうやる? 確かplamoの人がやってたな。後で調べてみよう。

そうそう、Chromeだと、音が出ない改悪が施されている可能性がある。

Since April 2018, the Chrome browser is reluctant to play audio on WebSDR
sites. If you use Chrome and have no audio on WebSDR sites, a workaround is
to switch off Chrome's new autoplay policy, by typing
chrome://flags/#autoplay-policy in the navigation bar and changing this
setting from Default to No user gesture is required
(and restarting the browser).

そんな横暴を跳ね除けるには、上記のようにするとな。

所で、被変調波を方形波に変えて、周波数を2Hzぐらいに設定すると、電波形式でA1Aの波形が出て来る。キャリアー波を700Hzぐらいに変更すると、ト・ト・ト・ と聞こえるじゃないですか。

Windows7機には、CWの学習用ソフトを色々と入れていたんだけど、今はその機がDebianなマシンに変身してるんで、気楽にモールスを聞けないな。Debianで何とかならないか?

ええ、WindowsOSには、余計な物を入れない主義なんで。

Windows 10でLinuxプログラムを利用可能にするWSL(Windows Subsystem for Linux)をインストールする(バージョン1803対応版)

でも、こんなお誘いが有るんだよな。お店で各種版を無料配布してるしなあ。でも、リナだけっている偏りが有るんで、今の所この話に乗る事は無い。

CWとは

ウィキによれば

無変調連続波(continuous wave)。信号が変化しないため通信機器の測定が簡単な構成で
できる。
アマチュア無線家の間では「CW」という略語は、(無線)電信の意で使われている。なお、
厳密には搬送波を断続するという変調方式の一種であり、日本における現行の電波型式の
表記法では「A1A」である(特殊な局などが発することがある、全く無情報の電波は「N0N」)。

世界最古の、デジタル通信。可変長符号方式で伝送効率を上げているのが味噌。モールス さんが実用化したんで、morseと言う事もある。

上で実験したのは、たまたま非変調波の方形波が、1-0でスイングしてたんで、1の時は、 搬送波がそのまま出て来る。0の時は、掛け算した結果も0と言う事で、搬送波が断続される 結果になった。

仮に、方形波が1と-1の間をスイングすると、-1の時は、搬送波が反転する(位相が180度シフトする)事になるんで、位相変調の一種になる。(BPSK)

アマチュア無線では、CWをやる人は世界遺産に登録されるけど、通信効率を上げるため、略語が 頻繁につかわれる。CW略符号 (CW Abbreviations)この中に、数字だけの略語も出て来る。

73とか88みたいなの。何で数字だけ? 無線電信が商業化された時、定型文を送る事が多かった。(例えば、ハハキトク、スグカエレとかカネオクレみたいなの)だったら、これらを数字で表しちゃえってのは、自然の発想として出て来る。77とかは、それらの名残なのさ。

CW decoder

CWとなれば今月号のCQ誌で、モールス信号のデコーダーが紹介されたので、当たってみる。

モールス符号解読&キーヤー CW-49

製品名の数字が49って謙遜してるなあ。ああ、最初の4は以前にやったけど人間の主観による了解度(5段階評価で5が最高。-- 通知表のあれです。)了解度が4って事は、ほぼOKだけど、たまにミスるって事です。ここが5になる製品は何時発売になるのだろう? ググル様とタイアップしてAIで評価してもらわないとダメかな。

モールス符号の解読アルゴリズムについて

CWデコーダー

ラズパイ Python モールス符号解読器

mbed CWデコーダ ~欧文解読

cwdecoder を試してみた ~その1~

Debianでmorse

探してみたら、詰め合わせセットと思しき物が有ったので入れてみる。

deb9:~$ sudo apt install hamradio-morse
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  aldo cw cwcp cwdaemon ebook2cw hamradio-tasks libcw6 morse morse2ascii qrq
  xcwcp
Suggested packages:
  cwirc flwkey
The following NEW packages will be installed:
  aldo cw cwcp cwdaemon ebook2cw hamradio-morse hamradio-tasks libcw6 morse
  morse2ascii qrq xcwcp
0 upgraded, 12 newly installed, 0 to remove and 0 not upgraded.
Need to get 672 kB of archives.
After this operation, 11.6 MB of additional disk space will be used.
Do you want to continue? [Y/n]

色々と入ったようなので、順ぐりに試してみた。

debian:~$ aldo
Aldo 0.7.7 Main Menu
        1: Blocks method
        2: Koch method
        3: Read from file
        4: Callsigns
        5: Setup
        6: Exit
Your choice: 1

xcb_connection_has_error() returned true
Keying speed: 10 wpm
String length: 5
Number of strings: 3
Training character set: e,i,s,h,t,m,o
Chars mixed without group order
About to start keying. Get ready...

Please input the signs you copied.
If you didn't copy a sign, put '@'.

これは、モールスコードを覚える人用みたいだな。

debian:~$ cw
cw: PulseAudio output not available (device: ( default ))
cw: OSS output not available (device: /dev/audio)
hello
hello

キーボードから入力したのを、オウム返しにモールス信号にしてくれる。

debian:~$ cwcp
cwcp: PulseAudio output not available (device: ( default ))
cwcp: OSS output not available (device: /dev/audio)

+Mode(F10v,F11^)---++Start(F9)-------------------------------------------------+
| Letter Groups    ||UNIX/Linux Morse Tutor v3.5.0                             |
| Number Groups    ||Copyright (C) 1997-2006 Simon Baldwin                     |
| Alphanum Groups  ||Copyright (C) 2011-2015 Kamil Ignacak                     |
  :
+------------------++----------------------------------------------------------+
+Speed(F1-,F2+)++Tone(F3-,F4+)-++Vol(F5-,F6+)--++Gap(F7-,F8+)--++Time(Dn-,Up+)-+
|    12 WPM    ||    800 Hz    ||     70 %     ||    0 dots    ||   0/15 mins  |
+--------------++--------------++--------------++--------------++--------------+

オイラーの好きなCUIバージョンで色々制御が出来る。聞き取り練習にうってつけ?

debian:~$ qrq
┌──────────────────────────────────────────────────────────┐┌──────────────────┐
│QRQ v0.3.1 by Fabian Kurz, DJ1YFK                         ││     Toplist      │
│Homepage and Toplist: http://fkurz.net/ham/qrq.html       ││                  │
└──────────────────────────────────────────────────────────┘│ YT6W      202472 │
┌──────────────────────────────────────────────────────────┐│ HA8KW     148892 │
│Usage:                                                    ││ DL4UNY    145549 │
│ After entering your callsign, 50 random callsigns        ││ SV2KBS     98758 │
│ from a database will be sent. After each callsign,       ││ YT1BX      97934 │
    :

こちらは、競技者養成コース風、コールサイン聞き取り。信号音にフェーディングがかかっていたり、トーンが高かったり低かったりと、実際のリグで聞いているような臨場感が有る。

morse on FreeBSD

FreeBSDでもモールス出来るか確認。

[fb11: tmp]$ echo hoge | morse
 di di di dit
 dah dah dah
 dah dah dit
 dit

[fb11: tmp]$ echo hoge | morse -p
/dev/speaker: No such file or directory

man morse すると

     -d device
             Similar to -p, but use the RTS line of device (which must by a
             TTY device) in order to emit the morse code.

どうやらレガシーなデバイス専用っぽい。 一応、サウンド系がどうなってるか確認。

[fb11: tmp]$ cat /dev/sndstat
Installed devices:
pcm0: <AudioPCI ES1371-A> (play/rec) default
No devices installed from userspace.
[fb11: tmp]$ dmesg|grep pcm
pcm0: <AudioPCI ES1371-A> port 0x2040-0x207f irq 16 at device 2.0 on pci2
pcm0: <Cirrus Logic CS4297A AC97 Codec>
pcm0: <Playback: DAC1,DAC2 / Record: ADC>

このデバイスを指定しても、スピーカーが欲しいと言われるんだよな。

speakerデバイスは、option speaker して、カーネルに組み込めって説明がmanに有るんだけど、これって旧世代の人用の説明。今ならダイナミックローディングでしょ。kldloadするなり、

[fb11: sakae]$ cat /boot/loader.conf
speaker_load="YES"

して、起動時にdriverを組み込めばよい。んだけど、このままではrootさんしか使えない。なんたって、大音量攻撃(場合によっては、某大使館の人達を不快にさせた攻撃が出来ますから)の恐れが有りますからね。rootの仲間なら使っていいよって事にする。

[fb11: sakae]$ grep speaker /etc/devfs.conf
# Allow members of group operator to cat things to the speaker
#own    speaker root:operator
perm    speaker 0660

permのコメントを外してあげる。これでspeakerからbeep音が出て来るようになる。beepな音なんで、汚いけどね。でも、このパッケージを入れると、CWでのラグチューを模したpod(みたいなの)が付いてくるよ。

[fb11: sakae]$ QSO
KF6BZF de VE6MGS
QTH is Southwest Salisbury, Ohio.
Your signal is RST 588/588.
Rig is a Swan 140 running 2 watts into a parasitic beam up 45 1/2 feet.
Name is Hadassah.
My occupation is programmer.
Age is 72.
Can you pick kryptonite locks?
I have been a Technician class ham for 3 years.
WX is sunny.
Temperature is 84.
+%=x/,? 73 just testing you.
+ %
KF6BZF de VE6MGS

温度が84度って、どんな灼熱地獄よ? 全くあちゃらの目盛りで言われると、とっさに変換できんよ。

ああ、上記のQSOってアプリが吐き出すやつは、あくまでもヒアリング用。本物のQSO(交信)を 模したやつが、リナに入ったcwに付いていたぞ。

The following example contact is taken from the CW section of the
RSGB's publication "Amateur Radio Operating Manual".

}%M0;{
}%T800;CQ CQ CQ CQ DE G4ZZZ G4ZZZ K {

}%T1200;G4ZZZ G4ZZZ DE WD9ZZZ WD9ZZZ [AR] {

}%T800;WD9ZZZ DE G4ZZZ GA OM ES MNI TNX FER CALL = UR RST 579 = {
}NAME JOHN ES QTH LONDON = SO HW CPY? [AR] WD9ZZZ DE G4ZZZ K {

}%T1200;G4ZZZ DE WD9ZZZ R FB JOHN ES GM OM = UR RST 559 = {
}QTH SR [HH] SPRINGFIELD, ILL = NAME IS ED = SO HW? [AR] G4ZZZ DE WD9ZZZ K {

}%T800;WD9ZZZ DE G4ZZZ SRI OM QRM5 = PSE RPT UR NAME?? BK {

}%T1200;BK NAME IS ED ED ED BK {

}%T800;BK R R TNX ED = QRM GONE = RIG IS HOMEBREW WID 75W INPUT = {
}ANT IS DIPOLE = MNI TNX FER QSO ES CU AGN = {
}73 ES GB [AR] WD9ZZZ DE G4ZZZ [VA] {

}%T1200;G4ZZZ DE WD9ZZZ R UR RIG T9X ES FB = RIG HR IS TS520 = {
}ANT IS 2EL QUAD = WL QSL VIA BURO = SO 73 ES GUD DX = {
}GB [VA] G4ZZZ DE WD9ZZZ {
}

時々出て来る%T800とかは、トーン800Hzで発音しなさいって指示なんだな。800Hzの人が交信相手を求めてCQを発砲。1200Hzの人が、それに答えて来たってドラマ設定だな。結構業界略語が使われてるね。

暫く使ってみたけど、チープなビープ(ひずみ率は約48%、倍音は豊穣ですよ)には耐えられないので、次のOSにバトンタッチしましょ。

morse on OpenBSD

探してみたら、morseplayerってのが、唯一のものみたい。使う前にOpenBSDのサウンド系が どうなっているか事前に調査しておく。参考にしたのは次のFAQ。

FAQ - Multimedia

これが状態とな。基本的にaudioってデバイスとmixerしか無いという、どこかの混沌としたOSとは違うのさって思想だ。

ob$ audioctl
name=azalia0
mode=
pause=0
active=0
nblks=2
blksz=960
rate=48000
encoding=s16le
play.channels=2
play.bytes=0
play.errors=0
record.channels=2
record.bytes=0
record.errors=0

続いて、dmesgの確認。azalia0ってデバイスがaudioデバイスに割り当てられているって風に読める。

azalia0 at pci0 dev 27 function 0 "Intel 82801I HD Audio" rev 0x03: msi
azalia0: codecs: Realtek ALC269, Intel/0x2802, using Realtek ALC269
audio0 at azalia0
ob$ cat > /dev/audio < /dev/zero &
[1] 47699
ob$ audioctl play.{bytes,errors}
play.bytes=2698240
play.errors=0
ob$ audioctl play.{bytes,errors}
play.bytes=4743680
play.errors=0
ob$ kill %1
ob$
[1] + Terminated           cat > /dev/audio < /dev/zero

続いて、audioデバイスがちゃんと機能してるかのテスト。zeroデータをどんどんとaudioデバイスに送り込んで、ちゃんと送られたかエラーは無いか確認。大丈夫そう。

ob$ echo hello | morseplayer
ob$ cat | morseplayer
CQ CQ DE JA1AAA

2番目の例は、リナに有ったcwってのと同じ機能を実行。FreeBSDと比べて、綺麗な音で聞こえる。シグナルレポート 599です。FreeBSDのそれは、596ぐらい? 最後の6とかはCW特有なレポートで、音の質を(9段階評価)表す。

昔は送信機を自作したものだ。 電源が貧弱だったりすると、送信した瞬間に電圧がドロップしてチャーピーな音に聞こえたり、配線が悪いと電源のハム音を拾って、音が濁る事が有るんだ。んなわけで、音の品質を報告してたのさ。

気をよくしたオイラーは、virtualboxに入れたOpenBSDでも動くだろうと思って試してみた。 (上記の試験は、ポータブルOpenBSDをThinkPad/SL510に刺しての実機試験でした。)

ob$ echo hello | morseplayer
morseplayer: Could not open sndio device

えっ

ob$ cat > /dev/audio < /dev/zero &
[1] 2529
ob$ ksh: cannot create /dev/audio: Invalid argument

[1] + Done (1)             cat > /dev/audio < /dev/zero

えっえーーーーー。

こうなれば、ソースをお取り寄せしてgdbの出番かなあ?

ob$ cc -g -O0 morseplayer.c -lm -lsndio

OpenBSD用にpatchが当たったものを、コンパイルしたよ。で、与えるテキストを作っておこう。こういう時にうってつけなのが、SOSって電文。

大体SOSの語源は、Save Our Ship とか Save Our Soul によるらしい。これが初めて使われたのは、氷山とぶつかったタイタニック号らしい。

shipの方は文字通り船を助けてになるけど、Soulの方は、もう神に祈るの心境だ。オイラーなら、八百万の神にお願いしますだな。本来、debugってそういうものでしょ。

そんな訳で、ひたすらSOSを連発する電文を作っておく。

[fb11: tmp]$ yes s | paste -d'o' - - | head -n 100 > SOS
(gdb) b main
Breakpoint 1 at 0x2ac6: file morseplayer.c, line 723.
(gdb) r < SOS
Starting program: /tmp/a.out < SOS

Breakpoint 1, main (argc=1, argv=0xcf7d2f84) at morseplayer.c:723
723             float cwpm = -1.0, owpm = -1.0, pitch = -1.0;

歩を進めて行くと、

  =>      pars.hdl = sio_open(afname, SIO_PLAY, 0);
          if (pars.hdl == NULL)
                  errx(1, "Could not open sndio device");

こんな所に到達する。ここで落ちるんだな。afnameは冒頭の所でnullに設定されてるけど、これはちゃんと動く環境でも同じ。と言う事は、sio_openの中に潜って行く必要が有りそう。

        if (strcmp(str, devany) == 0) {
                hdl = _sio_aucat_open("snd/0", mode, nbio);
                if (hdl != NULL)
                        return hdl;
=>              return _sio_sun_open("rsnd/0", mode, nbio);

sio.cっていうライブラリィーの中。afnameがnullだと、バックワードコンパチでDEVANYが有効になって、内部的には、rsnd/0 が使われるようだ。

  struct sio_hdl *
  _sio_sun_open(const char *str, unsigned int mode, int nbio)
  {
          struct sio_hdl *hdl;
          int fd;

B =>      fd = sio_sun_getfd(str, mode, nbio);
          if (fd < 0)
                  return NULL;

ここでfdが正しく得られていないっぽい。

Breakpoint 3, sio_sun_getfd (str=<optimized out>, mode=<optimized out>, nbio=15\
7245323) at /usr/src/lib/libsndio/sio_sun.c:302
302             while ((fd = open(path, flags | O_NONBLOCK | O_CLOEXEC)) < 0) {
(gdb) p path
$7 = "/dev/audio0\000\v}\317,O_)\020\002\343|"

ここのopenに失敗してる。デバイスがオープン出来ないと言う致命的なエラーだな。

システムコールがエラーって、どゆ事? 長くなりそうなので回を改めるか。それまで、散歩だあ。散歩に適した、哲学の道は無いので、農道で我慢々。