SoftModemインターフェースボードとJavaScriptで通信

SoftModemインターフェースボードを購入したので、遊んでみました。


スイッチサイエンスさんでほぼ完成状態で販売されています(ピンヘッダ付けるだけ)。
SoftModemインターフェースボード--販売終了 - スイッチサイエンス


SoftModemインターフェースボードが使っている通信方式(FSK)は作者のarmsさんのブログで説明されています。
SoftModemインターフェースボード発売! - なんでも作っちゃう、かも。
Arduinoで遊ぼう - iPhoneのオーディオ端子を使って通信をする - なんでも作っちゃう、かも。

iPhone用のソース ( FSKSerialGenerator.m )を眺めてみたところ、通信方式仕様は

  • High(1)は7350Hz, Low(0)は4900Hzのsin波を送る。これを1225baudで切り替える。
  • 1文字(8bit)の前後にスタートビット(0)、ストップビット(1)を付けて、10bitで送る。
    • 要は送信したい文字をcとすると、(c<<1)|0x200 を送る感じ。
  • 一連の文字列の送信の前に、40msのHighをプリアンプルとして送る。(1225baudだと49bit分)
  • 一連の文字列の送信後には、5msのHighをプリアンプルとして送る。(1225baudだと6.125bit分)

という感じらしいと分かったので、自分でも実装してみたくなって作ってみました*1


Cでも何でも良いんですが、JavaScriptから音が鳴らせたらBookmarklet等と組み合わせて面白いことができないかなーなどと妄想したので、JavaScriptで。
# 本当はiPhone等のブラウザで動かしたかったのですが、後述の方法はMac/PCのブラウザでは動くものの、iPhoneSafariでは動作しないことが後で判明。。ちょっと残念。
## あと受信はできません…。


作ったコードはgithubにアップしてあります。
http://github.com/NeoCat/FSK-Serial-Generator-in-JavaScript/
.htmlファイルをHTML5対応ブラウザで開いて、"Generate and Play"ボタンを押すと音が鳴ります。これをSoftModemインターフェースボードに3.5mmステレオ4極ケーブルで繋いで流せば、文字列を送信できます。
Jumpを押すと、生成したサウンドを直接ブラウザで開きます。ここでSaveすれば生成した.wavファイルとして保存できるはずです。


JavaScriptから音を鳴らす方法としては、Data URI Schemeを使った方法があります。Data URIを利用すると、画像などのバイナリをJavaScriptで生成することができます。今回の場合は、WAV形式のサウンドデータを生成します。


WAVのフォーマットの情報としては下記が参考になります。
http://www.kk.iij4u.or.jp/~kondo/wave/


詳しくはスクリプトを見て頂くとして、まずは8bit/mono、リニアオーディオ形式のヘッダを作ります。サンプリング周波数は生成するバイナリのサイズを小さくするため上記High/Lowがぎりぎり表現できる29400Hzを選びましたが、44100Hzでも大して変わらなかったかも。あとは、指定されたテキストをASCIIコードを表現するFSK変調したsin波を8bitのバイナリ(つまり0〜255)で表現していきます。

なお、テキストとしてnon-ASCIIな文字が指定された場合は、UTF-8エンコードしています。(こういう操作もJavaScriptでは関数一発ではできず、自前でバイナリとしてごりごり変換しています)


WAVデータができあがったら、それをbtoa関数でMIMEエンコード & escapeし、前に

data:audio/wav;base64,

という文字列をくっつければ、Data URIのできあがりです。

あとはHTML5のAudioオブジェクトにこのData URIを指定して

	audio = new Audio(dataURI);
	audio.play();

で再生できます。


生成した波形をwavとして保存してspwaveで開いてみたところ。2種類の周波数があるのが分かります。

そういえば、iPhoneアプリの「音響電文」とも通信できるみたいです(通信といっても一方向だけですが)。JavaScriptだけじゃ録音できない(多分)から受信は難しいだろうなあ。

*1:実際にはSoftModemインターフェースボードが届く前に書いたのですが、一発で動いてしまって自分でびっくり。FSKって簡単ですね〜。