January 2010 Archives

sf2xrniに手を付けてみる

| No Comments | No TrackBacks

先週ここに書いてから、諸般の事情で電子工作を優先してやらないといけないことになって、さらにwaveprotocolまで優先してやらないといけないことになって、こっちのプログラムがいきなり現実逃避に押しやられてしまったのだけど、昨日きっちり現実逃避できたので(?)、コンバータを作ろうと思って、少しコードを書いてみた

わずか50行ちょいのコードだけど、とりあえず、naudioもnrenoisetoolsも一度もいじったことがないので、使い方がよく分かっていない(たぶん知っている人は誰もいないだろうけど)ので、renoiseで読み込んでエラーにならないようなファイルを作るだけで、それなりに手間取ってしまった。で、ファイルが不正だと言われることはなくなったものの、読み込ませてみたら、最初の音しかきちんと鳴らない。どうやらまだいろいろおかしい。

そもそも、冷静に考えてみると、soundfontの中にはMIDI音色セットのようなパッケージになっているものがあり、それらは単純なrenoise Instrumentのようにひとつの音色をwave tableとキーでマッピングさせてハイ終わり、というものではなかった。単位が違う。sf2にはバンクがあって、それがrenoise Instrumentに相当するものではないかという気がしてきた。そんなわけで、根本から考え直さないといけないようだ。

マッピングが自明でない以上、sf2をサポートする方法もいくつかあるだろうから、renoise本体が未だに対応していないのも無理はない。ファイル構造の根本的な変更が必要になりそうだし。

renoiseあそび #2(?)

| No Comments | No TrackBacks

今週末は昨日書いたanowaveを公開するところまでもっていくつもりだったのだけど、昨日出来てしまったので、今日は思いのほか暇な時間が出来た。そんなわけで、折角ならと思ってrenoiseで遊んでみた。ちなみにrenoiseは面白そうだったのでもうライセンスを取得してしまった。

何か1曲でっちあげてみようと2時間ばかりいじってみたものの、ほとんど聴けた物ではないにもかかわらず既に演奏データが12MB近くにもなっていて、びっくりした。これだけファイルが大きくなるのは、音色データをそのまま取り込んでいるからだ。

一方で、音色はまだ豊富にあるとはとても言えない。使いたい音が入っていないという状況には以前と変わりがない。そんなわけで、打ち込むのにも早々に行き詰まり、大規模な音色バンクをもっているsoundfontから音色を引っこ抜いて、renoiseのxrni形式に出来ないかと考えてみた。同じようなことを考える人もそれなりにいるようで、おそらくrenoise本体がsf2をサポートすれば万事解決でもあるのだけど、とりあえずは出来ないようだ。

仕方がないので、可能なら自分で作ってしまえないかと思い、soundfontの解析が出来るライブラリは無いものかと探していたら、NAudioに行き当たった。そしてrenoiseに関しては既に知っていたものでNRenoiseToolsというライブラリがある。これらのソースを読みながら、creativeにあるsoundfont2の仕様書を眺めたりしている。soundfont2の仕様はそれなりに大きいが、サンプリングとキー別スロットとループの情報があれば、とりあえず再利用性は十分にあるのではないかと思っている。

最初は何となくrenoiseをいじってループで1曲くらいやっつけてしまおう、くらいのノリでいじり始めたのに、気がついたら全然違うことを始めていたという事実には気付かなかったことにする。

とりあえず今日はsf2ファイルを実際にNAudioで眺めてみようと思ったのだけど、sf2サポートのデモアプリのようなものが見あたらなかったので、デモアプリにちょこちょこと機能を追加して、sf2ファイルの内容をPropertyGridに表示するだけのサンプルを作ってパッチを投げた。

anogakki waveを公開

| No Comments | No TrackBacks

また妙に忙しく、しばらくコードをいじれなかったのだけど、この前原型を作ったあの楽器をいじって、それなりに本物っぽい図形を表示できるようになったので、ついでにいろいろ手を加えて公開することにした。ついでにsample galleryにも投稿してみた

改良したのは - 図形の回転表示とバリエーションの追加 - デフォルト音色を物理音源シミュレータのアコースティックギターに変更 - 音色のカスタマイズ対応 - あてぶりMML対応 - 非あてぶりモードにおける全音階と半音階の切り替え - ローカル実行モードとwave実行モードのjavascript共通化 などだろうか。地味にいろいろいじった。

本当に修正したい肝心の部分はSiONの呼び出し部分なのだけど、この部分はまだソースを追いかけていないので分かってない。Waveいじりで関心がある主な部分はwaveprotocolだし、wave gadgetにしようと思ったのはSiONをいじるきっかけにしたかったからでもある。今やってみたいのは、flash interopを使って、SiONで演奏中のデータをJavascript経由で動的に変更するようなことなのだけど、今回のはその習作みたいな感じだ。

Javascriptで命令を送るきっかけは何でも良い。今具体的に考えているのは、他のflashからのinteropなのだけど、たとえばfirefox 3.6で追加されたセンサーAPIなんかを使うこともできるだろう。この辺はいろいろ可能性がありそうな気がしている。

playing with fedone server

| No Comments | No TrackBacks

作りかけのあのがっきwidgetを改良するのが先という気もしなくもないのだけど、HTML Canvasをいじるのがメインの作業なのでいまいち気分が乗らず、どうせならやりたい所をつまみ食いしてしまおうと思い、waveプロトコルの実装を動かして遊んでみることにした。google自身がfedoneと呼ばれるリファレンス実装を提供しているので、動かすのは比較的簡単なはずなのだけど、XMPPサーバが必要になって、少しややこしい。

waveプロトコルではXEP-0060ことXMPP-PubSubが必要になる(XMPPはもともとjabber IMの標準化のためにあったようなものなのだけど、現在ではXMPP Coreに準拠するさまざまな仕様が作られていて、pubsubもそのひとつ)。なので、これを実装していないものを使うことはできない。最初、jabberd2で実験しようと思っていたのだけど、これにはpubsub実装が含まれていなかった。

仕方ないので、pubsubがありそうなXMPP実装を検索したら、openfireというものが見つかった。後になって気付いたが、waveのサイトにはopenfire, prosody, ejabberdといった実装を使って動かせるという説明があった。ejabberdを動かすには巨大なerlangをダウンロードしなければならなかったので、今回はopenfireを使うことにした(openfireはJavaで書かれている)。

最初、fedone-server-0.2.jar を直接起動しようとして、あれこれコマンドラインオプションを指定していって、それでも動かすことは出来たのだけど、先の説明のページに手順がひと通り書かれていて、その通りにやった方が簡単だった。ともあれ、これでサーバもクライアントも動かすことができた。

localhostでC/S接続が出来たら、次はやはりfederationに進みたかったわけだが、どうやらgooglewave.com はまだfederationに対応しておらず、wavesandbox.com のアカウントが無いとダメなようだ。wavesandbox.comのアカウントは持っていないので、ここでゲーム終了である。

実運用しているwaveとの間でfederationの実験が出来るようになったら、今度はjabber-netなどを使って、ありもののリファレンス実装ではない独自の実装を作って通信できるようにしてみたいと思っているのだけど(waveはgoogleだけのものではないはずだ)、それは着手するとしてももう少し先の話だろう。今でもfedoneを複数稼働すれば実験できそうな気もするけど、そこまで今急いでやることもないだろう。

まあ、fedoneを動かしただけでは、まだwaveプロトコルを体感できたとは言い難いのだけど、とりあえず動かすことは出来たので良しとしよう。

google waveであの楽器みたいなやつ

| No Comments | No TrackBacks

昨日というかもうほとんど一昨日のことだけど、google waveであの楽器みたいなgadgetを作ってみた。まだproof of conceptもいいところだけど。

あの楽器というのが実際にどういうものであるべきなのかは知らないが、タップしたら光ってランダムな図形を波状に表示して発音するもののようだ。とりあえずHTML Canvasの使い方を読んで、円と矩形を書くコードをjavascriptで書いてみて、ついでにjavascriptでアニメーションなんて初めてだったのでsetTimeoutの使い方まで読んで、それで実装してみた。ホンモノは三角形を出したり矩形も回転させたりするので、コレはいまいちな部類なのだけど、rotateで意外とハマったりしたので、まだやっていない。

これだけだとwaveの出番は全然無いので、同じwave gadgetを叩いたら、見ている人のところでも音が鳴るようにコールバックを設定してみた。最初無条件にコールバック経由の再生を処理していたら、自分が発音したときにもコールバックがかかってきて二度再生されていたので、実行ユーザでフィルタしてみたら、どう動作確認すればいいのか分からなくなってしまって、そのままにしてある。

音を出しているのはSiONというflashのシンセサイザエミュレータで、これは先日書いたflashとのinteropによって実現されている。これはSiON自体にそういうサンプルがあるのを流用しただけだ...結果的には。本当はnoteOn/noteOffのinteropを自分で定義して呼び出したかったのだけど、上手くいかず、そこに悩むのはwaveいじりとは関係ないと気付いたので今回は諦めた。

あの楽器自体はSiON interopのテスト的な感じでやってみたものなので、それ自体は目的とは言えない。が、proof of concept的なものが出来た今、作ろうと思っているのは別にある。

ピアノであれば連弾のようなことも出来るかもしれないが、演奏情報の通信の同期が期待できないので、その方向での応用は厳しいかもしれない。でもしばらく前に、上原ひろみがNYCと東京の間で連弾みたいなことをやっていた映像を見たことがあって、それくらいのことが現実に出来るようになる日も来るかもしれないとも思う。いずれにしろ今のwaveではそこまでの速度は出ない。

ActionScriptとHTML/Javascriptのinterop

| No Comments | No TrackBacks

気を取り直して、flashのActionScript (AS)と Javascript (JS)がどのようにやりとりするものなのかを調べてみた。調べたと言っても、既存のinteropコードを眺めただけだけど。基本的には以下の2つを使うことになる:

  • ExternalInterface.call()で、ASから呼び出すJSの関数の名前を指定する
  • ExternalInterface.addCallback()で、JSの関数の呼び出しに対応するASの関数を指定する

これらはいずれもAS側で行うことだ。(JSにはASを特別に扱う仕組みは無い)。コールバックで呼び出されるASの関数に対応するJSの関数の内容は空でよい(純粋仮想関数とかP/Invokeみたいな仕組みを連想すれば良いのではないだろうか)。

AS側は、後はflashをどういじるかの問題だ(実のところ今ここでハマっているのだけど、それはflashライブラリの使い方の問題だ)。ちなみにswfファイルを作ったことは今まで一度もないのだけど、wonderflでコードを編集するだけで自動的にswfまで作ってくれることに気付いたので、ここでビルドしている。

JS側は、いったんflashのobjectを生成してしまえば、後はcall()で指定した関数を定義して、必要に応じてaddCallback()で指定した関数を呼び出すだけだ。これはCanvasからのイベントコールバックでも、wave gadgetのイベントコールバックでもいいはずだ。といっても、どちらもこれから調べるのだけど。

時間ができたので、ひさしぶりにWebプログラミング的なことをやってみることにした。

というわけでprotocolにしか興味の無かったGoogle Waveを、今日はGadgetでいじってみることにした。といってもまだ実はgadgetらしいことは何もしていない。gadgetのXMLには、iframeの中に作られるHTMLの文字列をCDATAで指定するだけだ(とりあえず今のところは)。

そんなわけで、flashのオブジェクトを含むHTMLをそのまま記述して、xmlにしてweb上に配置し、それをwaveドキュメントの中に貼り付けてみたら、意外とあっさり動いた。どうやらjavascriptもswfもリモートにあるものをそのまま使えるようだ。(まあそれくらい出来ないとyoutubeの埋め込みプレイヤーなんかも実現できないわけだから当然か。)

さて今度はそのHTMLをいろいろローカルで編集することになるだろうと考えて、ローカルHTMLで開いてみた。ここら辺からがハマり道だった。まずflashオブジェクトが上手く動作してくれない。予想はしていたが、ローカルファイルとして実行できるとセキュリティ上の問題があるということだろう。とあたりを付けたら、それは確かに当たっていた。しかしadobeのサイトでグローバル設定でswfを安全なファイルとして指定しても、やっぱり実行してくれない。どうにも困ったので、諦めてローカルでHTTPサーバ(xsp)を動かして見ることにした。

で、今回はHTMLではなく画像をいじりたいと考えていたので、SVGをいじろうと思い至って、まず単なるcompound HTML (HTML+MathML+SVG) を作ってみることにした。これがまたハマり道で、web上にあるサンプルをいくらコピーしてローカルで表示しようとしても上手くいかない。1時間近く格闘して、どうやらmime typeがapplication/xhtml+xmlになっていないのが問題っぽいということに気がついた。ひとしきりmeta タグとhttp-equiv属性を試してから、もしやと思ってファイルの拡張子を.htmlから.xhtmlにしたら、それでSVGも表示されるようになった(!)。http-equivで指定しているcontent-typeよりそっちを優先するとは...。そしてcontent-typeがapplication/xhtml+xmlを指定していると、HTTPサーバがapplication/octet-streamのように生データで返すようになるので、text/htmlにしてすることに...

ともあれ、SVGも表示できるようになったので、これを先のgadget xmlに埋め込んで表示させてみようとしたのだが、やはりこれはうまくいかない。waveのページのcontent-typeはいじりようがなく、iframeの中のhead要素の内容もgadget xmlから変更することは出来そうにない(出来るのかもしれないがそこまで深入りしていない)。

どうしたものかと思って、ふと、世の中には似たようなことを考えてやっている人がいるのではないかと思って、探してみたら、案の定あった。そこでソースを眺めて見たのだが、どうやらこれは先のようにcompound XHTMLにするのではなく、svgcanvas.svgという外部SVGをobject/embedタグで「画像として」呼び出していた。画像として、とは言っても、その中ではjavascriptが呼び出されていて、動的な変更が実装されている。なるほどこれでSVG要素の埋め込みを実現しているというわけだ。なかなかややこしいものだ。

...ここまで調べたところで、そもそも、SVG Canvasを使うくらいなら、HTML5 Canvasを使えばいいのではないかということに気がついた。気がついて、愕然としている...そうだった。SVGには愛着があるので、自然とSVGを使うつもりになっていたが、よく考えたらHTML Canvasで十分できるようなことしか考えていないのだった...

次は気を取り直してHTML Canvasとflashと肝心のgadget APIをいじってみようかと思う。

twitterのstreaming API

| No Comments | No TrackBacks

新年になったので、少しずつここの内容も色を変えていくこともあるかもしれない。今日はのんびりとtwitter streaming APIを眺めていた。

streaming APIは、特定のクエリに対する更新情報を随時流しっぱなしにする、いわゆるpush配信の技術で、ユーザはHTTPリクエストを送って、随時流れてくるレスポンスを受信しつづけるだけだ。cometと同じようなもので、一定期間に返すものがなければ、クライアント側に空っぽの内容を返し、接続を維持する。ある種のHTTPクライアントは、サーバとのTCP接続を切断した後にユーザにレスポンス内容を返したりするので、この用途に使えなかったりする(と書いてある)のだけど、変に内部キャッシュに貯め込まない実装なら問題無く使えるだろう。

似たような技術ではpubsubhubbubというものがあって(これはもともとiGoogleガジェットでも使われているpubsubというXMPPのひとつの応用を、さらにHTTPにもってきたようなアプリケーションプロトコル)、データソースが全てtwitterであることや、細かいクエリパラメータを渡してフィルタリングできたりJSONで返せたりすること以外は、概ねstreaming APIとやっていることは変わらないだろう。

streaming APIでは、何でもほしいものをストリーミングで拾ってこられるわけではない。アカウントに紐付けられたアクセスレベルによって、実現可能なクエリは変わってくるようだ。APIドキュメントでは、filter, firehose, retweet, sample というクエリが説明されている。twythonのstreaming.pyには、APIドキュメントでも言及だけされているshadowやらbirddogやらが含まれている(URIの形式が違うようなので、これが動作するものなのかどうかは分からない)。firehoseを使えば、public_timelineのようなものが取得できるようだけど、標準のアクセスレベルでは取得できないようだ。sampleは、その一部をランダムに取り出しているようで、通常のユーザなら誰でもアクセスできるようだ(一般に開放しても困らない程度の量になっているということだろう)。

有償契約によって付与されるであろうアクセスレベルによって高度なクエリを可能にするというのは、収益を上げるためのひとつの上手い方法に見える。

streaming APIの恩恵をもっとも受けやすいのは、おそらくTweetBubblesのようにsearch APIを使って定期的にハッシュタグなどを探すタイプのアプリケーションだろう。もっとも、pull型で実装されたコードベースがある場合、基本的にbest effort型で不安定なpush型ベースに書き換えるのは面倒かもしれない。あとは、TwitterIrcGatewayみたいなものは、よりリアルタイムに近づけることもできるだろう。リアルタイム性が多かれ少なかれ求められるアプリケーションでなければ、無理に対応するものではないと思うけど(コードのあり方がだいぶ変わるはず)、楽しい使い方があるものかもしれない。

About this Archive

This page is an archive of entries from January 2010 listed from newest to oldest.

December 2009 is the previous archive.

February 2010 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Categories

Pages

OpenID accepted here Learn more about OpenID
Powered by Movable Type 4.23-en