iOS版 バックグラウンド演奏対応
Frameworks, Libraries, and Embedded Content に AVFoundation.framework を追加。
Background Modes を追加。"Audio, AirPlay, and Picture in Picture"を選択状態にする。
"Application does not run in background"をYESからNOに変更。
引数の定義に、NSDictionaryのキー/値の型指定を追加。
アクティブ状態遷移時に、アプリケーションオブジェクトに通知する処理を追加。
メンバにオーディオセッション m_pAudioSession を追加。
メンバのオーディオセッション m_pAudioSession の初期化処理を追加。
オーディオセッション初期化呼び出し処理を追加。
オーディオセッション中断通知の受信設定を追加。
メインビュー表示処理の呼び出しで戻り値をチェックする処理を追加。
メインビュー消去処理の呼び出しで戻り値をチェックする処理を追加。
メインビュー消去処理でオーディオセッションの非アクティブ化を行うため、 直前にシーケンサのMIDI出力デバイスクローズメソッド呼び出しを追加。 シーケンサは停止メソッドの呼び出しだけではデバイスをクローズしないため。 ライブモニタは停止メソッドの中でデバイスをクローズするため、ケアする必要がない。 メインビュー消去処理の呼び出しで戻り値をチェックする処理を追加。 シーケンサのstopメソッド内でスレッド終了待ちを行うように修正したため、0.1秒待ち合わせる処理を削除。 エラー発生時にアラートパネルを表示する処理を追加。
メインビュー表示処理の呼び出しで戻り値をチェックする処理を追加。
演奏中であれば一時停止する処理を削除。
演奏中であれば一時停止する処理を削除。 メインビューにバックグラウンド状態を通知する処理を追加。
アクティブ状態遷移を通知してもらうためのメソッドを追加。 メインビューにバックグラウンド状態を通知する処理を追加。
オーディオセッションをアクティブ化する処理を追加。 戻り値をvoidからintに変更して、処理結果を返却できるようにする。
オーディオセッションを非アクティブ化する処理を追加。 戻り値をvoidからintに変更して、処理結果を返却できるようにする。
オーディオセッション初期化メソッドを追加。
オーディオセッションアクティブ設定メソッドを追加。
オーディオセッション中断通知メソッドを追加。 電話着信時やアラーム発生時に、演奏中だった場合は一時停止する。
メンバにバックグラウンド状態フラグ m_isBackground を追加。
メンバのバックグラウンド状態フラグの初期化処理を追加。
バックグラウンド状態の場合は描画処理をスキップする判定処理を追加。
バックグラウンド状態設定メソッドを追加。
出力先ポートにWavetableシンセサイザが選択されているときだけ、 Wavetableシンセサイザのオープン処理を実施していたが、常に実施するように変更。 Wavetableシンセサイザがオープンされていないと(オーディオユニットが存在しないと)、 バックグランドに遷移した時点でスレッドがサスペンドされてしまい、演奏が停止してしまうため。 つまりCoreMIDIだけで演奏を行なっている場合、バックグラウンド演奏は実現できない。
MIDITrailApp::onCloseButton にて、シーケンサスレッド終了待ち直後にMIDIデバイスクローズ処理を追加した。 しかし0.1秒待ち合わせるだけで厳密なスレッド待ち処理を行なっていないため、 MIDIデバイスのクローズで問題が発生しないよう、確実にスレッド終了待ちを行うようにする。
スレッド終了待機処理を追加。
スレッド終了待機処理を追加。
メンバに同期オブジェクト m_pCondition を追加。 メンバにスレッド実行中フラグ m_isExecuting を追加。
同期オブジェクトの生成処理を追加。 スレッド実行中フラグの初期化処理を追加。
同期オブジェクトの破棄処理を追加。
スレッド終了時に同期オブジェクトをシグナル状態にする処理を追加。 スレッド実行中フラグをON/OFFする処理を追加。
スレッド終了待機メソッドを追加。
オーディオセッションのアクティブ化の前にサンプラーユニットのプロパティ設定を実施するように、 Wavetable読み込み処理のタイミングを変更する。
変更前 Initialize -> _CreateAUGraph -> _InitSamplerUnits:サンプラーユニットのWavetable読み込みを実施 Open -> _InitSamplerUnits:サンプラーユニットのWavetable読み込みを実施 変更後 Initialize -> _CreateAUGraph -> _InitSamplerUnits:サンプラーユニットのプロパティ設定を実施 Open -> _SetupSamplerUnits:サンプラーユニットのWavetable読み込みを実施
サンプラーユニット初期化処理の呼び出しを、セットアップ処理の呼び出しに変更。
サンプラーユニット初期化処理の呼び出しを追加。
Wavetable読み込み処理を SMWavetableSynthCtrl::_SetupSamplerUnits に移動。 オーディオユニットにサンプルフレーム最大数 kAudioUnitProperty_MaximumFramesPerSlice を設定する処理を追加。 本プロパティは、バックグラウンド演奏に必要となる。
参考サイト
iOS background audio stops when screen is locked https://stackoverflow.com/questions/11085007/ios-background-audio-stops-when-screen-is-locked
サンプラーユニットセットアップメソッドを追加。 SMWavetableSynthCtrl::_InitSamplerUnits からWavetable読み込み処理をこちらに移動。
iTunesのファイル共有でMIDITrailのDocumentsフォルダにファイルをコピーしたとき、ファイル一覧を更新できるようにする。 これまでMIDITrailはバックグラウンドに遷移するとアプリは終了し、次回アプリを起動した時にファイル一覧を作成し直すことができた。 しかしバックグラウンドに遷移してもアプリが終了しなくなるため、ファイル一覧を作成し直すタイミングがない。 ファイル一覧ビューにリフレッシュ機能を追加し、テーブルビューを下に引き下げる操作で更新ができるようにする。
メンバにリフレッシュ制御オブジェクト m_pRefreshCtrl を追加。
リフレッシュ制御を生成し、テーブルビューに登録する処理を追加。
セルの詳細テキストラベルに空文字を設定する処理を追加。 ファイル一覧のリフレッシュで、ファイルなしからファイルありに切り替わった時、 "You can import your MIDI files through iTunes File Sharing."のテキストが 表示されたままにならないようにするため。
リフレッシュ操作イベントハンドラを追加。ファイル一覧を更新する。
メンバにリフレッシュ制御オブジェクト m_pRefreshCtrl を追加。
リフレッシュ制御を生成し、テーブルビューに登録する処理を追加。
セルの詳細テキストラベルに空文字を設定する処理を追加。 ファイル一覧のリフレッシュで、ファイルなしからファイルありに切り替わった時、 "You can import your image files(*.jpg *.png) through iTunes File Sharing."のテキストが 表示されたままにならないようにするため。
リフレッシュ操作イベントハンドラを追加。ファイル一覧を更新する。
メンバにリフレッシュ制御オブジェクト m_pRefreshCtrl を追加。
リフレッシュ制御を生成し、テーブルビューに登録する処理を追加。
リフレッシュ操作イベントハンドラを追加。ファイル一覧を更新する。
改行コードが混在していたため、LFに統一した。
macOS版の実装と合わせるため、ボリューム設定処理を追加。 iOSではボリューム設定なしでも音は出たが、macOSではデフォルト値がゼロのため音が出ず、 ボリューム設定の処理を追加していた。
アプリをリリースするため、Organizerでアップロードしたところ、次の警告が発生した。
App Store Connect Operation Warning WARNING ITMS-90339: "Deprecated Info.plist Key. The Info.plist contains a key 'UIApplicationExitsOnSuspend' in bundle MIDITrail [MIDITrail.app] that will soon be unsupported. Remove the key, rebuild your app and resubmit."
"Application does not run in background"を削除した。(対策1でNOに変更した項目)
バックグラウンド演奏に対応する。 MIDITrailで演奏中に、ホーム画面に戻ったり画面オフしたときに、演奏を継続できるようにする。
現状は演奏を停止するとともに、アプリ終了していた。