2014年 04月 17日

1回休み

一昨日、15時ぐらいまでは普通だったが16時ごろから急激に悪寒、歯がガタガタしてどうしようもなく、18時ごろに会社を出た。電車に乗るうちに悪寒から吐き気になって途中下車。トイレに行って吐こうとしてみたが吐けず、とりあえず売店で買い物してビニール袋を用意しつつなんとか帰宅した。帰宅してからは吐き気よりもとにかく頭痛がひどくなった。帰宅した時点で体温は38℃前後だった。

仕事で対応が必要だったのでしかたなく VPN 繋いで居間で半分寝ながら1時間ぐらいごとに対応していたが、こっちで対応が必要になるタイミングがさっぱりわからずイライラした。おかげで悪夢倍増しつつだらだら夜中まで対応するハメになった。その日は結局居間で寝たが尻が痛くなった。

日があけて9時近くになったので病院に行って診察をうけたが今一原因はわからなかった。インフルエンザではなかった。鼻も喉もおかしくなく、下痢もないので、薬はロキソニンの処方だけだった。

とりあえず勤怠で休みますというメールをしたが、あいかわらず仕事でタイミング不明の対応が必要だったので1時間ぐらいごとにチェックして対応していた。

午後からは熱が下がった。たぶん仕事でイライラしすぎたせいで熱出たんだと思う。仕事ほんとしたくない。

2014年 04月 15日



関連エントリー (画像)

2014年 04月 11日


関連エントリー (画像)

Perl の Locale::Maketext::Lexicon::Gettext フォーマットのメッセージをJSでフォーマットする

Perl の Locale::Maketext::Lexicon::Gettext は以下のような Gettext ライクなフォーマットを扱うが、同じようなことを JS でしたいとき

%1 さん、こんにちは
%quant(%1,user,users)
  • %function() は任意の関数が呼べる感じなので、JS でもそのようにしておく。
  • numf は実装してない。
  • Locale.data= { ... } みたいなのが言語別に完全にわかれているのを想定してる
var Locale = {
    loc : function (msgid, arg) {
        var args = Array.prototype.slice.call(arguments, 0);
        var text = Locale.data[msgid];
        if (text) {
            if (/%/.test(text)) {
                text = text.replace(/%(\d)/g, function (_, n) {
                    return args[n];
                });
                text = text.replace(/%([a-z*#]+)\(([^\)]+)\)/g, function (_, func, args) {
                    if (func == '#') func = 'numf';
                    if (func == '*') func = 'quant';
                    args = args.split(/,/);
                    return Locale[func].apply(null, args);
                });
                return text;
            } else {
                return text;
            }
        } else {
            return msgid;
        }
    },

    quant : function (number, singular, plural, negative) {
        if (number == 0 && negative) { // no warnings
            return negative;
        } else
        if (number == 1) {
            return singular;
        } else
        if (plural) {
            return plural;
        } else {
            return singular + 's';
        }
    },

    numf : function (number) {
        return number; // XXX
    }
};
2014年 04月 10日

関連エントリー (画像)

2014年 04月 09日



関連エントリー (画像)

2014年 04月 07日


関連エントリー (画像)

2014年 03月 31日

関連エントリー (画像)

2014年 03月 27日

WebAudio FSK モデム

前文

我々は、ブラウザの WebAudio サポートによって、空気をメディアに使う方法を手に入れた。これにより、またひとつクロスドメイン通信の方法が増えたといえよう。

知っている人は少ないと思うが、古代人は空気によって伝送できる程度の周波数を用いてデータ伝送を行っていたという記録が残っている。これは失われた暗黒の技術であって、現在ではもはや ITU という国連の機関によってその存在の記録が残されているのみである。

デモ

小さな画像を音声帯域を使って送受信する

実際にマイク入力を使う場合、

マイク入力はやはり難しくて、周囲の環境によって波形が乱れるとうまくいかなかったりする。

V.21

ITU-T 勧告 V.21 は全二重 300bps の通信プロトコルで、変調方式は単純な FSK (周波数変移変調) になってる。

FSK

FSK (周波数変移変調) は、2つの周波数をそれぞれ 1 と 0 とに割当てて、切替えながら送信することでデータを送信する変調方法。単純でノイズに強いのが特徴。

かなり面倒くさがって WebAudio だけに依存するように書いたので、いちいち全サンプルに対して処理をしていてとても重い。アルゴリズム自体にも、もっと根本的にいい方法がありそうだけれど、知らないので直交信号をそれぞれヘテロダインする方法にしてある。

このへん、ノウハウがなさすぎて精度良く検出するのが僕にはかなり難しかった。

FSK 部分は以下

V.21 の周波数

既設の電話回線をデータ通信に応用する技術なので、可聴帯域の周波数を搬送波に使っており、全二重なのでチャンネルが2つある。つまり使う周波数は4つ。

  • channel No.1: FA=1180Hz, FB=980Hz (200Hz shift)
  • channel No.2: FA=1850Hz, FB=1650Hz (200Hz shift)

WebAudio + 空気の場合、別にこの帯域に拘る必要はなくて、可聴域限界ぎりぎりまで周波数をあげてもいいと思う。実際そのようにしても動くし、速度もあがるしモスキート音なのであまり煩くなくなる。今回はそれだとモデムっぽさがなくなってカッコよくないのでやめた。

プロトコル

プロトコルは以下のようにした

  • 非同期
    • スタートビット1bit
    • ストップビット1.5bit
    • データ8bit

でバイト単位のやりとりをする。1バイトにつき10.5bit使うので、最大で 28.6bytes/sec ぐらい。

さらにまとまったデータ送信のプロトコルとして以下のような xmodem ライクな実装を書いた

  • 送信側が待ちうけ
  • 受信側が NACK 送信
  • 送信側がデータブロック (128bytes) を送信
  • 受信側が ACK 送信
  • ... 繰り返し
  • 送信側が EOT を送信
  • 受信側は ACK を送信して終了

データ部は「SOH, データブロック番号, ビット反転したデータブロック番号」をヘッダにして、最後に CRC8 を付与している。これらが意図した値でなかった場合 NAK を返し、該当ブロックの再送要求をする。また、途中でバイト単位のやりとり自体が失敗した場合にそなえてタイムアウトによる再送もやってある。

まとめ

ポエティックでフィクションな前文を書くのを広めたい。

gerry++