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誌で、モールス信号のデコーダーが紹介されたので、当たってみる。
製品名の数字が49って謙遜してるなあ。ああ、最初の4は以前にやったけど人間の主観による了解度(5段階評価で5が最高。-- 通知表のあれです。)了解度が4って事は、ほぼOKだけど、たまにミスるって事です。ここが5になる製品は何時発売になるのだろう? ググル様とタイアップしてAIで評価してもらわないとダメかな。
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。
これが状態とな。基本的に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に失敗してる。デバイスがオープン出来ないと言う致命的なエラーだな。
システムコールがエラーって、どゆ事? 長くなりそうなので回を改めるか。それまで、散歩だあ。散歩に適した、哲学の道は無いので、農道で我慢々。