2007年9月15日土曜日

PythonでMIDI

当初PyPortMIDIで MIDIコントロールをしようとするも、インストールはできたがインポートでエラーが発生。続いてPyMIDIを試すもモジュールがエラーを発生。しかたがないのでPyObjCでCoreMIDIを使おうと思ったらCoreMIDIはObjective-Cじゃねーじゃねーか。な のでPyObjCから直接アクセスできない。そこでPyMIDIとなぜかおなじ名前でPYMIDIフレームワークというものがあったので、これをダウン ロードしてPyObjCのpathForFramework()でロードしようとするもロードできない。まったく使えない奴らばかりです。

しかたがないので、基本はPythonで書き、CoreMIDIを使う処理だけはObjective-CとCで書いてバンドルとしてまとめ、loadBundle()で読み込んで使うことにした。もはやObjective-Cだけでええやんって話やけど、やはりソースファイルが少なくてすむし、文字列操作らくだし、リンクとかメモリとかあんまり気にしなくていいので。以下、バンドルの作り方とバンドルの読み込み方法。

HelloWorldバンドルの作成:Xcodeでバンドル作成プロジェクトを作成し、プログラムしてコンパイルする

1.XCodeメニューバー>新規プロジェクト>Cocoa Bundle でバンドル用プロジェクト作成
2.XCodeメニューバー>新規ファイル>Cocoa Class でバンドル用ソースファイル作成、追加
3.プログラムを書く(以下例)

// HelloWorld.h
#import <Cocoa/Cocoa.h>

@interface HelloWorld : NSObject {
}
- (NSString *) helloWorld;
@end


// HelloWorld.m
#import "HelloWorld.h"

@implementation HelloWorld
- (NSString *) helloWorld
{
return(@"HelloWorld");
}
@end

以上でコンパイル(Debugモード)すると、プロジェクトディレクトリ内にバンドルファイル
build>Debug>HelloWorld.bundle
ができている。さらに、このHelloWorld.bundleをPythonで使うには、PyObjCを使って、
モジュールとしてインポートできるようにするための、HelloWorld.pyが必要となる。以下HelloWorld.bundleを利用する例。

HelloWorldバンドルの利用方法:

必要なファイル:
HelloWorld.bundle:XCodeで作成したObjective-Cによるバンドルファイル
HelloWorld.py:HelloWorld.bundleをモジュールとして扱えるようにするpythonコード
HelloWorldTest.py:実際に動作チェックする用のpythonコード


1.HelloWorld.bundle用モジュールファイルHelloWorld.pyを作成
-----------------------------------------------------------------------------------------
#HelloWorld.py
from Foundation import NSBundle
import objc

bundle = NSBundle.bundleWithPath_(u'./HelloWorld.bundle')
bundleID = bundle.bundleIdentifier()
objc.loadBundle('HelloWorld', globals(), bundle_identifier=bundleID)
-----------------------------------------------------------------------------------------
NSBundle.bundleWithPath_ (パス名)でNSBundleのインスタンスとして、パスのバンドルを生成できる。ただしこの時点ではバンドル自体はまだロードされていない。 bundle.bundleIdentifier()でバンドルのIDを取得。これを使って、obj.loadBundle()でバンドルをロードされ、 HelloWorldバンドルがpythonのモジュールとして扱えるようになる。


2.動作確認用HelloWorldTest.pyを作成
-----------------------------------------------------------------------------------------
#HelloWorldTest.py
import HelloWorld

helloworld = HelloWorld.HelloWorld.alloc().init()
print helloworld.helloWorld()
-----------------------------------------------------------------------------------------
HelloWorld モジュールをインポートする。例ではバンドルはObjective-CによるHelloWorldクラスであり、HelloWorldクラスは NSObjectを継承しているので、alloc()でメモリを確保し、init()で初期化しインスタンス生成。インスタンスメソッド helloWorld()を呼び出すと、"HelloWorld"の文字を返す。

0 件のコメント: