2014年6月12日木曜日

AVAudioPlayerでハマった話。システム音も聞こえなくなった話など。

環境:iOS 7.1.1, XCode 5.1.1
状況:AVAudioPlayerがシステム音量ごと沈黙

AVAudioPlayerでBGMを鳴らそうとしていたところ、ある時からBGMの鳴るはずのタイミングで鳴らなくなってしまった。
しかもどうやらiOSの他の音声ごと無音になってしまっており、ボリュームボタンを押せどもサイレントスイッチを弄れども音は出ず。(画面上の表示は反応しています。)
実機だとイヤホンを抜き差しなどしてオーディオのルートを変更すると復帰する模様。
シミュレータだとアプリを落とすと復帰するけど、それまではMacのシステム音声も巻き込んで消える。
なにこれこわい。

結論から言うと AVAudioPlayer の volume プロパティの値が不正だったというオチ。

原因 :
AVAudioPlayer の volume プロパティにゼロ除算の結果の+INFを入れてしまった

直前にSpriteKitのバグ回避のためにオーディオセッションの設定を実装していたのでそのせいかと思い、新しく呼ぶようにした関数を全部潰しても治らない。
念のため既に実装を終わらせていたオーディオの再生部分を確認したら原因判明。
BGMのフェードインの実装の中、引数で与えられたdurationからフレーム毎の音量の増加値を計算している部分でゼロ除算してました。
その計算で引数が 0 の場合に +INF になった値をそのまま AVAudioPlayer の volume にイン。
結果、音量が振り切れてシステム音声ごとオーディオが落ちる状態に。
確かに同時期に「フェードイン無しの再生って duration が 0 のフェードインと同じだから云々・・・」とか自分で弄ってたの忘れてた・・・。
まぁともかく、原因が分かってよかったよかっt・・・。
よくない。

公式ドキュメントに「このプロパティは 0.0 から 1.0 までよ」って書いてあったけど。
今回の件、volume プロパティは inf だったから異常値として代入できてしまったのか、そもそもアクセサとかで検証はしてくれていないのか。
試しに値に「2.0」を入れてみる。
音が大きくなる。

・・・。(ゴクリ。)
よーし、ちょっと思い切って大きい値入れちゃおうかなー。具体的には INT32_MAX とか。

結果:音が割れる。

・・・おいィ?
認識できる数値だったらスケールの範囲に関係なく再生しちゃうのか。
例えば音量制限の延長で極端な値だとシステムがフェールセーフで落とすとかではない模様。
なにそれこわい。
MPVolumeView の volume プロパティは非推奨にしてるくせに、このおざなり感。

結論:バリデーションは自前で。

0 件のコメント :

コメントを投稿