wasavi を実行中、音を出す場合がある。つまりビービー鳴らすモードを持つ vi と同様、必要なときにエラーベルを出す。もし「この音うるせーよ!!」と思われる場合は、ワークアラウンドとして [cci]:set bellvolume=0[/cci] とすれば、とりあえずミュート状態にはなる(例えばこの方がやっている方法だ)。将来的にはビジュアルベルに切り替わったりする気遣いをするかもしれない。
さてこの時に出す音は Audio 要素を使っていて、フロントエンド側で鳴らしている。音源は wasavi 起動時にバックエンドから送られてくる ogg または mp3 データである。
しかし、これは割と無駄なのではないか。複数のタブで wasavi を動かしているとして、各タブがもともと同じデータである音源のコピーを個別に抱えている状態だ。現状は 1 秒未満しか発音しないビープ音なのでデータ自体は数 KB だ。したがってものすごく容量を食っているというわけではないが、やっぱり無駄だ。
これを、Audio 要素をバックエンドで保持するようにして、フロントエンドで音が必要になったら発音リクエストを投げるだけにすれば、そういう無駄は解消できる。ということでやってみて、Opera と Chrome では思ったとおりになったのだけど、Firefox が問題だ。Firefox の Add on SDK 上のバックエンドは、Window ではない不可思議なサンドボックスオブジェクトがグローバルになっていて、つまり Audio 要素をバックエンド側で使えないのだった。
こういう場合、たいてい [cci]Cc[/cci] や [cci]Ci[/cci] といった Firefox 特有の黒魔術をごにょごにょして何とかなったりするものなのだが(Kosian では XHR や Blob や FormData についてごにょごにょしている)、黒魔術はしょせん黒魔術であり、あんまり使いたくない。なにしろ、AMO にアップする際の機械的チェックにすら「おい黒魔術使ってんぞ、気をつけろよな!」などと言われる始末である。禁止されているわけではなく、「気をつけろ」なのがミソではあるのだが。
さて、サウンドプレイヤについてもこの黒魔術を通して Audio 要素っぽいものを得ることはできるようなのだけど
var {Cc, Ci} = require("chrome");
var sound = Cc["@mozilla.org/sound;1"].createInstance(Ci.nsISound);
var uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI(self.data.url(...), null, null);
sound.play(uri);
これで得られる nsISound は Audio 要素とは全然異なるものであって、たとえばボリュームの指定とかはできないようなのである。