投稿

5月, 2013の投稿を表示しています

Audio Session細かいことまとめ

SessionActive化のタイミング
電話がかかってきて電話に出た時は、End Interruptionが呼ばれないそうなので、どこでSessionをActiveにするか、検討する必要がある。


割り込みのタイミング
アプリをバックグラウンドにしたときに音楽を再生していない場合は割り込みが入る(イニシャライズ時に指定した関数が走る)。再生している時は入らない。「何もしていないなら切りますよ」的なニュアンスで何かの処理が走る模様。割り込み関数が実際に走るのはフォアグラウンドにしたとき。begin分とend分の2回走る。

バックグラウンド機能のON OFFやmixWithOthersのON OFFも関係あります。

AVPlayerの割り込みメソッド呼び出しについて
AudioSessionのイニシャライズ時に指定する割り込みメソッドは再生中で無くても呼ばれるが、AVPlayerの割り込みメソッドはplay中でないと呼ばれない。(検証不十分)


AVPlayerの自動SessionActive機能について
AVPlayerには割り込み完了時にSessionActiveをYESにする機能があるのだが、この機能が少し癖があるので気を付けたい。
まずはいろいろなパターンを調べた。割り込みはiOSに付属しているアラームを使った。ちなみにタイマーだと1つしか登録できないが、アラームだと複数登録できる。

パターン1:初めにアラーム設定し、アプリを起動する
アラーム設定する
アプリ起動
AVPlayerインスタンス作成
セッション初期化
セッションアクティブ化
アラーム発生
アラーム処理(OKをタップ)
次のアラーム発生で割り込みメソッドが呼ばれない
自動でアクティブ化されない


パターン2:アプリを起動してから一旦バックグラウンドにして、アラーム設定し、再びアプリを起動する
アプリ起動
AVPlayerインスタンス作成
セッション初期化
セッションアクティブ化
アラーム設定する
アプリ起動
AVPlayerインスタンス作成(viewDidLoadに入れていたので再び処理が走った)
セッション初期化(viewDidLoadに入れていたので再び処理が走った)
セッションアクティブ化(viewDidLoadに入れていたので再び処理が走った)
アラーム発生
アラーム処理(OKをタップ)
次のアラ…

Affine行列の適用順序

イメージ
しょっちゅう忘れてしまうので…

基本
CGではAffine行列は3x3の行列で
a b 0
c d 0
tx ty 1
で表される。
この行列は元データである個々の座標に対して後ろから掛かり、適用後の座標を出す。
これは行列の中の移動を表すtx,tyの位置から明らか。

前から掛けると(行列)(縦表現座標)となり、結果は(ax+by,cx+dy,tx+ty+1)。これは求めたい結果ではない。
後ろから掛けると(横表現座標)(行列)となり、結果は(ax+cy+tx,bx+dy+ty,1)。こちらが求めたい結果。
ちなみに座標は(x,y,1)となる。最後の1は必要。

ということで
個々の座標データに行列を適用させるというのが行列の使われ方
座標に対して後ろから掛かる
という前程で進める。


複数の行列の適用順序
CGAffineTransform t = CGAffineTransformIdentity;
t = CGAffineTransformScale(t, 0.5, 2.0);
t = CGAffineTransformTranslate(t, 100.0, 100.0);
t = CGAffineTransformRotate(t, 1.0);

とプログラムを書いた場合、最終的な行列tは
(Rotate演算行列)(Translate演算行列)(Scale演算行列)
の結果となる。
つまり、行列追加関数は既存の行列の前に新しい行列を挿入する。
これが座標に後ろから掛かるので、個々の座標データにRotate演算、Translate演算、Scale演算の順に実行されたことと同じ結果(実際には先に適用行列の積が計算されていて、その結果を座標データに適用すると思う)。この順番は関数が書かれている順番と反対。

上のはCGAffineTransformの場合だが、
drawRect内でCGContextRefに行列を与える関数
CGContextScaleCTM(context, 0.5, 2.0);
CGContextTranslateCTM(context, 100,100);
CGContextRotateCTM(context, 1.0);
も同様の法則。

また、view.layerに与える行列の
CATransform3DScale(t, 0.5, 2.0, 1.0)…

C言語系のいろいろ

charを8ビットフルに正数として使う場合にunsignedは必要か
char型をint型に何かの理由でキャストするときにcharの最上位ビットが1だとマイナスの値のintになってしまう。
charは文字なんだから正数(と0)しか扱わない前程で処理してくれるかと早とちりすると危険。
NSLogやprintfの引数として渡すときに、値を見ようとして%dを使った時も同様。ちなみに%uにするとめちゃくちゃデカイ値が表示されてかなりわけのわからん状態になる。
iOSアプリの開発だとcharを使う機会はかなり少ないので見落としやすい。
また、unicharというのもあって、そっちはもとからunsignedで宣言されていて紛らわしい。
ということで正数と0のみの場合はcharでもunsignedは必要。