gjsでGIRepositoryを操作する

| No Comments | No TrackBacks

先日のエントリからの調べ物として、まずgjsでgobject-introspectionを使用する方法を残しておく。gjsはgobject-introspectionで実現していて、gobject-introspectionはそれ自身がgobject-introspectionをサポートしているので、gjsを使えば簡単なメタプログラミングが実現できるというわけだ。

ローカルでgobject-introspectionをサポートするAPIにどのようなものがあるかは、インストール先のgir-1.0フォルダを探して見てみると良い。典型的なLinux distroの場合は /usr/share/gir-1.0 などにあるだろう。

gjsのgirバインディングは素直だ。使いたいモジュールは imports.gi.XXX でアクセスできる。

var GIR = imports.gi.GIRepository;

GIRネームスペースには、(ドキュメントを読んでもらえればわかるが)GIRepositoryというクラスが存在する。gjsからアクセスする場合は、共通の型名プレフィックスである GI を除いた Repository がクラス名となる(共通のプレフィックスが何になるかは、*.girファイルに記述してあるので、gjsは機械的に名前を計算できる)。

girベースのAPIには、classが定義されており、その中にはinstanceメンバーとstaticメンバーが存在する。instanceメンバーの場合、*.girファイルには関数の定義部分に instance-parameter というXML elementが存在している。それ以外はstaticメンバーとなる。

staticメンバーにアクセスする場合は、クラスをあらわすオブジェクトのメンバーとして呼びだせば良い。Repositoryには、 girepositoryget_default() という、デフォルトのRepositoryを返す関数がある。girのclassにはsymbol-prefixというものが定義されており、これは関数名の解決で使用される。同様に、GIRのネームスペースには、ネームスペースのプレフィックスも規定されている。GIRepositoryネームスペースのプレフィックスは "g" で、Repositoryクラスのプレフィックスは "irepository" だ。

ここから、girepositorygetdefault()という関数は、GIRepositoryネームスペースのRepositoryクラスのgetdefault()というメソッドとして、定義されることになる。たとえば、get_default()の呼び出しはこうなる:

var GIR = imports.gi.GIRepository;
var repo = GIR.Repository.get_default();

これでrepo変数にRepository型のオブジェクトが格納されたことになる。

gjs> repo
[object instance proxy GIName:GIRepository.Repository jsobj@0x7f8cbe1357f0 native@0x21d6420]

インスタンスメソッドのマッピングも簡単だ。名前の解決はstatic関数と同様に行われる。引数については、前述の通り、インスタンスメソッドの定義には instance-parameter というXML elementが含まれている。この引数は、gjsのAPIではthisの扱いになり、引数とはならない。

girepositorygetloadednamespaces()関数を呼び出してみよう。この関数もRepositoryクラス内で定義されている。唯一のパラメーターが instance-parameter なので、gjsでインスタンスメソッドとなった時には、引数は存在しない。

gjs> repo.get_loaded_namespaces()
GLib,GObject,GIRepository

girepositorygetninfos() は、2つ引数をとり、最初はインスタンス パラメーターであり、最後はネームスペース名となる。戻り値には、そのネームスペースに含まれる「定義」の数を返す。

gjs> repo.get_n_infos("GIRepository");
152

それぞれの要素は girepositoryget_info() で取得できる。

gjs> var info = repo.get_info("GIRepository",0);
gjs> info
[boxed instance proxy GIName:GIRepository.BaseInfo jsobj@0x7f05f0735a60 native@0x715320]

gjsを使ったGIRepositoryの基本的な操作は、概ねこの辺りが分かれば出来そうだ。

途方もない空白期間の後にしれっと書いているけど、ここはもともとメモ置き場だし、まとまった内容はだいたい他の場所に書いているので問題ない。ここに書いているのは、要するにまとまっていないアイディアである。

そんなわけで今日はTypeScriptをGNOME開発で使うにはどうするのがいいか、について考えてみる。

現在のGNOME開発のトレンドは、主にJavaScriptを使うということになっているようだけど、実態はC + 任意の言語 ということらしい。その心は、Cおよび好きな言語でアプリを書けるようにしておけ、ということだそうだ。Cをサポートするのは、GNOMEの基本的な方針ということなのだろう。

古いGNOMEのモデルだと、任意の言語、の部分は、それぞれの言語のバインディングが担うことになるわけだけど、2010年代のわれわれはそれが各言語バインディングごとに追いついたり追いつかなかったりで、理想的には機能しない、ということを知っている。

その問題を解決するために、GNOMEにはgobject-introspectionというAPI公開仕様が導入された。gobject-introspectionをサポートしている言語ランタイムでは、使いたいGNOMEのライブラリがgobject-introspectionに準拠していれば、特別にその言語バインディングを作成する必要はない。

さて、現在のGNOME 3.xでは、JavaScriptが標準としてプッシュされている。gnome-shellなどはJavaScriptで拡張を書くことが出来る。GNOMEのJavaScript実行環境には、spidermonkeyベースのgjsとwebkitベースのseedという実装が存在していて、どちらもgobject-introspectionに準拠している。これらのJSランタイム実装は、gobeject-introspectionを活用して、API情報をクエリして、JSオブジェクトに対するメソッド呼び出しを適宜解決して、そのgobjectに対するネイティブ呼び出しを実現する、というわけだ。これは少なくとも使い方としてはORBitだのBonoboだのと言っていた時代よりははるかに簡単だ。

さて、gjs(seedがBlinkで使えるかどうかは知らないが、Apple専用となったWebKitを使う気は全く無いので、以降gjsについてのみ扱う)でgobject-introspectionのgirを経由してAPIを「使える」ことは分かった。一方で、プログラムの開発時には、JavaScriptでは型情報が無いので、静的型付け言語を使うことで、コード補完などを実現できるようにしたい。

というわけで、TypeScriptを使いたい。TypeScriptは、JavaScriptにコーディング時の型情報を提供するものだ。TypeScriptはどうやって型情報を取得しているかというと、バージョン1.5の現在では、主に型情報を定義したTypeScript (d.ts)を参照して、型情報を構築している。AMD (asynchronous module definition)を利用することも可能だ。

(実行時には型情報は無いわけだが、gobject-introspectionのAPIで何とかなるのではないかとは思う。gjsが実現しているからといって、その仕組みが開発時に、すなわちTypeScriptで、そのまま使いまわせるわけではない。)

というわけで、現在の仕様に準拠するかたちで、GNOME開発でTypeScriptを使いたい場合は、このd.tsファイルをgirファイルから構築してしまえば良いわけだ。

しかし、これはあまり理想的ではない。これでは、girが変換されてd.tsが提供されたAPI以外については、「バインディングが提供されていないAPIはサポートされない」状況に近い。現実的な問題としては、DefinitelyTypedに誰かが登録したd.tsに対応するgirは、d.tsの利用者(プログラムの開発者)の手元にある各ライブラリと、バージョンが合わないかもしれない。出来ることなら、誰かがわざわざAPIを変換しなくても、girのリポジトリを、直接、型情報リポジトリとして使えるようにしたい。

これを実現するためには、typescriptコンパイラそのもの(tscおよびそのLanguageService)に手を入れなければならないだろう。しかし、typescriptそのものにプラットフォーム固有のgobject-introspectionのサポートを組み込むというのは、やはり抵抗感がある。tscはValaのようなGNOME-centric languageではない。

おそらく、ここで最も望ましいアプローチは、F#のType Providerのような仕組みなのではないか。TypeScriptの場合、実行時には型情報は存在しない。コンパイル時に型情報を解決出来れば良い。F#ではopenキーワードを拡張することで、Type Providerの仕組みを実現した。同様のことが、TypeScriptでも実現できるのではないか。

実のところ、JavaScriptライブラリにAPI情報を提供する仕組みは、他の実行環境等にも存在していて、「型情報をxxxから取得できるようにしろ」という要求にはissuesやpull requestsの前例がある。

  • JSDocからのAPI情報取得 https://github.com/Microsoft/TypeScript/pull/2646
  • node.jsのnode_modulesからの情報取得 https://github.com/Microsoft/TypeScript/issues/247

AMDサポートも、この(既に実現している)一種と言える。

また、QMetaObjectのようなものを(gobject-introspectionとsmokeを経由せずに)サポートしようと思ったら、やはり独自のtype providerがあれば実現できる。

これらのような例を考えるに、おそらくそれぞれを個別にサポートするよりは、何らかのかたちで標準化されたtype providerをサポートするようにした方が望ましいのではないか。

node_modulesサポートのissueは、TypeScript 2.0というカテゴリでまとめられているので、この辺りの議論は、もしかしたら早めに出したほうが良いのかもしれない。個人的にTypeScriptにもGNOME開発にも全力でコミットするつもりがないので、tscパッチなど何かしらの具体的な実装を伴わないアイディアで終わってしまっているのが残念なところではある。気が向いたら実装に着手するかもしれない。

portable MIDIライブラリの再検討

| No Comments | No TrackBacks

また半年くらい書いていなかったわけだけど、今回はパブリックにコードを書いていたわけではなくて単に多忙な時期の後に語学の勉強をしていた。それはさておき、ひさしぶりに自分の書いたMIDIユーティリティで遊ぼうと思って、手元にある新しいマシンでも使えるようにとportmidiをビルドしようとしたのだけど、全く上手く行かない。原因はわかるのだけど、そもそもportmidiはビルドが不親切すぎて、とても多用されている気がしない。

そんなわけで、この際、他にライブラリもあるだろうと思って探してみた。とりあえずぱっと見あまり悪い印象がなかったのがRtMidiだ。MITライセンスだし、iOSまで対応している(AndroidにはまともなMIDIサポートは無いので対応も無い)。これを使ってみることにした。

とりあえずコードがAPIのレベルでC++なので、これをCで呼び出せる形に変換しないとP/Invokeなどが出来ない。というわけでまずはCのラッパーを書くところからスタートだ。Cのヘッダーは、APIドキュメントをもとに適当に作った。public APIのレベルでstd::vectorやstd::stringが出てくるので、この辺はchar*に全て置き換えだ(stringといってもMIDIデバイス名くらいで、ASCIIで考えてもほぼ問題ないはず)。

実装側はC++で書くことになる(呼び出すライブラリがC++だし)。面倒なのはコールバック関数にこれらが使われている場合で、いったん登録時にRtMidiが要求する形式に合ったC++ベースの関数を定義して、さらにCのコールバック関数とCのコールバック登録時ユーザーデータの2つをメンバーとする別のユーザーデータクラスを作って、RtMidi本体にはそれらを登録する。コールバック関数が呼び出されると、C++ベースの関数の実装は、ユーザーデータとして渡された先のユーザーデータクラスのオブジェクトから、Cのコールバック関数とCのコールバックユーザーデータを取得して、それらを呼び出す...という手順が必要になる。

そんなわけで実装まで書いてみたけど、実際に試す前に力尽きたので続きはまた今度。

ひさしぶりにNDKいじり

| No Comments | No TrackBacks

そもそもここに書くのが1年ぶりくらいのようだけど、コードを書くことが少なくなったというより、パブリックに書いたコードを直接出すことが多かったのだろうと思っている。そんなわけで今回は裏の...というわけではないけど、こっちで書いていたことの焼き直しのようなネタを書く。

そんなわけでひさしぶりにAndroid NDKだ。

直近でいじったのをみると、NDK r6がどうのと書いているようだ。現在はr8dまで出ている。Androidの状況もだいぶ変わった。armeabiの他に名ばかりのx86サポートがあった時代ではなくなり、エミュレーターなどで本格的にx86が使われるようになり、mipsもサポートされるようになった。NDK r8cからはツールチェインのパスも統一的になって、より簡単にスタンドアロンで利用できるようになった。ツールチェインのセットも、gcc(4.4.3/4.6/4.7)のほかにclangまで使えるようになった。NDK以外にも目を向けると、AOSPにはgold linkerやmclinkerといったllvmベースのリンカーまで含まれている。

以前にビルドしてみたlibiconvは、次のように configure - make - ld で簡単にビルドできるようになった(ついでにstdlibまわりのiconv特有の問題も解決してある):

export ANDROID_ROOT=~/android-ndk-r8d
export BUILD_OS=linux-x86
export ANDROID_VER=14 # 3 4 5 8 9 14
export ARCH=x86 # arm-linux-androideabi or mipsel-linux or x86
export ARCH2=i686 # arm or mipsel or i686
export TOOLFAMILY=4.7 # 4.4.3 or 4.6 or 4.7 or clang-3.1
export SYSROOT=$ANDROID_ROOT/platforms/android-$ANDROID_VER/arch-$ARCH
export CC="$ANDROID_ROOT/toolchains/$ARCH-$TOOLFAMILY/prebuilt/$BUILD_OS/bin/$ARCH2-linux-android-gcc --sysroot=$SYSROOT"
export TARGET_LIBRARY=libiconv

gl_cv_header_working_stdint_h=yes ./configure --host=x86 CPPFLAGS="-fpic -O3" CFLAGS="-fpic -O3"

make

$CC -nostdlib -shared -s -o $TARGET_LIBRARY.so -Wl,-whole-archive ./lib/.libs/$TARGET_LIBRARY.a

この例ではまだbuild-standalone-toolchain.sh を使用していないが、あれを利用すればRTTIなども使えるようになるはずだ。

ツールチェインが新しくなるのであれば、以前に作成したビルド支援ツールもかたちを変えないといけない。実のところ、以前のツールではメンテナンスが面倒になるし、NDKを利用したビルドは実際には成功するまで何度も試行することになったのにも関わらず、既に完成品のパッケージがあることを前提としすぎるきらいがあった。ビルドできるtar.gzが豊富にあるつもりだったので、むしろ依存関係の解決などに意識が向いていたけど、実際にはビルドスクリプトを試行錯誤することになった。そのような経験をふまえて、今回はローカルビルドを中心にできるようにしたい。ビルドできるモジュールの記述は、ビルドツールの一部として含めることができるだろう。

今考えているのは、大まかなディレクトリ構成だ:

  • ビルドは「生け垣」単位で管理される。
  • 1つの生け垣には、プラットフォーム別のブランチが含まれる(ここはarmeabiしか念頭になかった以前のツールとは異なる)
  • それぞれのブランチでは、SYSROOTのようにbinやらincludeやらlibやらをもつ。依存関係のインクルードなどは、それらを利用して解決する。

ビルドされたバイナリは、別途どこかで公開しても良いだろうし、無くてもビルドスクリプトさえあれば困らないだろう。

以前の経験から、主な成果が、ビルドツールではなく、個別のプロジェクトのビルドセットアップ・スクリプトにあることが分かったので、今回はそっちを貯めこむかたちで実現できればと思う。

6502 CPUの実装

| No Comments | No TrackBacks

最近までいろいろ調べたりしていたことを全く書いていなかったので備忘録代わりに。

NESというものがある。nintendo entertainment system、ファミコンで使われているOSのことだ。最近であればたいていの環境向けに存在しているFCエミュレータの類は、このNESというものを実装していることになる。FCはハードウェアとしては6502というCPUに独自の音源(audio processing unit, APU)を搭載した2A03というチップを使用している。

ファミコンはゲーム機なので当然ながらROMはゲームのものが多いが、音楽データとしてはNSFという形式のデータが出回っていて、この実体は2A03に対する機械語命令であり、ゲームのROMと何ら変わらない。NSFのプレイヤーは、NESのエミュレータを搭載している(はずだ)。

NSFを演奏できるようになるためには、6502の仮想ハードウェアを作って、そのI/Oポート(実際にはメモリアドレスに対する読み書き)に対応するAPUの仮想ハードウェアを作って、さらにAPUのレジスタ値から音声を合成するシンセサイザを作って、その上でCPU上にNSFをプログラムとしてロードし実行し、かつAPUのシンセサイザも制御しながら、処理系ネイティブで音声を再生するプレイヤーが必要になる。

FC音源の音は率直に言えばゴミなので、そこまでやる意味は自分を含む一般人にはほとんど無い。ノスタルジーで生きていたり、機構に関心があれば、眺める価値があるかもしれない。

さて、今回は無駄にその一部をC#で実装することになってしまったので、そこだけ何とかしようと思っている。実のところゲーム類を実行する気はさらさらないので、音楽ファイルを処理するためにAPUの一部も必要だろうとは思っている。完成させるところまではしない予定だけど。

CPUを実装するためには、計算機工学の基礎的な理解があると有用だろう。CASL/Cometがわかれば十分だと思う。6502のCPU命令に相当するロジックを書けば良い、ということになる。実のところ、6502 CPUの実装は様々な言語で存在しているので、それらを引っ張ってくれば通常は十分だ。

CPUが出来たら、APUを作って繋ぎ込む必要がある。APUへはメモリアドレス4000h-4017hでCPUからアクセスできる。APUのレジスタ側の論理構造を用意するのは簡単だ。一方、APUは実機では独自にループを回して発振器から音声を出力しているので、エミュレータでもこれを実現してやる必要がある。これをやるためには基礎的な音声合成の知識が必要だ。実のところまだ無いので、ある程度分かってきたら書こうと思う。

さて、6502の実装は大抵のプラットフォームではあると書いたけど、MIT/X11レベルで自由に使えるエミュレータは見つからなかった。そこで今回は既存の他言語の実装を探してきて、それをC#に移植することにした。

今回最終的に決めたターゲットはlib6502というCの実装だ。これがどこまでFCに忠実なのかは分からないが、コードは綺麗に1000行ちょっとでまとめられている。中身はマクロの嵐だが、これはコードを最適化してメインループから関数呼び出しを排斥してIRQ/BRK以外でのレジスタコピーを抑えたからだ、と思われる。アカデミックなコードとしての完成度は高そうだ。いずれにせよ、これを1日かけて移植した(選ぶのには時間をかけたけど、着手したら1日でできるレベルだった)。

全くといって良いほど動作を確認していないので、実際に動かし始めたらバグフィクスをはじめることになるのだろうけど、CPUはこれで出来たことにしたので、次は他の部分の話を書こうと思う。

resumed ActionScript porting

| No Comments | No TrackBacks

今週は、FM音源まわりで音楽ソフトを作っているから興味ある人を募集するという人がいて、話を聞いてみたら、動いているコードが無いどころか、これからやるはずの設計も実装もMMLコンパイラ以外は他人に丸投げ、つまり音源ドライバよろしく、みたいな、普通だったら呆れて帰るような話を振られて、とりあえず何かコードを書いてみて出来るか出来ないか考えてみよう、と思いながら、何かしら調べておくという話をしてきた。

とはいえ今さらそういうソフトをゼロから書く気はさらさら起きないので、以前途中までやっていたActionScriptベースのコードを使い回すことにした。今回はプラットフォームとしてC#を使う具体的な理由が出来てしまったし、再始動するにはちょうど良いだろう。

もっともASから移植したコードには既にかなり手を入れていて、コンパイルも通っているため、いまさら自動生成部分を改良するのは厳しい。自動生成コードにはいずれにせよ大規模に手を加えることはないだろうし、後からコードトランスレーターを改良することも出来るだろうとは思っている。

というわけで、既にコンパイルが通るようなコードを、実際に動かすためには、FlashのAPIを実装しなければならない。コード上で明示的に参照されていたFlashのAPIはそれほど多くないのだけど、暗黙的に利用されているFlashの仕組みは未知数だ。あまり多いとは考えていないけど。

今のところ自動生成コードで大きく足りていなかったのは、Eventまわりのコードだ。ASでは、各クラスについて、利用出来るコンポーネントイベントの種類を登録することになっているのだけど、宣言の中に引数型も含まれているので、C#ならイベントを生成するようにしておけば良かったと思っている。まあ実際に使用されている数は多くないので、手作業で追加することは十分できる。

実際にコードを動かしてみてハマったASの特性は、Arrayの動作だ。ASのArrayは後から要素を追加出来るので、C#の配列にはせず、Listなどにする必要がある。配列なので、サイズ指定で初期化するコードについては、要素の確保が必要になるのだけど、変数の型を解決しないとサイズなのかどうか分からないものなどがあって、これは相当するコードについてのみ手作業でアロケーションに置き換えている。自動化するにはちゃんとした型解決が必要だろう。

この辺までたどり着くまででもある程度時間がかかったので、とりあえずここまで。

gestureを記述する

| No Comments | No TrackBacks

冬休みからしばらくの間、イベント処理を簡単に実現するためのフレームワークとしてRxを実装していたのだけど、先週でひと区切りつけられたので、今週はRx自体の実装から離れて、入力イベントを簡単に記述できる手段を実現できないものかと模索していた。とりあえず「複雑なイベント処理を簡単に実装できるようにする」例として、タッチイベントによるジェスチャーの実装が思い浮かんだ。

Androidでは、タッチイベントはMotionEventとしてGestureViewOverlayを経由して受け取ることができる。これにはdown, move, up, あとcancelというイベントが渡ってくる(触ってすぐ戻るとキャンセルになるようだ)。これを組み合わせることで、複雑なイベントを実現できるはずだ。たとえばholdなら、downの後しばらくupが無ければトリガーしても良さそうだ。

こういう一連のイベントの流れを、よりわかりやすい形で記述できないものか。そう思いながら、何となく独自の記法で、今すでにあるようなイベントの仕組みを推測しながら、書いてみた

この種の記法で、イベント自体が記述できればもちろんそれも良いし、実際にコードまで落とし込めなくても、設計を考えるときの足しになれば、有用なんじゃないかと思う。

実のところ、Androidにはandroid.gestureというパッケージが提供されていて、Gestureクラスには連続的なtimestamp付きの座標リストが渡されてくるので、そこまで面倒を自分で見る必要は無い。自分でやるとしたら、認識方法を自分の好みにカスタマイズしたい場合くらいだろう。さらに、GestureDetectorというクラスも用意されていて、一定のパターンの入力イベントを認識して特別なイベントを発行するようになっているようだ。2本指でzoomする場合にはScaleGestureDetectorが使える、といった具合だ。もっとも、OnGesturePerformedListenerがどういうタイミングでイベントを送ってくるかは、実験してみないと分からない。downの後upが来る前に送られてくるとしたら、イベント処理に重複が発生しそうだし(パフォーマンスも悪そうだ)、upがあって初めてイベントが送られてくるとしたら、ホールド状態の時にイベントを発生させたり次のイベントの条件に繋げたい場合などに使えない。

...といったわけで、自分でGestureDetectorに相当するものを作るのもそれなりに有用ではないかと考えている。

もう一つ、この週末に引っかかっていたのは、ジェスチャーライブラリの類はプラットフォーム非依存に出来るのではないかということだ。どのプラットフォームでも、タッチ入力にはdown, move, upくらいはあるだろうし、そこでマルチタッチも扱えているのではないかと思う。それらを共通化してしまえば、後はプラットフォーム独立のやり方でgesture detectorを実現できるのではないかと思う。

android.gestureがandroid.viewから独立しているのも、ある程度プラットフォーム中立の仕組みになっていることを開発者も認識しているから、ではないかという気がしている。

実のところ、そのような発想に近い形でプラットフォーム中立の入力インターフェースロジックを実現しているものがある。TUIOというプロジェクトで、reactableなどを実現している。メディアアートの系譜で使われているようだ。ただし、これはイベントの入力装置 (tracker) とイベントの処理装置 (client) が別々になっていることを前提とするモデルで、その間はOSCを経由している。UDPだからTCPよりはましだけど、ローカルのイベント処理にそこまで抽象化してリソースを浪費するのはちょっともったいないと思う。

といった感じで、いろいろ考えることはあったけど、ひさびさに実装には全く至らない週末だった。この辺は時間がとれたら面白いことが出来そうだけど、そこまで余裕が出来るかは分からない。

tsukimi on android

| No Comments | No TrackBacks

昨日、processingの最新版はAndroidでも動作するらしい、という記事を見かけたので、自分にはtsukimiという自分の実装があるんだからそれを使ってC#で動かせるはずだし難しくないはずだと思い立って、挑戦してみることにした。

ただ、実際に移植してみると、tsukimiはSilverlight 2.0の頃に作られたものなので、いろいろと古いし制約が大きい。WritableBitmapは存在していなかったし、Linqのexpression treeもかろうじて存在していただけで、また詳しくもなかったので、コード生成は別途行っていた。

まず、tsukimiのWPF/Eベースの描画バックエンドを、SurfaceViewに移植するところから始めることになった。SurfaceViewは2年ほど前にちょっといじった程度で、もう覚えていない。適当にAPIを眺めながら実装した。

そしてアプリケーションのスタートアップの仕組みが、Silverlightとは異なるので、その辺りを試行錯誤しながら実装した。ここが一番ハマったと思う。結局今はSurfaceViewの派生クラスもActivityの派生クラスも作成して、その上にユーザーコードを派生させるという仕組みになっているのだけど、そうでない状態で動かなかったからそうしているだけで、改善の余地は大きい。

誰でも使える実装ができたわけではないけど、とりあえず1つだけサンプルが動いて、仕組みとして動くらしいことは分かったので、後は他のタスクを優先して、気が向いた時に改善しようと思う。

vocaloid-connector ... is suspended

| No Comments | No TrackBacks

Vocaloid3には新しくJob Pluginという機能が追加されていて、これはLuaで書かれたスクリプトを実行できるようになっている。これが出来ることが非常に限られていて、実のところ全く使い物にならないエディタ上の編集作業を補助する程度の存在なのだけど、Vocaloid3はVocaloid2に比べて実用性が大きく後退していて、ReWireやRealtime VST pluginが消滅してしまっている。まともな編集作業はこのJob pluginを経由してしか行えないと考えた方が良いようだ。

それならば、いっそ外部からJob plugin APIを汎用的に操作できるようなライブラリをC#で作って、LuaSocketと通信して命令を送り込むようにしたら良いのではないか、と思って、1日ちょいでやっつけでC#のインターフェースとソケットベースの実装を作ってみた

先にクライアントのコードをでっちあげてから、ホスト側のluaコードを書こうという段になってPCを修理に出さなければならなくなってしまって、様々な不幸が重なって結局戻ってきたのが1ヶ月も後になってしまって、その間すっかり更新が止まってしまったのだけど、今日になってようやく作業を再開してホスト側に手を付けてみた。

それで初めて気がついたのだけど、どうもluasocketをうまくrequire()で呼び出すことができない。Luaスクリプトを組むのは初めてなので、使い方が分かっていない可能性も大いにあるのだけど、ホスト側がvocaloid editorなので、外部モジュールを読み込めるようになっていないのかもしれない(そういう高度な例を示すスクリプトの例は何一つ見つからなかった)。

そんなわけで、とりあえずこのLua環境でluasocketが使えるようになるまで、この方面の作業は中断ということにしておこうと思う。

Android NDK r6 changes...

| No Comments | No TrackBacks

前回書いてから休暇のような職探しのような旅に出ていて、ほとんど自由にコードをいじることができなかったのだけど、仕事もほぼ決まって少し落ち着いた。

というわけでその間にAndroid NDK r6が公開され、SDK 3.2も公開された。後者はほぼ無関係なので放置しておくとして、NDK r6の変更が割と大きく、まだビルドサーバーがきちんと動作するように更新出来ていない。breaking changeとしては、これまで armeabi だったABIの識別子が、arm-linux-androideabi のようになったことがある。これによって、使用しているgccが外部の(バージョンが異なる)ものだったりすると、この識別子を受け入れてもらえない。

とりあえず、standalone toolchainを作って、これまでと違うtoolingでビルドしようとしているのだけど、まだ様々なエラーにはまって先に進めていない。じっくり調べる時間がほしいところだけど、他に関わっているプロジェクトもあるので先はまだ見えない感じだ。