Touch the Wave for iPad v1.2.1リリース

Touch the Wave for iPadのv1.2.1がリリースされました。

前回のv1.2の時に曲のファイルを一時保存する場所を変更したのですが、ミスっていて新規インストールしたときに全く曲がロードされないという状態になっていたので修正しました。

ちなみに告知していませんでしたが、v1.2から曲のロード時にテンポを自動検出する機能を追加しました。

いまのバージョンだとiPad1台で1曲しか再生できない状態なのでいまいちテンポ検出が生かせていない感じですが、iOS6になってからUSBとヘッドホン別々にサウンドを出せる様になったので(ステレオ2系統の計4chアウトが出せる)、v2.0ではdjayのように1台で2曲同時再生とモニタリングが出来るようにしようと考えています。ボタン一つでテンポの同期とか。ただ、UIが大幅な変更になるので3〜4ヶ月先くらいですかね。

あと、AudiobusもSDKが触れる様になったら対応したい所です。

AudioQueueProcessingTap

iOS6からAudioQueueServiceにProcessingTapという機能が追加されました。

これを利用すると、Queueにバッファされた後のデータにエフェクトなど処理を挟み込む事ができるようになります。AudioQueueのピッチ処理はiOSでは機能していないと思いますが、AudioUnitを挟み込む事もできるので、VarispeedとかNewTimePitchとか使えば実現する事ができます。

AudioQueueProcessingTapNew

ProcessingTapをAudioQueueで使えるようにするのが以下の関数です。

extern OSStatus
AudioQueueProcessingTapNew(
        AudioQueueRef inAQ,
        AudioQueueProcessingTapCallback inCallback,
        void *inClientData,
        UInt32 inFlags,
        UInt32 *outMaxFrames,
        AudioStreamBasicDescription *   outProcessingFormat,
        AudioQueueProcessingTapRef *    outAQTap)

AudioQueueProcessingTapNewでAudioQueueProcessingTapを作って、既に作ってあるAudioQueueに追加します。なお、ひとつのAudioQueueにつき、ひとつのProcessingTapしか割り当てられないようです。

inAQにはProcessingTapを入れたいAudioQueueを指定します。

inCallbackには処理をするコールバックの関数を指定します。引数の構成はAudioUnitのRenderCallbackと似たような感じです。

inFlagsではCallbackの動作の仕方を指定する事ができます。使えるのは以下の3つです。

kAudioQueueProcessingTap_PreEffects
kAudioQueueProcessingTap_PostEffects
kAudioQueueProcessingTap_Siphon

PreEffectsとPostEffectsは必ずどちらかを指定しないといけません。ここでのEffectというのはMacでのみ使えるAudioQueueのピッチ処理の事のようで、その前後のどちらかを選択できるようです。iOSだと、今の所どちらを選択しても動作的にはおそらく変わりません。

Siphonをフラグに足しておくと、CallbackのioDataにバッファからのデータが入った状態で来ます。フラグを入れなければ、AudioQueueProcessingTapGetSourceAudioという関数を使ってバッファからデータを読み込まなければいけません。ProcessingTapのコールバックの中だけでゴリゴリ自分で処理をするならSiphoneを入れる、AudioUnitを使って入力側のコールバックにデータが欲しい場合やスピードを変更したい場合はSiphonを入れないでAudioQueueProcessingTapGetSourceAudioを呼ぶ、という事になると思います。

outMaxFramesやoutProcessingFormatには、ProcessingTapコールバックでの最大のフレーム数や、フォーマットが返ってきます。たぶん自分でフォーマットを指定したりとかはできません。オーディオファイルをリニアPCMに解凍した状態のフォーマットが返ってくると思います。AudioUnitのエフェクトを使いたい場合は、AUConverterなどを使ってoutProcessingFormatに変換したり、outMaxFramesのフレーム数をmaximumPerFramesに設定する必要があると思います。

AudioQueueにProcessingTapを追加する簡単なコードは以下のような感じです。

//
// インスタンス変数とか(AudioQueueは既にセットアップ済みを想定)
// AudioQueueRef _queue;
// AudioQueueProcessingTapRef _processingTap;
//
static void Callback(
        void *inClientData,
        AudioQueueProcessingTapRef inAQTap,
        UInt32 inNumberFrames,
        AudioTimeStamp *ioTimeStamp,
        UInt32 *ioFlags,
        UInt32 *outNumberFrames,
        AudioBufferList *ioData)
{
    AudioQueueProcessingTapGetSourceAudio(
            inAQTap,
            inNumberFrames,
            ioTimeStamp,
            ioFlags,
            outNumberFrames,
            ioData);
    // ここで何か処理をする
}
- (void)setupAudioQueueProcessingTap
{
    UInt32 processingMaxFrames;
    AudioStreamBasicDescription processingFormat;
    BOOL isPost = YES;
    BOOL isSiphon = NO;
    UInt32 flags = isPost ? kAudioQueueProcessingTap_PostEffects :
                       kAudioQueueProcessingTap_PreEffects;
    if (isSiphon) flags |= kAudioQueueProcessingTap_Siphon;
    AudioQueueProcessingTapNew(
            _queue,
            Callback,
            NULL,
            flags,
            &processingMaxFrames,
            &processingFormat,
            &_processingTap);
}

このコードではエフェクトが何もかからないスルー状態です。Siphonをフラグに入れていないのでAudioQueueProcessingTapGetSourceAudioを呼んでいます。何か処理をしたい場合は、GetSourceAudioの後にioDataの中身をいじってください。もしSiphonをいれたらAudioQueueProcessingTapGetSourceAudioの行は全くなしでも音が鳴ります。

AudioUnitのエフェクトを使う場合には、AudioUnitの入力側のコールバックでGetSourceAudioを呼ぶ事になります。

あと、スピードを変更する場合、AudioUnitのVariSpeedを使うなら気にしなくてもいいのですが、自分でやる場合にはGetSourceAudioに渡すTimeStampのsampleTimeをちゃんと使ったフレーム分だけ毎コールバック進めないといけません。ProcessingTapに来ているTimeStampそのまま渡すと、ノーマルスピードで進んでいると判断してデータを取ってきてしまいます。

iPadアプリのRetina対応バージョンを公開

Touch the Wave for iPad」と「BigStopWatch HD」の、iPadのRetinaディスプレイに対応したバージョンを公開しました。

僕のアプリはこれらのアプリを含め全部なんですけど、画像リソースをいっさい使ってないので、いろんなところの画像を作るときのサイズを2倍にしているだけで対応しています。新しいiPadのOpenGLのテクスチャ最大サイズが4096×4096になっていたので、あっさりと終わってしまいました。iPad発売日に間に合わなかったのだけが残念です。

iOS 5のオーディオ新機能

世の中iOS 5といったらiCloudだSiriだと騒いでいますが、オーディオの新機能も実は結構あります。とりあえずどんなものがあるかだけ書いておきます。

AudioUnitプラグイン

AudioUnitのプラグインがかなり追加されてます。Macでは以前からあるもののサブセット的な感じです。

【Generator】
・ScheduledSoundPlayer
・AudioFilePlayer

【MusicDevice】
・Sampler

音を再生するものはGeneratorとMusicDeviceですね。特にSamplerはSoundFont&MIDI対応のプレイバックシンセなので、SoundFontを作ってしまえばMIDI対応も簡単にできてしまいます。「なんとかピアノ」とか「シンギングなんとか」とか、AVAudioPlayerで無理矢理つくるんじゃなくて、これ使った方が良いです。AudioFilePlayerは、これはこれでいいんですが、使い方が独特ってのもありますし、個人的にはAudioQueueのAudioUnitプラグイン版を作ってほしいなぁと思います。

【FormatConverter】
・VariSpeed
・iPodTimeOther

僕は使ってませんが、VariSpeedつかえば再生スピードの変更も簡単です。AUConverterでも良いんじゃないの?と思うかもしれませんが、VariSpeedならスピードを変えたときにプツっとならずにスムーズに変わります。ただ、すごく速くとか、すごく遅くとか出来ませんので、「Touch the Wave」でやってるようなスクラッチを実現するのは難しいです。

iPodTimeOtherというのは「Touch the Wave for iPad」でも早速使っています。iPodTimeよりもクオリティの上がったタイムストレッチです。

【Effect】
・LowPassFilter
・HiPassFilter
・BandPassFilter
・HighShelfFilter
・LowShelfFilter
・NBandEQ
・ParametricEQ
・PeakLimiter
・DynamicProcessor
・Reverb2
・Distortion

Effectは、半分くらいEQですが、結構増えました。リバーブの追加はうれしいです。

プラグインがこれだけ用意されていると、ようやくAUGraphの便利さが活用できそうです。はっきりいって今までは、RemoteIOだけ使って全部自分で作んなくちゃいけませんでしたから。

MusicPlayer

MIDIシーケンサーです。SMFが読み込めます。中にSamplerを含んだAUGraphを持っているので、入れ替えてあげれば自分で用意した音も鳴らせます。もちろんMIDIメッセージだけ再生させて利用する事も出来ます。

MIDINetworkSession

MIDINetworkSessionがシミュレータに対応してます。実機につながなくてもMacだけでMIDIの送受信ができるので、デバッグが楽になるんじゃないでしょうか。あとiOS4だとMIDINetworkSessionってMIDI使い始めたら勝手にオンになっていたと思うのですが、iOS5だとちゃんとenabledをYESにしたりとかしておかないと使えないみたいです。

Float32対応 (2011/10/23追加)

iOS 5からAudioConverterがFloat32対応になっています。上記でも紹介したAudioUnitプラグインなどは、floatにしか対応していないようです。AUGraphなんかでつなぐ場合はあまり意識しなくても良いのですが、整数で用意したデータを渡すときにはAUConverterを前に挟み込む必要がありそうです。

Touch the WaveのiOS 5向けアップデート公開

Touch the Wave 2とTouch the Wave for iPadの両方とも、iOS 5以降対応のアップデートがリリースされました。(と書いている段階では、まだiOS 5はリリースされてませんが)

Touch the Wave for iPad v1.1
Touch the Wave 2 v1.3

Touch the Wave for iPadの方は、iOS 5の新機能に対応させてます。リバーブとタイムストレッチです。それに合わせて、レイアウトの変更や、細かいところのバグ修正もしてます。

それと、しばらくセールやってましたが終了です。

Touch the Wave 2の方は、オーディオファイルがiCloudのバックアップに含まれてしまうから別のところに保存しておいてね、とAppleさんからメールを頂いたので対応しただけのバージョンです。とくに機能の変更はありません。

iOS 5では、今回アップデートで入れたリバーブなども含めて、Core Audio周りでかなり新機能が増えているので、近いうちにまとめたエントリを書こうかなと思っています。

METRONOME STAR v1.1リリース

METRONOME STARのv1.1がリリースされました。

メトロノームのクリック音を変更しました。実際にメトロノームの音を録音したものを使ってます。

まあ、もともと嫌う人が出てくるだろうなぁという音作りをしていたのもあり、リリース1年たってちらほらとそんな内容のレビューを見かけるようになったので変えてみました。あまり設定とか作りたくなかったので、完全に差し替えです。前の音には戻せません。

Touch the Wave for iPad

Touch the WaveのiPad版がほぼ完成に近づいたので、動画をあげてみました。来月くらいにはApp Storeに出せればいいかなと思っています。

iPhone版の現在の「Touch the Wave 2」では2曲同時再生やってたのですが、今回のiPad版では単純に1曲だけの単体のプレーヤーとして作ってます。やっぱりステレオ2系統出せないと本格的な用途には意味がないかなぁ、と思いまして。よりプロ用途を考えての選択です。

そのかわりiPadの広い画面を生かして、EQとDelayを付けてます。

テンポ算出はあいかわらずタップテンポです。BPMの自動検出とかやってみたかったんですけど、今のところ僕の力不足で実現に至ってません。研究の成果があらわれたら今後搭載するかもしれません。

あと、ピッチを変えずにスピード変える機能は要望を頂いたりしていたのですが、これもちょっと力不足ですね。iPad自体の力不足という面もあります。実際に実装してみた訳ではないですが、自分の満足のいく音質のタイムコンプは今のiPadのパワーでは無理なんじゃないかなという気がします。たしか「djay」ってアプリでもiPad2しかタイムコンプ使えないんですよね。とりあえずMacで研究を進めておいて、いずれ搭載出来るようになればいいなぁと思っています。

iOSのCore MIDI

iOSの勉強会用にCoreMIDIを調べてみたりしたのはいいものの、まだ発表する機会がなさそうなのと、気がつけば3ヶ月もブログを更新していなかったので、ちょっと書いておこうかなと思います。とりあえずこのエントリは、CoreMIDI対応アプリを開発する前の準備の話です。(※2011/7/26に内容を変更しています)

CoreMIDIはiPadだけ?

iOS 4.3.3より前のOSだと、外部とMIDIデータの送受信をできるのはiPadだけだったのですが、iOS 4.3.3以降だとiPhoneでもWi-fi経由でiPadと同じく使えるようになったようです。また、iPadではMIDIインターフェースをCamera Connection Kitにつなげれば使えたのですが、最近YAMAHAなどからドックに直接つなげるタイプのMIDIインターフェースが発売されましたので、iPhoneでもそれらをつかえばMIDIの送受信を実機だけで出来るようになりました。

デバッグはWi-Fiで!

MIDIインターフェースをドックに付けた状態だと、Macとつなげる事が出来ないので非常にデバッグがめんどくさいです。なので開発中はドックにつながず、iPhone/iPad(実機)とMacをWi-Fiで接続してWi-Fi経由でMIDIを送受信するようにした方が良いと思います。MacにMIDIインターフェースをつなげるのも良いですが、何かMIDIを送受信出来るアプリケーションがあれば別にMIDIインターフェースがなくても問題ありません。むしろ、いろいろなMIDIメッセージを送信出来るMacアプリケーションを作ってデバッグに活用する方が良いんじゃないでしょうか。

以下は、Macと実機をWi-Fi経由でMIDIの送受信をする接続方法を解説します。これはアプリの開発者に関わらず、MacのシーケンスソフトなどからiOSアプリの音をならしたい、でもケーブルでごちゃごちゃしたくないというユーザーの方にも参考になると思います。ですがWi-Fi経由だと、直接MIDIインターフェースをドックにつなげた場合と違って、それなりに発音の遅れや揺れがあると思いますのでご注意ください。

Wi-Fi経由のCore MIDIの接続方法

まず、実機になにかCoreMIDI対応アプリを入れておきましょう。何も持っていなければ無料の「Midi Monitor」あたりをダウンロードしておけば良いと思います(僕の環境ではしょっちゅう落ちるアプリですが…)。もちろん、自分のアプリを開発するときにはそれを立ち上げればいいので、それで。

Macと実機を同じWi-Fiネットワークに接続してください。Wi-Fiアクセスポイントがない場所でも、MacでAd-Hocネットワークを作成して接続する方法もありますので、わからない方は適当にぐぐってください。

Macの「Audio MIDI 設定」アプリケーションを起動して、「MIDI スタジオ」というウィンドウが開いていなければ、メニューのウィンドウの「MIDI ウィンドウを開く」を選択して開いてください。

MIDIスタジオのなかにネットワークというアイコンがありますのでダブルクリックして「MIDIネットワーク設定」というウィンドウを開きます。

CoreMIDI01.jpg

ウィンドウ左上の「自分のセッション」の「+」をクリックして、ネットワークセッションを作ります。

CoreMIDI03.jpg

おそらく「セッション1」という名前のセッションが出来ると思いますので、そこの左のボタンにチェックを入れます。

CoreMIDI04.jpg

実機側で、CoreMIDI対応のアプリを起動してください。実機では、アプリでMIDIClientを作成する事で自動的にネットワークセッションが作成されます。ちゃんと実機側のネットワークセッションがMacで認識されていれば、ウィンドウ左真ん中の「ディレクトリ」に実機の名前が表示されています。もし、CoreMIDI対応アプリを起動しても名前が現れない場合は、一度実機を再起動してみてからアプリを起動しなおすと良いかもしれません。

CoreMIDI05.jpg

実機の名前が現れたら選択して、下の「接続」ボタンをクリックしてください。接続に成功すれば、右側の「構成」のところに実機の名前が表示されているはずです。

CoreMIDI06.jpg

MacのMIDIアプリケーションからMIDIを送受信する場合は、この時点でMacアプリケーションのMIDIインやアウトでネットワークセッションを選択出来るようになっていると思いますので、Audio MIDI 設定での設定は以上です。

アプリケーションを使わずMIDIインターフェースと実機をつなげたい場合は、ウィンドウ右下のライブルーティングを使います。実機へMIDIメッセージを送りたいMIDIインターフェース(MIDI IN)を上のポップアップボタンで選択してください。逆に実機から送りたいMIDIインターフェース(MIDI OUT)は下のポップアップボタンで選択してください。(手元にUSB接続のMIDIキーボードしかなかったので、下のスクリーンショットではIN側だけ選択した状態です。)

CoreMIDI07.jpg

あとは実機アプリ側の設定ですが、MIDI INやOUTが選択出来るアプリであれば、「Network Session 1」というのがあるはずですので選択してください。そのような設定がないものはつながるものは全部つなげてしまう仕様になっていると思いますので、特に設定する必要はないと思います。

と、今回はこの辺で。

BigStopWatch HD v1.1.0 公開されました

BigStopWatch HD v1.1.0が公開されました。

変更点はカウントダウンで0秒を通過したときにサウンドを鳴らすようにしたことだけです。

他にもいろいろな操作に音を付ける事は試してみたのですが、結局うるさかったのでやめました。とりあえずはカウントダウンにだけ付けています。