記事一覧

viewWithTag

カスタムUI の各種部品への参照は

NSTextField* aFileld = (NSTextField*)[self viewWithTag:tagNumber]

とかで取得できるのね。これは iPhone でさんざんやったのと同じだから分かりやすいわ;(なんか順番逆な気がするが;)

しかし、NSSlider のカスタムイメージの設定方法が未だにわからん!
Magical8bitPlug とかほとんどスライダーしかないからコレがカスタマイズできないとカスタムUIの意味が半減だわ;
なんで setImage: が depricated になってるんだろ???
代わりの手段が何か提供されてる???

プリセット

とりあえずAudioUnit的にはユーザープリセットはサポートしていないらしい・・・。現在の設定を .aupreset ファイルとして書き出す機能はデフォルトで搭載しているようだが。

プリセット一覧を要求されたときに都度 .aupreset ファイルが格納されているディレクトリをスキャンしたりできればいいのかな〜。
それにしても .aupreset を外部から読み込むのとかどうしたらいいのか分からんしな・・・

完全に独自仕様で実装しちゃってもいいかもな〜。
プリセットの切り替えを普通のプルダウンメニューで作って、新しいプリセットの作成もプルダウンメニューの末尾に「Create New」を付けて対応、とか。
そしたらプリセットの内容も独自形式で別ファイルに置いておけばいいしな〜。

うー・・・

とりあえずカスタムUIの件はメーリングリストに質問して回答待ちってことで、ひとまずもう一個懸案だったファクトリープリセット&ユーザープリセットに取りかかってみるが、こちらも情報少なすぎて泣きそう・・・。
アップルの公式サンプルコード、プリセットの内容全部 static const float kPrameterXXX = .... でベタ書きって何だよぉぉ!!
これじゃユーザープリセットとか一切できないじゃんかよぉぉ・・・

誰かAudioUnitの全貌を日本語でやさしく教えてくれー!!!

とりあえず、

ポップアップの中身の設定は、
- (void)setAU:(AudioUnit)inAU
の中で [popUp1 addItemWithTitle:@"..."];
とかすれば良いようだ。
あとは中に入れる内容だが・・・、getParametereValueStringsをどうやって呼べばいいんだ?
パラメータの値自体は AUParameterGet( ... ) で取れるようだけど、これに対応するポップアップアイテムの取得手段って何だ???

次なる難関・・・

こんどはカスタム UI の中身をどう実装するかですわ。

ひとまず、プルダウンメニューとかどうすりゃいいんだ・・・。
しかるべきところで AudioUnit 本体の getParameterStrings( ... ) を呼んで、その内容を NSPopUpButton に流し込めばいいんだろうけど、それをどこに書いたらいいんだ?
ていうか、NSPopUpButton の扱い方忘れた・・・。
こりゃまた一悩みですな;

後からカスタムUIを追加する

なんだかやたら面倒だったぞ!!
あまりに複雑だったので、とりあえず自分用にメモ。
今扱ってるプロジェクト名を MyGreatPlugin.xcodeproj と仮定します。


(1)仮プロジェクトを作る
仮プロジェクトとして、新規で Audio Unit Effect with Cocoa View プロジェクトを作る。ここから目ぼしいものをコピーして使う。

※プロジェクト名は、目的AUとかぶる部分が無いようにする。
(あとで一括置換をかけるから。たとえば対象の名前が MyGreatPlugin のときに、この仮プロジェクト名を Plugin とかにするとハマる)
ここでは仮に CocoaViewTemp.xcodeproj としておこう。

(2)仮プロジェクトから必要なものをコピー
CocoaViewTemp.xcodeproj の「グループとファイル」から、cocoaUIグループをまるごとコピー。ファイル名に CocoaViewTemp とついてる部分を全部 MyGreatPlugin に置き換える。

同じく、resources にある .xib と .plist もコピーして名前を置き換える。

(3)ソースコードに AU プロパティ関係のメソッドを追加
仮プロジェクト内の CocoaViewTemp.cpp から
virtual OSStatus getPropertyInfo( ... )
virtual OSStatus getProperty( ... )
の2つをコピーして、MyGreatPlugin.cpp の対応する位置にペースト。

CocoaViewTemp.h にこれのプロトタイプ宣言もあるので、それも MyGreatPlugin.h にコピー。

(4)仮プロジェクト由来の名前を一括置換
プロジェクト検索で CocoaViewTemp を MyGreatPlugin に一括置換。plist の中身が置換にかからないこともあるかもしれないので確認。

あと、これによって MyGreatPlugin.cpp 内の getProperty( ... ) にある
CFBundleRef bundle = CFBundleGetBundleWithIdentifier( ... )
内に書かれている識別子が正しいか確認する。
(ターゲットのプロパティの「識別子」( com.GreatCompany.MyGreatPlugin みたいなやつ)と一致していれば良い)

(5).xibファイル内の各種名前変更
MyGreatPlugin_cocoaView.xib を Interface Builder で開き、
File's Ownerのクラス名を MyGreatPlugin_CocoaViewFactoryに、ビューのクラス名を MyGreatPlugin_CocoaView 変更する

(6)バンドルのビルド設定
MyGreatPlugin.xcodeproj の「グループとファイル」にある「ターゲット」から右クリックで新規ターゲット→Loadable Bundleを選択して新しくバンドル用ターゲットを作成。
名前はとりあえず CocoaUI としておく。

ターゲットのプロパティを開いて、プロダクト名を
MyGreatPlugin_CocoaViewFactory
に変更する。

このターゲットに、ドラッグ&ドロップとかいろいろやって
▼ヘッダをコピー(2)
 MyGreatPlugin_CocoaViewFactory.h
 MyGreatPlugin_CocoaView.h
▼バンドルリソースをコピー(2)
 MyGreatPlugin_CocoaViewFactory.plist
 MyGreatPlugin_CocoaView.xib
▼ソースをコンパイル(2)
 MyGreatPlugin_CocoaViewFactory.m
 MyGreatPlugin_CocoaView.m
▼バイナリをライブラリにリンク(3)
 AudioToolbox.framework
 AudioUnit.framework
 Cocoa.framework
となるようにする。

(7)メインターゲットにバンドルを加える
メインターゲット(ここでは「ターゲット」の下の MyGreatPlugin)の下にさっき作ったターゲット "CocoaUI" をドラッグして加える。

さらに、メインターゲットに「新規コピーファイル」を追加。(デスティネーションは「リソース」のまま。)これで出来た「ファイルをコピー」の下に Productsの下にある MyGreatPlugin_CocoaViewFactory.bundle をドラッグして追加する。


たぶん以上の手順でひとまずは通る・・・かも。
書き忘れ・書き間違いが多々あると思うので。

あと、書いてる途中で思ったが、仮プロジェクトの名前を対象プロジェクトと同じにするという手もあったな・・・。
別のフォルダに作ればいいだけだもんね。その場合コピー元とコピー先を間違えないように注意だな。

ウギャーー!

やっぱり C++ わからん!!!!
なんで AudioUnit は C++ なんだよ〜

たまりかねて Amazon でロベールの C++入門ポチッとしてきました・・。

久しぶりに Cocoa

iPhone アプリが一段落したので久しぶりに MacOSX アプリの方に戻ってきたけど、NSDocument Application とかややこしすぎだわ。
いろいろ必要な機能を準備してくれてるのはいいのだけど、どの段階で何をしてくれてるのか分からないので、ちょっと応用しようと思うとかなり悩む。特に Interface Builder が絡んでくるところはほとんど謎。
少し解析して自分なりにまとめてみないとですな。

オブジェクトの保持

オブジェクトを保持するためには、オブジェクトに retain を送る。そのためには
[anObject retain];
などとする。これはいいとして、では、具体的に retain カウントを持っているのは誰か? といえば、それは anObject ではなく、あくまで 0x33994b2c とかいうアドレスで「メモリ上に格納されているそれ」である。
anObject は単なるポインタであって、「それ」と通信する窓口にすぎない。窓口は複数あっても良いから、anotherObject という別の窓口から retain やら release を送ってもよい。

・・・こんな話は Objective-C の入門書に書いてあることをよく噛みしめて読めば分かることなのだけど、始めた当初はどうにもこの仕組みを把握しにくかった。

で、最近思うに、その理由は「『それ』はメモリ上の『それ』であって、あくまで名前は無い」ということをハッキリ意識できていなかったからではないか、と。
静的な変数では、「名前」と「それに対応するメモリ上のデータ」を別個に意識する必要はないわけで、そのイメージが当初はなかなか拭えなかったのかもしれない。

Appの提出は

開発者がそのまま iTunes Connect で提出する場合は手順通りで良いわけですが(それでもけっこう面倒ですがね)、提出する人が別だと大変ですね。

提出用の最終ビルドは、Developer Program に Team Agent として登録している人しか作れないわけですが、Team Agent ってそもそも会社を代表して Apple と契約した人なわけで、そういう人ってわりと事務方の人間であることが多いんじゃないでしょうか。
その人にソース渡してコンパイルしてください、ってのは酷な話ですわ。

似たような状況にある方々は結局みんな、秘密鍵を受け渡しして「なりすまし」で切り抜けるというパターンに落ち着いているのではないかと推測します。
ちなみに、その場合に使う方法手順はこちら。「バックアップまたは環境移行」のための方法。これを裏技的に使うわけですね。
http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/128-Managing_Devices/devices.html