モールス信号発生器
友達が撮った飛行機の中に、エンジンの写真が含まれていたそうな。その写真を見た 友人は、ふと飛行機、ジェットストリームの連想で、i-tunesから、「ジェットストリーム」 のCDを購入して、聞いているとか。
曲の合間に効果音で、管制塔とのやり取りとか、モールス信号で発せられるビーコン 信号が使われていたそうな。そのモールス信号を聞くとはなく聞いてみると 「JFK:ケネディ空港」だったとか。
いいなあ、私もたまには聞いてみたいよ。今から40年も前にモールスを覚えた事が あるけど、今、どれぐらい取れるかなあ?
モールス信号を聞く
早速、Vectorへ 行って、A1A Breaker というのを落としてきた。モールスコードの半分ぐらいは、頭から 蒸発してたよ。BGMとして、暫く聞いてみようかな。そのうちに、思い出してくるか。
BGMと言えば、先の友人に教えてもらった 標準周波数報時シミュレータ STEMU と言うソフトも楽しい。NCITが、アナウンサーの声を提供するなんて、なかなか味な事を するわい。
で、昨日から A1A Breakerを聞いているんだけど、つい悪い癖が出てしまった。自分で、 これと同等のものを作ってみたくなった。
まずは、資料集めですね。 世界の百科辞典 を引いて、ここを基点に モールス信号へのお誘いを経由して 初心者向けエレクトロニックキーヤ-の使い方 に、やさしい説明を見つけた。
モールス信号発生器
ハムフェア2009へ行けば 「オリジナルモールス練習機(会場価格2,500円)」等と言う楽しい工作が出来るようだ が、もう、こても部品もすっかり処分してしまっているので、パソコンでやってみる。
えっと、まずブザーを鳴らすんだな。それからちょっとお休みしろと言う命令があれば 何とかなりそう。私の部品箱 へ行って、適当に調べればいい。
今回は、音を鳴らすんだから、beep かなあ。お休みだから、sleepかなあと当たりを つけたら、ぴったんこのやつがヒットした。
後は、発生器をどういう構成にするかだな。発生して欲しいモールス信号を、コマンド引数か 何かから、"CQCQ DE 8J1A" とかするか。これじゃ、RTTYみたいで面白みに欠ける。
もっと単純に、ト・ツー・ツーみたいに与えたほうが、何となく、モールスっぽくて 面白い。もう一つ考えておかないとならないのは、文字区切り(やワード区切り)を どうするかだ。一文字づつ、発生器を呼び出すのもオーバーヘッドが大きそうだ。 一文(1行)単位ぐらいで呼ぶのが良さそう。
そうなると、文字区切りのマークとワード区切りのマークも定義しておいて、ト・ツーも 含めて、モールス記号となるな。まとめると、
- s
- ト(短点)を表わす、1単位分の発声、これに続き、必ず1単位の停止あり
- l
- ツー(長点)を表わす、3単位分の発声、これに続き、必ず1単位の停止あり
- c
- 文字区切りを表わす、3単位分の発声停止
- w
- ワード区切りを表わす、7単位分の発声停止
"I AM A" ならば、"sswslcllwsl" と言う文字列を、モールス発信器に送る事になる。これ 私が今決めた、文字列は、別アプリにより発生させる事にしよう。
後は、お好みだけど、発生スピードと、発生周波数も指定出来るようにしておこう。 これらはオプション扱いにする。指定しなかった場合は、発生スピード、短点の長さが 100ms、周波数は、440Hzとしよう。
原始的モールス発生器
一応、Windows限定って事で
#include <windows.h> #include <stdio.h> #include <stdlib.h> long freq = 440; // beep freq in [Hz] long t = 100; // dot length in [MS] long t3 = 300; // dash length in [MS] long t2 = 200; // between char break length in [MS] long t6 = 600; // between word break length in [MS] sett(long t){ t3 = t * 3; t2 = t * 2; t6 = t * 6; } osc(char *str){ int c; while ( (c = *str++) ){ switch (c) { case 's': case 'S': Beep(freq, t); Sleep(t); break; case 'l': case 'L': Beep(freq, t3); Sleep(t); break; case 'c': case 'C': Sleep(t2); break; case 'w': case 'W': Sleep(t6); break; default: exit(2); // Bad char, soon exit } } } main(int argc, char *argv[]){ if (argc > 3){ freq = atol(argv[3]); } if (argc > 2){ t = atol(argv[2]); sett(t); } if (argc > 1){ osc(argv[1]); } if (argc == 1){ printf("Usage: mosc.exe \"slcw\" [speed freq]\n"); exit(1); } exit(0); }
既定した文字以外が発見された場合、実行は即座に終了する。
実行例
c:\borland\work\beep\Debug>mosc.exe Usage: mosc.exe "slcw" [speed freq] c:\borland\work\beep\Debug>mosc.exe slclsss c:\borland\work\beep\Debug>mosc.exe sssClllCsss 80 c:\borland\work\beep\Debug>mosc.exe lslscllslwlsscs 120 880 c:\borland\work\beep\Debug>mosc.exe sssXsssclll
最後の例では、"sss"の後、例外文字があったので、実行は、打ち切りとなった。 なお、一度動き出したプログラムは、CTRL+Cで停止するか、全コードを発声し終わるまでは、 終了しない。