JOURNAL

モールス信号変換ツールを作るときに考えたこと — 和文と欧文、多言語対応の壁

すみません、この道具は完全に私個人の目的で作成したものになります、WEBツールとは異なるわけなのですが、この子だけ蚊帳の外というのもかわいそうなので、ここに置かせてください…🙏

正直に言うと、モールス信号の変換ツールなんて「文字を・と-に置き換えるだけでしょ」と最初は完全になめてました。1週間もあれば終わるだろうと。

結果、思ったより長く付き合うことになりました。

和文と欧文は別物だった

まず躓いたのが、モールス信号には欧文(アルファベットや数字)用の符号と、日本国内で独自に発展した和文(カタカナ)用の符号があって、この2つがまったくの別物だということ。同じ「・-」の並びでも和文と欧文では意味が違う、というのを実装しながら初めてちゃんと知りました。

知ってはいたつもりだったんですが、いざコードに落とし込む段になって「あ、これ本当に別テーブルとして持たないと破綻するやつだ」と気づいた感じです。ボタン1つで切り替えられるようにして、誤爆しないよう注意書きも添えました。

UI言語という、もう1つの軸

で、これだけでも面倒なのに、サイトのUI自体を日本語・英語で切り替えられるようにもしたかったので、「和文か欧文か」という軸と「UIが日本語か英語か」という軸が、独立したまま同時に存在することになりました。頭の中で組み合わせを考えるとちょっとしたパズルで、深夜にホワイトボード代わりのメモ帳に4象限の表を書いて整理した記憶があります。テキストはdata-i18n属性と言語辞書で管理する形に落ち着きましたが、当初の見積もりより文言まわりの作業量が2倍近くに膨らみました。

見積もりが甘かったと言われれば、その通りです。

「PARIS方式」という速度基準と、その計算ロジック

もう1つ地味にハマったのが、符号を再生するタイミングと速度の計算です。モールス符号は「短点・長点・間隔」の長さの比率で成り立っており、この比率さえ維持すれば、再生速度(テンポ)をいくら変えても意味が崩れることはありません。

要素 長さ(短点=1単位として) 役割
短点(・)1単位基本となる「ト」の音(dit)
長点(-)3単位短点3つ分の「ツー」の音(dah)
符号内の間隔1単位同じ文字内の「・」や「-」の間の無音時間
文字と文字の間隔3単位次の文字に移る前の無音時間
単語と単語の間隔7単位次の単語(スペース)に移る前の無音時間

では、この再生速度(WPM:Words Per Minute / 1分間あたりの単語数)はどうやって計算しているのか? 調べてみると、国際的に「PARIS方式(PARIS method)」という標準規格が使われていることを知りました。

最初見たときは「なぜ突然パリ(PARIS)が出てくるの?」と思ったんですが、ちゃんと理由がありました。英語の平均的な単語の長さや文字の出現頻度(短点と長点のバランス)を統計的に表す代表例として選ばれたのが、この「PARIS」という5文字の単語だったのです。

文字 符号 符号の内訳(短点1 / 長点3 / 符号間1) 間隔 合計単位数
P·--·1 + 1 + 3 + 1 + 3 + 1 + 1 = 11単位文字間 3単位14単位
A·-1 + 1 + 3 = 5単位文字間 3単位8単位
R·-·1 + 1 + 3 + 1 + 1 = 7単位文字間 3単位10単位
I··1 + 1 + 1 = 3単位文字間 3単位6単位
S···1 + 1 + 1 + 1 + 1 = 5単位単語間 7単位12単位
1語(PARIS)の合計50単位

符号とスペースの時間をすべて足し合わせると、「PARIS」1語はちょうど【50単位】になります。

つまり、1 WPM = 1分間に50単位を送る速度と定義されているわけです。
たとえば 20 WPM で送信する場合:

  • 1分間(60秒)で送信する総単位数:50単位 × 20 = 1,000単位/分
  • 基本となる短点(1単位)の長さ:60秒 ÷ 1,000 = 0.060秒(60ミリ秒)

「PARIS」が5文字だから5文字/分、という文字数ベースではなく、「符号全体の再生時間長として50単位分」を標準の1語としているのがミソです。

このツールでは、速度調整スライダー(WPM)を動かしたときに、この式から短点1つのミリ秒数をリアルタイムに逆算し、Web Audio APIの発音タイミングやランプの点滅キューを生成しています。数式自体はシンプルですが、歴史ある通信規格の知恵が今もWebブラウザの中でそのまま動いていると思うと、なかなか感慨深いものがあります。

音と光のズレを誤魔化す

あとは音とランプの光を、体感でズレなく同期させる調整。符号の再生キューを1本用意して、そこから音のオン・オフとランプの点滅を同時に駆動する形にして、なんとか誤魔化しました。

単なる変換ツールのつもりで手を出したら、符号体系・UI言語・タイミングという3枚のレイヤーが絡み合う、想像より歯ごたえのある題材でした。次に「これは簡単でしょ」と思ったときは、その油断こそフラグだと自分に言い聞かせています。

オフラインでも使える自己完結ファイルを作った理由

このツールには、変換結果を音と光で再生できる自己完結型HTMLをダウンロードできる機能がひっそり付いています。地味すぎて誰も気づいてない可能性がありますが、これを入れた理由は自分の中では結構真面目な話です。モールス信号って、そもそも非常時のバックアップ通信手段という側面があるじゃないですか。それなのに、体験するために毎回ネット接続とサーバーが必要って、なんかコンセプトとして矛盾してないか、と作りながらふと思ってしまったんです。

それで、ダウンロードしたHTMLファイルをブラウザで開くだけで、音と光の再生が完結して、以降は一切通信が要らないようにしました。

モールス信号の画面
▲ 作った信号をダウンロードできます

ここで地味に面倒だったのが、外部ファイルへの依存を残すとフォルダごと保存しないと正しく動かなくなる問題です。そこで、CSS(見た目)・JavaScript(再生ロジック)・Web Audio APIによる音の合成(外部音声ファイル不要)の3つを、ファイル1個の中に全部詰め込みました。単体でどこに置いてもダブルクリックするだけで動くようになっています。

ダウンロードしたHTMLファイルの再生画面
▲ ダウンロードしたファイルだけで音と光の再生ができます

ファイル1個で完結してる状態を見たとき、「これはこれで職人技だな」と1人で満足していたのを覚えています。使う人がどれだけこの機能に気づいてくれるかは分かりませんが、「オフラインでも学べる」というモールス信号らしさを、道具としても体現できたんじゃないかなと思っています。救難信号用のファイルを作って、いざという時のためにスマホにダウンロードしておくのも一つの使い方です。