HTML5でワードアートするJSライブラリ作った

以前は商店街のチラシや自治会のお知らせなんかでよくワードアートが使われていました。もう最近は目にすることも少なくなりましたが、ワードアートのレトロで独特の雰囲気は見る人をなごませるように思います。
そんなわけで、最新のウェブ技術の粋を集めてワードアートを再現するライブラリwordart.jsを作りました。
http://aikelab.net/wordart/

 

 
 
こんな文字列にするといかにもな雰囲気が出ます。


 
 
最先端のインフォメーションもワードアートにするとまるで90年代のようです。


 
 
世界的な大イベントもほらこのとおり、なんだか町内会っぽい。


 
 

不思議な円グラフを描くウェブサービス作ったよ

最近ツイッター界隈で不思議な円グラフを見かけました。
こんなやつです。

ちょっと調べてみると昨年の報道番組からキャプチャした映像のようです。
 
このグラフを見て、その手があったか!という新鮮な驚きを感じました。これまでの円グラフの常識にとらわれず、円の中心からあえてずらした位置から分割することで飛躍的に表現の幅を向上させています。無味乾燥で機械的なグラフにくらべて製作者の強い思いがぐっと伝わってきます。なんとイノベーティブでなんとワンダーなグラフなのでしょう。
 
でも、このグラフ、実際に描こうと思うとけっこう面倒です。Excelのグラフ機能をみても中心点の位置をずらす方法はなさそうです。
 
そんなわけでゆがんだ円グラフを描くウェブサービスを作りました。

ワンダー・グラフ・ジェネレイター

f:id:aike:20130718185842j:image

項目の追加変更はもちろん、中心をずらしたり、楕円形にして項目を強調したりできます。円グラフの秘められた表現力を感じてみてください。
それからレポートで使うとたぶん怒られます。
 


Still Life

Still Life

通勤用シンセにKORG M01D買ったよー

最近転職して勤務地が遠くなったので毎日高速バスで通勤するという水曜どうでしょうサイコロの旅みたいな生活をしています。そんなわけで移動中の時間にDTM的なものができないかいろいろ考えてました。ノートPCもカバンに入ってるんですがやっぱり隣に人が座っていたりするとひじがぶつかったりしてちょっと狭い。すでに持ってるDS-10か、それともちょうど今月発売のvolca keysかM01Dにしようかと考えてM01Dを買ってみました。
 
決め手としては、音色作りというより曲のスケッチに向いている点です。なにしろM01Dは割り切り方がすごい。シンセといっても音色関係のパラメータはAttackとReleaseだけ。音色作るのってそれはそれですごく楽しいんだけど、曲を作るって決めたときはこのくらい制限がある方が悩まなくていい感じです。エフェクトは、トラックごとにON/OFFできるものの、全体で1種類リバーブかディレイのみ。それでもそのまま使いやすいプリセットの音色がそろってるのであんまり困りません。びっくりするほど分厚いポリシンセの音がこんな小さなゲーム機から出たりしてなんだか技術の進歩を感じます。
 
シーケンサーは64ステップ×99シーンあり5分くらいの曲なら十分だし、パートは8トラックで同時発音数も24音ということで、和音楽器×3+ドラム+ベースくらいなら余裕です。そうそう、一番大事なところですが、変拍子もできますよ。これでプログレの人も安心ですね。
 
そんなわけで最初に書いた曲がこんな感じ。M01Dだけで鳴らしてます。

 


ニンテンドー3DS LL ブラック (SPR-S-KKAA)

ニンテンドー3DS LL ブラック (SPR-S-KKAA)

エクスコムの情報流出はシステム設計というより業務設計がだめな件

そんなわけでクレジットカード再発行しました。そうです流出です。今年の3月にアメリカ行ったときに海外旅行者向けWiFiルーターレンタル業者を探してたらエクスコムが安かったので申し込みました。まさかこんなことになろうとは、という感じでくやしかったのでブログのネタにしてみました。
 
申し込みから返却まで経緯はこんな感じでした。
 
■3月5日 申し込み

エクスコムのウェブフォームから住所氏名とともにクレジットカード情報を入力して申し込んだら、こんな確認メールが返ってきました。一部省略、伏字にしています。

 Subject: レンタルお申し込みありがとうございます
    Date: 5 Mar 2013 10:46:21 +0900
    From: エクスコムグローバル株式会社

この度は、お申込みいただき、誠にありがとうございます。
ご利用に際しては、以下の注意事項をご確認ください。
(略)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
ご利用料金合計 : 14,455円
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
(略)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
■ 支払い情報
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
クレジットカード
カード会社         : Master
カード番号         : ************9999
セキュリティコード : **9
有効期限           : 99 / 9999
カード名義人       : oooooo oooooo
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
(略)

上記の***は実際のメールでも***と伏字になっています。999の部分は実際のメールではカード番号などの一部だったところを引用時に置き換えました。
このメールを見たときに伏字とはいえセキュリティコードを返送してきたことに疑問を持つべきでした。
 
さらにメールにはこんなことも書いてあります。

■ご請求について
ご返却頂いた3営業日後に、ご請求書を発行もしくはクレジットカード決済いたします。

なんと、このメールは決済完了メールではなかったのです。
さらっと書いてあるこの文の意味は重いです。
 
■3月8日 WiFiルーター受け渡し
さて、受け渡しは出発当日に成田空港のエクスコムのカウンターでおこなうことを選択しました。本当に受け取るだけ。保証金などの支払いも発生しません。
 
■3月18日 WiFiルーター返却
予定通り帰国して成田空港の借りたときと同じカウンターに行って返却しました。このときも一式確認するくらいでお金のやりとりはありません。
 
■3月19日 領収書メール受信
返却の翌日以下のメールが届きました。

 Subject: 【領収書】エクスコムグローバル(株)(No.XXXXXXXXXXXXXX)
    Date: 19 Mar 2013 23:07:55 +0900
    From: info@xcom-XXXXXXX.XXX

平素は格別のご愛顧を賜り、心より御礼申し上げます。
領収書を添付しておりますので、ご査収頂きますようお願い致します。
(略)

 
添付されてきたPDF形式の領収書の一部がこれ。

あー、良く見たら決済日が今日(返却の翌日)になってる。つまり、申し込み日ではなく、返却後に決済する方針なんですね。これを実現するには確かにクレジットカード番号や名義、期限、セキュリティコード情報を少なくとも返却時点まで保管しておく必要がありますね。おそらく、紛失や延滞などの申し込み時点では含まれていない追加料金が発生した場合に二度手間にならず確実に徴収するためにこうしているのでしょう。
 
気持ちはわかるけどだめですね。やっちゃいけない業務設計です。システム開発者の方でも、これは満たしちゃいけない要件だと気づくべきです。
 
Amazonなどのワンクリックショッピングに少し似てますが、あれはAmazonへのログインで当該顧客を特定しているし、なにより購入者が決済タイミングを自覚しています。しかも十分信頼のおける大企業でないとなりたたない方式です。
 
レンタカーなどと違い、WiFiルーターは小さい機器であり、紛失の可能性も多く、海外へ行ってしまうため借りたまま持ち逃げされても取り立てが難しく、乗り継ぎのあわただしい時間で受け渡すようなことを考えるとカウンターでの支払い作業は減らしたい、といったような理由でこうしたのでしょうね。
 
でもだめですね。
 
じゃあ、どうすればいいのかというと、あんまり良い案を思いつきません。たとえば、申し込み時に保証金を乗せた額を提示し決済して返却時にカウンターで保証金分を現金で返すとか、前金制のホテルみたいに最初に通常料金を払って、もし追加料金が発生すれば返却時にカウンターで支払うとか。どちらも手間だけど。
そもそも海外旅行者向けWiFiレンタルという業態がオンライン決済に向いてないのかもしれないとか思ったり。
 
2013/5/31追記
おー、ブクマとかツイートで僕より詳しい人がいろいろコメントしてくれてますね。ありがとうございます。正しいやり方として、申し込み時に与信(オーソリ)だけやって利用後に売上処理をやる、あるいは決済代行会社のカード番号あずかりサービスを利用する、といった方法があるようです。後から売上確定ってシステムは少し携わったことあるけど、あれって確定/キャンセルくらいしかできないかと思ってました。まだまだ修行が足りません。
今回このエントリーを書くにあたって参考にした記事では、エクスコムの担当者も正しいやり方を知らなかったみたいです。僕と一緒に修行しよう。

【速報】イモトのWiFi・グローバルデータが11万件クレジットカード流出。セキュリティコードを含み、発表も1ヶ月後 | ライター三上洋 事務所
Q:なぜ自社サーバーに、クレジットカード番号・セキュリティコード・住所を紐付けて保存していたのか?(筆者注:この手の情報は自社サイトにおかないのが現在では一般的)
A:海外渡航者にWiFiをレンタルする業務を行なっている。決済額はお客様からの申し込み時点ではわからない。日本に帰国後に、空港のカウンターで決済する。申し込み時には決済できないので、クレジットカード番号を自社サーバーに保存していた。

 

Web Audio APIでオシレーターの実装方式いろいろ試してみた

あなたの好きな波形は何ですか。人はだれしも思い入れのある波形があるかと思います。矩形波が好きなかたもいるようですが僕はだんぜんノコギリ波派です。ノコギリ波の優しくて存在感のある音色につつまれているだけでしあわせな気持ちになります。
 
そんなわけでみなさんこれから多くのシンセをWeb Audio APIで作成するかと思いますが、いくつかあるノコギリ波のオシレーター実装方法について比較してみたいと思います。また、ソフトシンセを作るうえで避けて通れないエイリアスノイズについて方式ごとの差異を聴き比べてみます。
 
こちらのページで実際に聴きながら読んでください。(Chrome推奨)
http://aikelab.net/sawwave/
 
■ナイーブな実装

    return 1.0 - (this.phase / Math.PI);

こんな感じの処理を1サンプルごとに呼ぶとノコギリ波になります。高い音になるほど濁ったようなエイリアスノイズが聴こえると思います。自分も完全に理解しているわけではありませんが、倍音の周波数(例:440Hzの場合、880Hz, 1320Hz, 1760Hz, ...)がナイキスト周波数(例:サンプリングレート44100Hzの場合22050Hz)を越えると波形が再現できなくて可聴域にノイズが出るとのことです。そのため高次の倍音を多く含む波形ほどノイズが目立ちます。
この実装方法は処理としては軽いものの高音にはちょっと使えませんね。僕のWebAudioSynthはこの方式です:-p
 
■オーバーサンプリング

    var w = 0.0;
    var i;
    for (i = 0; i < this.oversampling; i++) {
        this.phase += this.delta / this.oversampling;
        if (this.phase > Math.PI * 2) {
            this.phase -= Math.PI * 2;
        }
        w += (1.0 - (this.phase / Math.PI)) / this.oversampling;
    }
    return w;

エイリアスノイズ対策として良く使われるのがオーバーサンプリングです。たとえばサンプリングレートの2倍の細かさで計算して、その後隣接する2サンプルの平均をとってもとのサンプリングレートに戻す処理をします。先ほどよりだいぶ良い感じですが2倍程度だとまだ上の方でノイズが目立ちます。また計算量も当然ナイーブな実装のn倍かかります。
takmizさんのWeb FM synthesizerはこの方式をとっているようです。
 
■加算合成

   var out = 0.0;
    var n;
    for (n = 1; ; n++) {
        if (this.frequency * n > this.samplerate / 2)
            break;
        var overtone = Math.sin(this.phase * n) / n;
        out += overtone;
        if (n >= this.highestharmonics)
            break;
    }
    return out;

高次倍音ナイキスト周波数を越えるとノイズになるのであれば、下から倍音を積み重ねていってナイキスト周波数に達したら積み重ねるのをやめればいいのでは、という考え方で倍音を加算合成する方法です。
確かにノイズは無くなりますが、1サンプルあたり何十回も三角関数を呼ぶなど計算量がとても多くなります。また20〜30回くらいで計算を打ち切ると低音の方で倍音が足りずに甘い音色になってしまいます。
Synth1のDaichiさんが公開しているVSTiシンセのサンプルソースはウェーブテーブル方式ですが、アプリ起動時にウェーブテーブルの波形データを加算合成で作っています。
 
■BLIT

    if (this.x >= 0.5) {
        this.x -= 1.0;
        this.p = this.samplerate / this.frequency;
        this.f = 1.0 / this.p;
        this.m = 2 * Math.floor(this.p / 2) + 1;
        this.sum = this.c3 = 0.0;
    }
    this.sum += this.m / this.p * Math.sin(this.m * this.x * Math.PI)
                / (this.m * Math.sin(this.x * Math.PI));
    this.x += this.f;
    this.c3 += this.f;
    return 2.0 * (this.sum - this.c3);

BLIT(Band Limited Impulse Train)は比較的新しいアルゴリズムです。g200kgさんのBLITのお話が詳しいです。
計算式よりもソースコードが好きなみなさんはTALさんのページの一番下を見ると良いと思います。
自分なりに解釈すると、これは「方眼紙に波形を書くとゆがんでしまうので逆向きにゆがませた方眼紙の上で波形を書く」ようなイメージと理解しています。方眼紙にあたるのが通常のImpulse Trainで、ゆがませた方眼紙がBand Limited Impulse Trainなのかと。
BLITは1サンプルにつき三角関数が2個なので加算合成などに比べれば軽いです。
ノイズが完全にはなくなっていないのは僕の実装が悪いせいかもしれません。BLITのJavaScriptでの実装例は、いまのところ他では見たことがありません。
 
オシレーターノード

    this.onode = this.ctx.createOscillator();
    this.onode.type = 2;
    this.onode.connect(this.ctx.destination);
    this.onode.start(0);

ここまで書いておいてなんですが、Web Audio APIではオシレーターの部品が最初からあるので、ノコギリ波などそこに用意されている波形は普通にオシレーターノードで実装するのが正しい方法です。JavaScriptで実装するより当然軽いしカスタム波形も使えるようです。
実際に聴いてみるとノイズがないのはもちろんですが、音程切り替え時に少しポルタメントがかかる特徴があるようです。
ただ、残念なことに2013年5月現在FirefoxではオシレーターノードがAPIに存在しません。(前述の試聴ページではFirefoxの場合エミュレーションで鳴らしているので本来のオシレーターノードの音ではありません)
 
あとはやっぱりウェーブテーブル方式が良さそうなので今後調べてみたいと思っています。補間方式などいろいろノウハウがありそうな気がします。

いろんなものがハフィントンポストっぽくなるウェブサービス作ったよ

ハフィントンポスト日本版がついにスタートしましたね。ネット上に良質な言論空間をつくることを期待されていてこれからが楽しみです。
 
ところでびっくりしたんですが、ハフィントンポストっててっきり悪意あるテレビ局が歯のない人にインタビューしてワシントンポストって言わせたりとか、そういう由来があるのかと思ってました。ツイッターなどでもちょっと話題になりましたが、どうやらワシントンポストも歯のない人も関係なくて創設者のアリアナ・ハフィントン氏の名前からつけられたようです。
 
そんなわけで、いろんな言葉をハフィントンっぽくするウェブサービスを作りました。
http://aikelab.net/huffingtonizer/
Huffingtonizer

 
独自のアルゴリズムで文字列を歯のない人っぽく変換します。漢字まじり文や英単語もそれなりに変換します。ただ、我々のアルゴリズムの未熟さにより実際にそうでもない風に見えてしまう部分はあると思います。


 
これを使って世の中をいっぱいハフィントンっぽくしてしまいまひょう!
 
aikeの日記はハフィントンポストを応援しています。

JavaScriptにsleepを実装しようとして気づいたら新言語を作ってた話

あのですね、JavaScriptにsleep()とかwait()みたいなのってほしいじゃないですか。で、調べてみると標準にはなくて作れるには作れるけどブラウザ依存だったりビジーループだったりJava Applet併用だったりしてがっかりするじゃないですか。
 
ぼくは1年半くらい前に「竹内関数で音楽生成」っていうエントリーを書いたんですが、当然これをJavaScriptで計算しながら音を鳴らすページを作りたくなりますよね。ですよね。こう見えても昔はN88-BASICでCMD PLAYとかばりばり使ってたくちなんで、そのくらい簡単だと思うじゃないですか。そしたらもう当時はAudio APIも出たばかりで情報もすくなくてブラウザ依存で、しかもJavaScriptでsleepできないしふんだりけったりで最初の一歩も踏み出せない状態。
 
そんなわけでなんとか手はないかとこの1年以上ずっと試行錯誤してきてようやく完成したと、まあそういうわけです。
 
http://aikelab.net/tarai/
Tarai Function Music

 
これは[Start/Pause]ボタンを押すと、竹内関数(たらいまわし関数)を再帰的にどんどん呼び出して、関数を呼び出すたびに1小節分の音を鳴らして、鳴り終わるまで待って、音が鳴りおわったら次の関数を再帰して、ということをくりかえしいく、そんなページ。ということはですよ、sleep処理が実現できてるんですよ、奥さん。しかもソースコード上はsetTimeout地獄とかになってないんですよ。
 
で、まあ、どうやったかというと、タイトルのとおりJavaScriptで「sleepできる別の言語」を作ったわけです。CoffeeScriptやJSXのようなJavaScriptに変換するやつじゃなくってJavaScriptで書かれたインタプリタです。
 
この言語、ぼくがいうのもなんですが小さいわりにちゃんとしてて、現在の実行アドレスを格納するProgram Counter(PC)レジスタ、クロックごとにPCレジスタの命令を実行するプロセッサ、メモリ領域のスタック、ローカル変数(v1〜v4)、引数(a1〜a3)付の関数定義、簡易的な四則演算、if文による分岐なんかを実装してたりします。
関数呼び出しのときは、退避すべき変数と呼び出し元アドレスと引数をスタックに積んで、returnするときはそれらを戻しつつ戻り値をスタックに積んで返します。こうすることで竹内関数のような深い再帰呼び出しも問題なく実行できます。

それで、実行するスクリプトはこんな感じ。playのところで音を鳴らしつつ一定時間スリープします。

var script = [
    '#----------------------',
    '# tarai function script',
    '#----------------------',
    'call tarai 10 5 0',
    'end',
    '',
    'def tarai',
    '   play a1 a2 a3',
    '   if a1 <= a2',
    '       return a2',
    '   v1 = a1 - 1',
    '   call tarai v1 a2 a3',
    '   v2 = ret',
    '   v1 = a2 - 1',
    '   call tarai v1 a3 a1',
    '   v3 = ret',
    '   v1 = a3 - 1',
    '   call tarai v1 a1 a2',
    '   v4 = ret',
    '   call tarai v2 v3 v4',
    '   return ret',
    'defend'
];

JavaScriptのライブラリとしてはちょっとつかいみちが思いつかない感じかもしれないけど、プログラミング言語実装の参考にどうぞ。

https://github.com/aike/tarai_language