XcodeでPure Dataのオブジェクトを作る 1. Hello world

Posted in PD会 on 9月 14th, 2009 by Norihisa Nagano – 3 Comments

Pure Data(以下Pd)がiPhoneで動かせたので、いろいろ拡張すべく格闘しています。
Pdの使い方が実は分かってないとか、いろいろ(大きな)問題はありますが、なにはともあれプラグインで拡張です。
そう、Pdは自分でオブジェクトをCで書いて拡張できるようになっています(エクスターナル・オブジェクト。以下External)。画面に出てくるあのブロックを自作できるわけです。

Windowsはどうだか知りませんが、Mac OS Xの場合Pd-extendedをインストールしているなら
/Applications/Pd-extended.app/Contents/Resources/extra/bonk~/bonk~.pd_darwin
みたいに、.pd_darwinというファイルがあります。これがExternalです。
Cで書くのだから、Xcodeで作れます。
ということで作ってみよう!5分で作れます。

追記:
UNIXな人はnagachikaさんの記事を参照です。

準備

http://puredata.info/docs/developer/PdExternalsInXcode
にばっちり書いてあるので、この通りやればいいのですが、10.6で画面が少々違うし、日本語であるとうれしいかもなので書いておきます。

・プロジェクトを作る
Xcodeで新規プロジェクトを作ります。
Framework & LibraryのBSD C Libraryを選択して、TypeはDynamicにします。これ重要です。
名前はhelloworldにします。
Screen shot 2009-09-14 at 12.19.51

・ビルド設定
先にビルド設定を行います。
赤い丸のTargetsのhelloworld
Screen shot 2009-09-14 at 12.21.10

をダブルクリックするとインスペクタが開くのでBuildタブを選択して
Configuration:を[All Configurations]にして横の検索窓に”Other linker flags”と入力します。

Screen shot 2009-09-14 at 12.23.44

Other linker flagsのところをダブルクリックするとシートが出てくるので +ボタンを押して
-undefined dynamic_lookup
をコピペします。これをやらないと、「この関数の実装・変数が無い、無い、無い、無い」とビルドエラーが出まくって途方に暮れることになります。つまりこれはm_pd.hに定義がある(が実装などが見当たらない)ものは動的に見るよ、という呪文です。

同様に以下3つもやります。
“Product Name”: helloworldにする(なっている)
“Executable Prefix”: libを消す。(これでlibhelloworld.dylibというファイル名前からhelloworld.dylibに)
“Executable Extension”: pd_darwinにする(さらにhelloworld. pd_darwinになる)

追記:
上記設定名が、日本語環境だと違います。
”Other linker flags”→他のリンカフラグ
“Product Name”:→プロダクト名

“Executable Prefix”→実行可能ファイルのプレフィックス

“Executable Extension”→実行可能ファイルの拡張子
(thanks! yasoshimaさん)

以上をやってConfiguration:の下のShow:のところをSettings Defined at This Levelにするとこんな感じになってます。
Screen shot 2009-09-14 at 12.27.13

これで準備OK。

実装

http://puredata.info/downloadsからPdのソースをダウンロードしてきてm_pd.hを探してプロジェクトにコピーします。
m_pd.hにはPdのオブジェクトで使うクラスや型の定義、メソッドがもりもり書いてあります。

コマンド + Nで新規ファイルの追加画面が出るので、helloworld.cというファイルを作って追加します。このファイルに実装を書きます。

この時点でこういう感じになっています。
Screen shot 2009-09-14 at 12.50.28

Productsがhelloworld.pd_darwinになってないと設定が失敗してます。
.pd_darwinという拡張子じゃないとPdが読み込んでくれないので注意です。

次に、helloworld.cに
http://iem.at/pd/externals-HOWTO/node3.html

the code: helloworldのコードをコピペします。

これで実装は完了です。

このオブジェクトが何をやるかというと

void helloworld_bang(t_helloworld *x)
{
    post("Hello world !!");
}

となっているように、bangを送ったら、Hello world !!と出力します。

テスト

ビルドターゲットをReleaseにしてビルドしましょう。
Screen shot 2009-09-14 at 12.32.12

ファイルを見ると、こういうのが出来てます。
Screen shot 2009-09-14 at 12.34.10

このファイルを/Applications/Pd-extended.app/Contents/Resources/extraのどこかにコピーします。
extra/helloworld/helloworld.pd_darwinとか、フォルダを作って置いてもOKです。

では、Pdを起動してみましょう。

こんな感じでHello world !!
と出ます。

Screen shot 2009-09-14 at 12.36.33

Hello world !!

これでPdが拡張し放題ですね。

作ったXcodeプロジェクトファイル

PD会 第1回やりました

Posted in PD会 on 9月 6th, 2009 by Norihisa Nagano – Be the first to comment

Pure Dataのソースコードを読んでどうにかする会、第1回をやりました。

ざっと内容など。

・自己紹介いただいて、興味あることなどを伺う。
音に興味ありという人がほとんどながら、みなさんいろんなバックグラウンドで面白い。

・興味別に
オーディオ処理部分解明班
ビジュアル処理部分解明班(GEMとかGUIとか)
移植班(iPhoneとかAudio Unitへとか)
PD自体の解明班

に分かれてもらってグループ会議。

その後、三名様発表
藤本さん「Pure DataとArduino」「GEM入門」
ナルミさん「Objective-C++ 入門」

で、僕の発表は「Pure Data Runtime for iPhone」
その名の通り、Pure DataをiPhoneに移植したので、そのデモをしました。(当然GUI除く)
それに合わせて、PDの大まかな構造の解説などしました。
RjDjを超える勢いでがんばります。

と、PDとRjDjのネタを書いていたら、unoh labさんでRjDjのシーン作成の解説が公開されています!
すごく分かりやすい解説。素晴らしい。
(僕の記事もリファーいただいていて光栄)

PD会、次回は9/19 or 20に開催予定。
初回に参加されなかった方も参加いただいて大丈夫です。
(初回の議事録を追っていただければ)

ただ、次回は会場に余裕が無い可能性があるので、現在14名のメンバーさんのお休み待ちになるかもしれません。
ともあれ、まずは参加メールをnagano@monalisa-au.orgまで。

オライリー「iPhone SDK アプリケーション開発ガイド」

Posted in iPhone Core Audio on 8月 29th, 2009 by Norihisa Nagano – Be the first to comment

オライリー「iPhone SDK アプリケーション開発ガイド」が9月頭に発売になります。

オライリージャパンからの初のiPhoneプログラミング本ということで、Twitterなどで話題になっている模様です。

詳しい内容は充実のサポートページを参照いただくとして、日本語版のみの付録Bに寄稿させていただきましたので、それについて。

付録Bでは、Audio SessionAudio Unitについて、iPhoneのプログラミング本ではなぜか両方無視されているので、これはいかんということで書いてみました。
(Webでも日本語だと、Objective-Audioさんとウチぐらいしか見当たらないし)

例えば、App Storeのオーディオを扱うアプリケーションで、「サイレントモードでは音が出ません」と書いてあったりします。Audio Sessionの節では、果たしてそれでいいのかどうか、またその挙動を変更することができる、ということを書きました。

iPhoneのオーディオはいろいろ難しいみたいな話がありますが、Audio Unitは簡単ですよ、ということでAudio Unitの節では、8.24固定小数点の解説からはじまって、サイン波を鳴らすサンプルを解説してあります。シンセサイザーを作りたいんだけど、Audio Queueだと難しいし、レーテンシーが・・という場合はAudio Unitですよ!

おそらく両方のトピックとも、本に載るのは初めての情報だと思います。
そんなわけで、お手に取ってくみてください。
現在、Amazonで予約可能になっています。

また、現在開催中の第参回天下一カウボーイ大会
Lightweight Language Television (LLTV)
で先行発売されているようです。


画像はnakamura001さんがアップされていたものです。

Pure Dataのソースコードを読んでどうにかする会 2

Posted in PD会 on 8月 26th, 2009 by Norihisa Nagano – Be the first to comment

Pure Dataのソースコードを読んでどうにかする会ですが

日時: 9/6 13:00〜
場所: 表参道

開催になりました。
日程が分からないので迷っていらっしゃった方、ぜひぜひ御参加ください。

初回は自己紹介、方針の会議や、ネタがあれば発表いただく感じで考えています。
現在、メンバーさんは11名です。

お借りする会議室の入室で以下の情報が必要ですので、記載いただいて
nagano@monalisa-au.orgまでご連絡ください。
————
1. フルネーム
2. 所属
————
合わせてメーリングリストにGoogle Group、document共有にGoogle Docを使っているので(あれば)Googleアカウントを教えてください。
なければご連絡いただいたメールアドレスをメーリングリストに登録させていただきます。
詳しい場所、当日の入室方法等はMLでお知らせします。

特にすごい技術を持っていないと駄目、とかはないので(僕もそんなものは持っておりません笑)、お気軽にご参加ください。

#ただ、PDの使い方が調べられないとか、C言語って何?という方は厳しいです。

お問い合わせ

・Twitterで7gano宛に@
・nagano@monalisa-au.orgまでメール
・ここにコメント

Corer Point 1.2

Posted in Download Software on 8月 21st, 2009 by Norihisa Nagano – Be the first to comment

Corer PointをMac OS X 10.5 Leopard対応しました。

Pure Dataのソースコードを読んでどうにかする会

Posted in PD会 on 8月 20th, 2009 by Norihisa Nagano – Be the first to comment

勉強会を企画しています。名付けて「PureDataのソースコード読んでどうにかする会」

PureDataって何?

オブジェクトと呼ばれるブロックを複数接続して、オーディオ、グラフィック処理が行える、オープンソースのソフトウェアです。
Mac/Win/Unix/Linuxなど、およそメジャーなOSに対応しています。言語はCでGUIはTcl/Tkです。

http://puredata.info/ (本家)
http://puredata.info/downloads (Get PD!)

何やる会ですか?

基本、PureDataのソースコードを読んで、応用する会です。デジタル信号処理の勉強や、自分のソフトウェアへの応用をメインに考えています。PureDataはオーディオメインですが、GEMという3Dグラフィクス用オブジェクト群もあるし、GUI部分を改良するならQuartzを使うなど、グラフィックの人も参加いただけるのではないかと思います。というか是非。
その他、C言語は分からないけど、PureDataを何かに使いたいので、他のメンバーさんとコラボするってのも可能かと思います。

どこでやるの?

開催場所は都内になります。
どこかの会議室を借りるなどを考えています。
その場合、若干費用を負担いただくことになります。
場所をご提供いただける方大募集!

tatmosさんに会場提供いただけそうです!感謝。

いつやるのか?

未定。たぶん来月以降になります。
土日になります。

何をやるの?

PureDataの守備範囲は多岐に渡るので、興味に応じて班に分けて、各班で成果を発表してもらうというのもありかな、と思っています。
例えば以下。

・PureDataの使い方とか調べる班
    パッチ作って、こんなのできるよーとか。作品作りたい人向け

・Quartzで書き換える班
    フロントエンドを作ってPDの使い勝手とパフォーマンスを向上!

・オブジェクトのソース読んで解説する班
    デジタル信号処理を勉強したい人向け。

・移植を進める班(iPhoneとかAndroidとか、自分アプリとか)
    iPhoneへの移植を試みて、iPhone Core Audioの勉強をする
    ソースがCなので、Objectを読めるようにするだけで、例えばフィルターが使えるようになるとかいいな

・ドキュメント読む班
    結構いいドキュメントがある!ミラーパケット万歳
    http://crca.ucsd.edu/%7Emsp/techniques/latest/book-html/

・GEMを他に移植班
    グラフィックエンジンとして利用
    iPhoneに移植すればOpenGL ESの勉強になる

・別言語にする(俺PD)

・OpenCV本も出たことだし、Objectに移植する
既に移植してある(via naokiringさん)

・Quartz Buildとかを出して、PureDataに還元する。

そんなわけで、いろいろできると思います。

初回は、何をやるか、どういう風に進めるかを会議しようと思っています。

Twitterで提案してみたところ、現在、オーディオ、グラフィック、フィジカルコンピューティングなどの分野の強者の方々に参加表明いただいております!
以下、TwitterID(書いていいよと言ってもらった方のみ。追記予定)
naokiring
lalalila
tgck
tatmos
sumitwit

僕は7ganoです。

参加表明

・Twitterで7gano宛に@
・nagano@monalisa-au.orgまでメール
・ここにコメント(メールアドレスを記入お願いします)

など、僕宛になんらかの方法でご連絡ください。
メンバーさんと書いた原案をGoogle Docで共有しますので、合わせてGoogle アカウントをお知らせいただけると助かります。

参考URL
http://puredata.info/ (本家)
http://puredata.info/downloads (Get PD!)

派生プロジェクト
DesireData
http://code.goto10.org/projects/desiredata/wiki/UserDocs
    DesireData is a project whose main goal is to enhance the everyday experience of the PureData users and developers.

(via lalalilaさん)

RjDj
http://www.rjdj.me/what/

iPhone Core Audio Programming 第3回 AUGraphを使ってPlay Thru 2

Posted in iPhone Core Audio Programming on 8月 19th, 2009 by Norihisa Nagano – 2 Comments

前回の続き。

まずはRemote IO Unitのバスとスコープについて。
Remote IO UnitはAudio Unitの中でも特殊で、二個のAudio Unitをくっつけたみたいな感じになってます。
In/Outだからこれで正常ですが。
で、その構造は次の図のようになっています。
IO_unit
AppleのDocumentから拝借。

Input scopeとOutput scopeは、次の定数
kAudioUnitScope_Input
kAudioUnitScope_Output
で区別します。
Audio Unit全体にかかわる設定のときにはkAudioUnitScope_Globalを使います。
バスは1と0で区別するので、前回の次のコードを翻訳すると

//マイク入力をオンにする
UInt32 flag = 1;
AudioUnitSetProperty(remoteIOUnit,
                         kAudioOutputUnitProperty_EnableIO,
                         kAudioUnitScope_Input, //Remote InputのInput
                         1, //Remote Input
                         &flag,
                         sizeof(UInt32));

Remote IO Unitのマイク入力のInput BusをEnableにする

となります。図のマイクがつながっている左側の部分が対象、となります。

で、前回の問題はこの入力がモノラルになってるんだけど、出力がステレオだから片方聞こえない
でした。なので、マイク入力以降をモノラルにしちゃいます。

Core Audioで、オーディオデータフォーマットを扱うにはAudioStreamBasicDescription構造体を使います。

struct AudioStreamBasicDescription
{
    Float64 mSampleRate;
    UInt32  mFormatID;
    UInt32  mFormatFlags;
    UInt32  mBytesPerPacket;
    UInt32  mFramesPerPacket;
    UInt32  mBytesPerFrame;
    UInt32  mChannelsPerFrame;
    UInt32  mBitsPerChannel;
    UInt32  mReserved;
};
typedef struct AudioStreamBasicDescription  AudioStreamBasicDescription;

名前が長いので、ASBDと略して使います。

それぞれのメンバの詳細はおいておいて、チャンネル数はmChannelsPerFrameです。
で、iPhone Core AudioではAudio Unit正準形というのがありまして、Audio UnitのデフォルトのASBDです。

mSampleRate = 44100.0;
mFormatID = kAudioFormatLinearPCM;
mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
mBytesPerPacket = 1 * sizeof (AudioUnitSampleType); // 8
mFramesPerPacket = 1;
mBytesPerFrame = 1 * sizeof (AudioUnitSampleType); // 8
mChannelsPerFrame = 2;
mBitsPerChannel = 8 * sizeof (AudioUnitSampleType); // 32
mReserved = 0;

このASBDのmChannelsPerFrameを1にすればモノラルのAudio Unit正準形になります。
ただし、iPhone OS 3.0と2.2.1以前とでは、厳密にはデフォルトが異なります。この辺はいずれ詳しく扱うとして、ひとまずPlay Thruを完成させます。

結局のところ、図の部分をモノラルにすれば解決します。
ピクチャ 15

モノラルにするには、Audio Unit正準形のモノラルのASBDを作ってAudioUnitSetPropertyでセットします。

AUGraphInitializeの前に以下のコードを追加します。

    //Audio Unit正準形
    AudioStreamBasicDescription audioFormat;
    audioFormat.mSampleRate      = 44100.0;
    audioFormat.mFormatID         = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags      = kAudioFormatFlagsAudioUnitCanonical;
    audioFormat.mBytesPerPacket   = 1 * sizeof (AudioUnitSampleType);
    audioFormat.mFramesPerPacket  = 1;
    audioFormat.mBytesPerFrame    = 1 * sizeof (AudioUnitSampleType);
    audioFormat.mChannelsPerFrame = 1; //モノラル!!
    audioFormat.mBitsPerChannel   = 8 * sizeof (AudioUnitSampleType);
    audioFormat.mReserved         = 0;

    //モノラルに変更する
    AudioUnitSetProperty(remoteIOUnit,
                         kAudioUnitProperty_StreamFormat,
                         kAudioUnitScope_Output, //Remote inputのアウトプットバス
                         1, //Remote input
                         &audioFormat,
                         sizeof(AudioStreamBasicDescription));

    AudioUnitSetProperty(remoteIOUnit,
                         kAudioUnitProperty_StreamFormat,
                         kAudioUnitScope_Input, //Remote outputのインプットバス
                         0, //Remote output
                         &audioFormat,
                         sizeof(AudioStreamBasicDescription));

これでOK。最終的な出力は入力がモノラルなので、勝手にLRに同じソースを出力してくれます。なので、kAudioUnitScope_Output/Bus0は変更しなくてOK(というか変更できません)。

iPhone OS2.2.1でも3.0でも3.1でも完璧に動きます。

この例はiPhoneの内蔵マイクを使う場合ですが、ProTrackみたいなステレオマイクを持つ外部機器を接続した場合、実は前回のコードでまったく問題無くステレオでモニタリングできます。
なので、外部機器を付けたときは前回の設定、通常時は今回の設定に切り替えればOKです。
じゃぁ、マイク入力の入力チャンネル数ってどうやって取得するのか?
Audio Sessionを使います!

ってことで、次回はAudio Sessionをやります。
続きは次回。

#あ、オトカメラ、ステレオ録音対応してなかった。以上のように簡単なので対応します。

オライリー 詳解 OpenCV

Posted in Book on 8月 19th, 2009 by Norihisa Nagano – 1 Comment

Learning OpenCVの日本語版、詳解 OpenCVが2009年08月22日発売になります。

オライリー様より献本いただきましたので、ちらっと内容をご紹介。

OpenCVのCVというのは、Computer Visionのことで、つまりは画像処理ライブラリです。
代表的なところでは顔認識などができます。試してみましたがなかなかの精度です。
OS Xでささっと試すには、海上忍さんのこの記事が分かりやすいです。

本の内容ですが、おおまかには、あるアルゴリズムを示し、それをOpenCVの関数で実際に試してみるという形式で進みます。

OpenCVは移植性を重視して実装されている(らしい)ので、いろいろなプラットフォームで動きます。iPhoneでも動きます。詳解 OpenCVでも、iPhoneへの移植が日本語特別付録で扱ってあります。しかも処理の高速化がこれでもかと細かく書いてあり、OpenCV以外へも応用できそうです。いやいや、これすごいな。

Web2.0バブルが終了してウェブサービスが軒並み下火で、ARが儲かるかどうかでいろいろな企業が模索中な今日この頃、ARの基本技術である画像認識への需要は高まるばかり。少なくともこの本に載っているアルゴリズムぐらいは押さえておく必要がありそうです。そんなわけでオススメ!
(僕も勉強中)

iPhone Core Audio Programming 第2回 AUGraphを使ってPlay Thru

Posted in iPhone Core Audio Programming on 7月 22nd, 2009 by Norihisa Nagano – Be the first to comment

iPhone Core Audio Programming 2回目

前回、これまでGetting Started〜で書いてきたことがiPhoneでも通用すると書きました。
あと、Core Audioはいろいろありすぎてわけわからん!などと言われているようですが、たしかにそうだし、サンプルコードがほとんど無いというのはありますが、実は結構簡単です。
まずはそれを証明しましょう。
そこでまずは、というかいきなりAUGraphを使ってみます。Audio Queueより簡単です。
(僕はAudio QueueはCore Audioで一番難しいと思うのですが、どうでしょう)

AUGraphとは何か

AUGraphについては
Getting Started With Audio Unit 第06回.AUGraphとは何か
Getting Started With Audio Unit 第16回.AUGraph SubGraphを使う

で説明してあります。なんだか分からない方は先に一読ください。その方が今後の時間節約になると思います。

簡単に説明すると、AUGraphはAudio Unitを複数組み合わせて一つの処理を実現するための仕組みです。
Audio Unitとはオーディオ処理で必要となる機能を持つプラグインです。プラグインといっても必ずしもVSTみたいなエフェクターではなくて、音の出力、ミックス、変換、生成など、オーディオ処理で必要となるほぼ全ての機能を持てます。

*Audio UnitについてもGetting Started With Audio Unitの1〜5回ぐらいまでを読んでおいてください。

Core Audioはこのようにシステム自体がプラグイン・アーキテクチャーを採用しています。
AVAudioPlayerとかAudio QueueとかOpenALとかいろいろありますが、最終的には全部Audio Unitを使っていると考えてよいです(後述のRemote IO Unitを使って音を出力します)。

さて、話を戻すと、AUGraphを使うわけですが、iPhone Core Audioには音を生成するジェネレーター(kAudioUnitType_Generator)に該当するAudio Unitがありません。そこで今回はマイク入力を使います。つまり、マイク入力をそのまま出力するAUGraphを作ります。

Remote IO Unit

マイク入力、スピーカーからの出力にはRemote IO Unitを使います。
OS X Core AudioのDefault Output Unitと同じと考えてもらっていいと思います。
Remote IO Unitには IOというぐらいですから、InputとOutputがあります。
そしてそれぞれは「バス」(Bus)で区別します。Inputは1でOutputは0です。以降、このバスの1とか0をバスナンバーと呼びます。今回はこれだけ分かればよいです。詳細は次回解説します。
以降、便宜的にInputをRemote Input、OutputをRemote Outputと呼びます。

さっそく、Remote InputとRemote Outputを繫いでAUGraphを作ってみます。

PlayThruという名前でView-Based Applicationをテンプレートにプロジェクトを作って、AudioToolBox.frameworkをリンク、PlayThruViewController.hに
#import <AudioToolbox/AudioToolbox.h>
#import <AudioUnit/AudioUnit.h>
を追加、viewDidLoadを以下のように実装します。ViewControllerにオーディオのロジックを書くな!と言われそうですが、クラス化はひとまず置いておいて、手っ取り早く動かしましょう。

ちなみに、AudioUnit.frameworkはリンクしません。するとビルドエラーが出ます(なにこれ)。

- (void)viewDidLoad {
    AUGraph mAuGraph;
    AUNode remoteIONode;
    AudioUnit remoteIOUnit;

    NewAUGraph(&mAuGraph);
    AUGraphOpen(mAuGraph);

    AudioComponentDescription cd;
    cd.componentType = kAudioUnitType_Output;
    cd.componentSubType = kAudioUnitSubType_RemoteIO;
    cd.componentManufacturer = kAudioUnitManufacturer_Apple;
    cd.componentFlags = cd.componentFlagsMask = 0;

    AUGraphAddNode(mAuGraph, &cd, &remoteIONode);
    AUGraphNodeInfo(mAuGraph, remoteIONode, NULL, &remoteIOUnit);

    //マイク入力をオンにする
    UInt32 flag = 1;
    AudioUnitSetProperty(remoteIOUnit,
                         kAudioOutputUnitProperty_EnableIO,
                         kAudioUnitScope_Input, //Remote InputのInput
                         1, //Remote Input
                         &flag,
                         sizeof(UInt32));

    AUGraphConnectNodeInput(mAuGraph,
                            remoteIONode, 1, //Remote Inputと
                            remoteIONode, 0  //Remote Outputを接続
                            );
    AUGraphInitialize(mAuGraph);
    AUGraphStart(mAuGraph);
}

カテゴリ(タイプ)がkAudioUnitType_OutputでサブタイプがkAudioUnitSubType_RemoteIOのAudioComponentDescriptionを作って、AUGraphAddNoteでRemote IO UnitをAUGraphに追加、Remote InputとRemote Outputを接続しているだけです。
途中、AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO)という呪文がありますが、これはマイクを使う!という指示です。Remote InputのInputという謎のコメントがありますが、Remote Inputはマイク”入力”を”出力”するのですから、当然Input/Outputがあるわけです。とりあえず今は呪文と思ってください。

これら以外はGetting Started With Audio Unit 第06回.AUGraphとは何か
とほとんど同じコードだというのが分かると思います。
AUGraphNewNodeがdeprecatedになったのでAUGraphAddNodeに変更になっていたりしますが。

ヘッドフォンを装着して、ビルド実行してみてください。マイク入力が聞こえます。
が、が、片方のチャンネルしか聞こえません。

マイク入力がモノラルなのに、その後はステレオになっているので片方しか聞こえないのですが、これを解決するにはRemote IO Unitの詳細とAudioStreamDescriptionを解説しないといけないので、次回やります。

ちなみに、ヘッドフォンをしてない場合は面白くて、受話部分から音が出ます。
これは、ヘッドフォンをしていない場合、スピーカーを使うと、スピーカーとマイクが近い位置にあるので、フィードバック(ハウリング)してしまうため、こういう仕様になっています。これはAudio Sessionを使うと変更できます(Audio Sessionについてはたぶん第4回目ぐらいにやります。)。

次回はちゃんと両チャンネルから音が出るように修正していきます。あと、今回のコードは処理の開始・停止すらないので、これも実装します。

Core AudioのAPIはほぼ全部OSStatus型を返します。これはエラーが発生した場合に0以外が帰ります。今回は全部無視していますが、気になる人は

OSStatus err = AUGraphNodeInfo(mAuGraph, remoteIONode, NULL, &remoteIOUnit);
if(err)NSLog(@"errorが発生した! %d",err);

という感じでチェックしてください。

App Storeにあるレコーダーはモニタリングができないものが大半ですが、AUGraphを使えば結構簡単にできます。この入力をどうにか加工すればRjDjみたいなものを作るのも可能ですね。
もちろん、AUGraphを使わなくてもマイク入力を取得できますが、これも先の回でやります。

続きは次回。



オトカメラは以上の機能を使ってモニタリングに対応した、音も記録するカメラアプリケーションです。
モニタリングに加えて、録音レベルの調整にも対応しています。

App Storeで購入いただけますので、よろしくお願いします!

ただ、3GSで不具合が見つかったので、3GSの方は少々お待ちください。

iPhone Core Audio Programming 第1回 概要

Posted in iPhone Core Audio Programming on 7月 21st, 2009 by Norihisa Nagano – 4 Comments

iPhone Core Audio Programming 1回目。

Getting Started With Audio Unitが2006/12、Introduction to Audio Unit Developmentが2007/11と、情報が古くなってきました。加えて、iPhoneの登場でCore Audioが次の次元へ進みました。Core AudioとiPhoneが出会い、「いつでもどこでもCore Audio」な時代の到来です。そんなiPhone Core Audioの全容がやっとつかめてきたので、続編iPhone Core Audio Programmingをはじめます。

iPhone Core Audio Overview

まずは最初にOS X Core AudioとiPhone Core Audioの違いを把握しておきます。

Audio Session

iPhoneはモバイルデバイスであるため、特有のサービスが導入されています。
それがAudio Session Servicesです。Audio Session Servicesは何をやるかというと、例えば、サイレントモード時にオーディオを鳴らすか鳴らさないか、といったオーディオの挙動、電話がかかってきたときにどうするか(割り込みへの対応)、そしてハードウェアの状態の制御です。

オーディオの挙動、割り込み
iPhoneがコンピュータと異なるのはさまざまな状態を持つということです。それはヘッドフォンをして音楽を聞いているだとか、サイレントモードにしてるといった状態です。Audio Sessionはこれらに対応するための仕組みで、つまり最もiPhoneらしいサービスだと言えます。Audio SessionがiPhone Core Audioの特徴を最も表していると言っても過言ではない!
そして状態のもう一つが電話がかかってくる、ということです。電話がかかってきて応答するとアプリケーションは終了しますが、拒否したり、出なかったりすると、またアプリケーションに処理が戻ってきます。これが割り込みです。まっとうなアプリケーションはこの割り込みに対応せねばなりません。これもAudio Sessionが担当します。

ハードウェアの状態の制御
で、OSX Core AudioではHAL(Hardware Abstract Layer)があるのですが、iPhone Core Audioではありません(というかたぶんあるけどアクセスできません)。なので、Audio Sessionが代わりに対応します。

AVFoundation

もう一個、OS X Core Audioには無いものとして、AVFoundation Frameworkがあります。これは
・オーディオ再生
・録音
・Audio Sessionの操作
が行える、”Objective-CのAPI”を持つフレームワークです。Objective-CのAPI !
これはCore Audio史上初で相当びっくりしました。相当びっくりしました。相当びっくりしました。

AVFoudationの機能と、この傾向を見るに、AppleはおそらくリニアPCM等のオーディオのデータを直接操作する必要が無いものはObjective-CのAPIを提供するという方針になったんじゃないかなと思います。
そのうちAVEffectとか出て、AVAudioPlayerにエフェクトかけれるようになるんじゃないかなぁ、と。

Audio Unit、AUGraph

しかし肝心のエフェクト、つまりエフェクトカテゴリのAudio UnitがiPhone Core Audioには一個しか載ってません。
iPodアプリケーションでイコライザが使えますが、これの実装はAudio Unitになってて、iPod Equalizerという名前で搭載されております。エフェクトはこれだけです。
IMG_5352

あとはOS Xにも載ってる3D Mixer、MultiChannel Mixer、AU Converterなんかが載ってます。OpenALは3D Mixerの上に実装されているので、3D Mixerを直接使えばOpenALと同等のことができます。だたし、3Dといっても頭部伝達関数(HRTF)あたりの3D定位用の機能がiPhone Core Audio版には実装されてないので、パンニングしかできません。全然3Dじゃないです。パンニングはパラメーター上360度できますが、前後でまったく同じ音がなるので意味無しです。上下に限ってはヴォリュームすら変わりません。つまりOpenALでできるのもパンニングのみです。3GSは結構速いのでそのうちHRTFが実装されるかもしれません。その時本領発揮となるでしょう。で、これらAudio Unitを使う場合にはAUGraphを使うのですが、Sub Graphは使えません。Audio Unit少ないし、Sub Graph使うようなこともないだろうと思われるので問題無いでしょうし、iPhone OS 3.5とかになれば実装されるやもしれません。

Audio Unit正準形

あとはOS X Core AudioではAudio Unitで使うリニアPCMのサンプルはFloat32型でしたが、SInt32型の8.24固定小数点という謎の形式を使います。そしてSInt32型を基準としたAudioStreamBasicDescriptionをAudio Unit正準形と言います。いろいろめんどくさそうに思えますが、floatで計算して最後に数値を変換してやればいいので大して難しくないです。詳細は後の回で解説します。

ハードウェアデコーダー

iPhoneのCPUは遅いので、MP3、ACC、Apple Losslessといった可変ビットレートの圧縮フォーマットの再生は専用のハードウェアデコーダーで処理します。なので、iPodアプリケーションも含め、同時に1個しか再生できません。そんで、いまのところApple Lossless以外はiPhone内でエンコードできません。IMA-4、iLBCなどの固定ビットレートの圧縮フォーマットは何個でもデコード、エンコードできます。

Audio Unitを作れるのか?

これがまだはっきりと明言できないのですが、3.0以降作れます。けどドキュメントが無いのでよく分かりません。あと、作ったとしてもiPhoneだとライブラリはスタティック(静的)リンクしかできないし、他のアプリケーションとも共有できないので、よっぽどAUGraphでやりたいとかじゃなければ、作る意味はあまりないかもしれません(いやいや、ひょっとしたら動的に使えるかも?)。
ただ、アプリ内課金でAudio Unitを売るっていうのはカッコいいですね。

ちなみに、iPhone Core AudioではComponent Managerが廃止になってAudio Component Servicesというのが新設されてます。
これを使ってAudioUnitのインスタンスを作ります。

これぐらいがOS X Core Audioとの違いで、それ以外はOS X Core Audioとだいたい同じです。

まとめ

以上をまとめると・・・・・Getting Startedとかで書いた内容は一部修正すればiPhoneでも使えます!

ということで、次回以降、コードも含めてiPhone Core Audioの世界を探っていきます。
次回はGetting Startedと同じく、いきなりAUGraphを使います。