ストアにオーディオ アプリがあります。iOS 4.0 より前のバージョンの iPhone OS では問題なく動作します。アプリを新しい iOS マルチタスク機能に準拠させることから始めて、新しいバージョンに取り組んでいます。(私の iPhone には iOS 4.0 があり、最新の xCode と SDK にアップグレードしました。)
結果はショーストッパーでした。
o iPhone にアプリをインストールしてデバッガーで実行するか、iPhone の電源を切った後にアプリを起動すると、アプリは問題なく動作します。アプリが前回実行された時間。
o ホーム ボタンを押してバックグラウンドからアプリを再起動しようとすると、オーディオ (a および 1-n オーディオ ストリームのミックス) が、私だけが認識できる途切れ途切れの音で出てきます。
o 音声がきれいなうちに iPhone に電話をかけた場合、電話に出るか拒否することができます。どちらの場合も、アプリは正常に戻り、正常に再生されます。
バックグラウンド モードでは何も再生しようとしていないことに注意してください。私は単に物事を止めて、尋ねられたら元に戻したいだけです。
テクノロジー: すべてのオーディオ ロジックは RemoteIO を使用します。(私はいつかかなり洗練された信号処理を行う計画を持っています。)
疑似コードの説明はご容赦ください。実際のコードの一部はかなり広範です。
MainViewController:
o viewDidLoad - 特別なことは何もありません
o didBecomeActive は、自分自身をオーディオ セッション デリゲートとして設定します。AudioSessionCategory を MediaPlayback に設定します。AudioSessionActive を設定します。プレーヤーを作成します (以下を参照)。以前に再生されていたサウンドを再開します。
o willResignActive 再生中の状態を保存します。stopAllSounds; プレーヤーを停止します。オーディオ セッションを非アクティブに設定します。
o didEnterBackground - なし (メソッドは登録されていますが、コンテンツはありません。)
o willEnterForeground - なし (メソッドは登録されていますが、コンテンツはありません。)
Player の概要 - 私のクラス: Player はシングルトンです。didBecomeActive で、シングルトン インスタンスが破棄され、新しいインスタンスが作成されていることを確認します。シングルトンをインスタンス化すると、実際に AudioUnit が開始されます。
コンストラクター setupRemoteIO; AudioOutputUnitStart を開始します。AudioOutputUnitStop を停止します。プレーヤーは通常のものをコールバックします。
>
ここに私の MainViewController からのいくつかのメソッドがあります:
(void)willResignActive:(NSNotification *)note {
[ self saveState ];
[ [ NaturePlayer getInstance ] stopAllSounds ];
[ [ NaturePlayer getInstance ] stop ];
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: NO error: &activationError];
[NaturePlayer destroy];
}
- (void)didBecomeActive:(NSNotification *)note {
[ self setupAudioSession ];
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
[ self restartSounds ];
[ self setViewState ];
}
- (void)didEnterBackground:(NSNotification *)note {
int xxx = 1;
}
- (void)willEnterForeground:(NSNotification *)note {
int xxx = 1;
}
- (void) applicationWillTerminate: (NSNotification*) notification {
int xxx = 1;
}
以下は NaturePlayer のメソッドです。
/**
* Stop the playback process.
*/
void NaturePlayerDelegate::stop() {
if (isPlaying_) {
AudioOutputUnitStop(outputUnit_);
isPlaying_ = FALSE ;
}
}
私はチェックしました:stop()が呼び出され、次にAudioOutputUnitStop()を呼び出します。またチェック: AudioOutputUnitStop のドキュメントには、すべてのアクティビティが完了するまでブロックすると書かれています。