Ticket #39799

iOS版 バックグラウンド演奏対応

Open Date: 2019-11-28 01:18 Last Update: 2019-12-01 01:28

Reporter:
Owner:
Status:
Closed
Priority:
5 - Medium
Severity:
5 - Medium
Resolution:
Fixed
File:
None

Details

バックグラウンド演奏に対応する。 MIDITrailで演奏中に、ホーム画面に戻ったり画面オフしたときに、演奏を継続できるようにする。

現状は演奏を停止するとともに、アプリ終了していた。

Ticket History (3/11 Histories)

2019-11-28 01:18 Updated by: yknk
  • New Ticket "iOS版 バックグラウンド演奏対応" created
2019-11-30 11:32 Updated by: yknk
Comment

対策1:プロジェクト設定

Targets / MIDITrail / General

Frameworks, Libraries, and Embedded Content に AVFoundation.framework を追加。

Targets / MIDITrail / Signing & Capabilities

Background Modes を追加。"Audio, AirPlay, and Picture in Picture"を選択状態にする。

MIDITrail-Info.plist

"Application does not run in background"をYESからNOに変更。

2019-11-30 11:39 Updated by: yknk
Comment

対策2:MIDITrailアプリケーションクラスの修正

MIDITrailAppDelegate::didFinishLaunchingWithOptions

引数の定義に、NSDictionaryのキー/値の型指定を追加。

MIDITrailAppDelegate::applicationDidBecomeActive

アクティブ状態遷移時に、アプリケーションオブジェクトに通知する処理を追加。

MIDITrailApp

メンバにオーディオセッション m_pAudioSession を追加。

MIDITrailApp::init

メンバのオーディオセッション m_pAudioSession の初期化処理を追加。

MIDITrailApp::initialize

オーディオセッション初期化呼び出し処理を追加。

MIDITrailApp::initializeNotification

オーディオセッション中断通知の受信設定を追加。

MIDITrailApp::onSelectFile

メインビュー表示処理の呼び出しで戻り値をチェックする処理を追加。

MIDITrailApp::onFinishCreateScene

メインビュー消去処理の呼び出しで戻り値をチェックする処理を追加。

MIDITrailApp::onCloseButton

メインビュー消去処理でオーディオセッションの非アクティブ化を行うため、 直前にシーケンサのMIDI出力デバイスクローズメソッド呼び出しを追加。 シーケンサは停止メソッドの呼び出しだけではデバイスをクローズしないため。 ライブモニタは停止メソッドの中でデバイスをクローズするため、ケアする必要がない。 メインビュー消去処理の呼び出しで戻り値をチェックする処理を追加。 シーケンサのstopメソッド内でスレッド終了待ちを行うように修正したため、0.1秒待ち合わせる処理を削除。 エラー発生時にアラートパネルを表示する処理を追加。

MIDITrailApp::onStartMonitoring

メインビュー表示処理の呼び出しで戻り値をチェックする処理を追加。

MIDITrailApp::onApplicationWillResignActive

演奏中であれば一時停止する処理を削除。

MIDITrailApp::onApplicationDidEnterBackground

演奏中であれば一時停止する処理を削除。 メインビューにバックグラウンド状態を通知する処理を追加。

MIDITrailApp::onApplicationDidBecomeActive

アクティブ状態遷移を通知してもらうためのメソッドを追加。 メインビューにバックグラウンド状態を通知する処理を追加。

MIDITrailApp::openMainView

オーディオセッションをアクティブ化する処理を追加。 戻り値をvoidからintに変更して、処理結果を返却できるようにする。

MIDITrailApp::closeMainView

オーディオセッションを非アクティブ化する処理を追加。 戻り値をvoidからintに変更して、処理結果を返却できるようにする。

MIDITrailApp::initAudioSession

オーディオセッション初期化メソッドを追加。

MIDITrailApp::

オーディオセッションアクティブ設定メソッドを追加。

MIDITrailApp::onAudioSessionInterruption

オーディオセッション中断通知メソッドを追加。 電話着信時やアラーム発生時に、演奏中だった場合は一時停止する。

2019-11-30 11:40 Updated by: yknk
Comment

対策3:メインビュー制御の修正

MTMainViewCtrl

メンバにバックグラウンド状態フラグ m_isBackground を追加。

MTMainViewCtrl::initWithNibName:bundle:rendererParam

メンバのバックグラウンド状態フラグの初期化処理を追加。

MTMainViewCtrl::drawScene

バックグラウンド状態の場合は描画処理をスキップする判定処理を追加。

MTMainViewCtrl::setBackground

バックグラウンド状態設定メソッドを追加。

2019-11-30 11:40 Updated by: yknk
Comment

対策4:MIDI出力デバイス制御の修正

SMOutDevCtrlEx::OpenPortDevAll

出力先ポートにWavetableシンセサイザが選択されているときだけ、 Wavetableシンセサイザのオープン処理を実施していたが、常に実施するように変更。 Wavetableシンセサイザがオープンされていないと(オーディオユニットが存在しないと)、 バックグランドに遷移した時点でスレッドがサスペンドされてしまい、演奏が停止してしまうため。 つまりCoreMIDIだけで演奏を行なっている場合、バックグラウンド演奏は実現できない。

2019-11-30 11:40 Updated by: yknk
Comment

対策5:シーケンサスレッドクラスの修正

MIDITrailApp::onCloseButton にて、シーケンサスレッド終了待ち直後にMIDIデバイスクローズ処理を追加した。 しかし0.1秒待ち合わせるだけで厳密なスレッド待ち処理を行なっていないため、 MIDIデバイスのクローズで問題が発生しないよう、確実にスレッド終了待ちを行うようにする。

SMSequencer::Pause

スレッド終了待機処理を追加。

SMSequencer::Stop

スレッド終了待機処理を追加。

SMSequencerThread

メンバに同期オブジェクト m_pCondition を追加。 メンバにスレッド実行中フラグ m_isExecuting を追加。

SMSequencerThread::init

同期オブジェクトの生成処理を追加。 スレッド実行中フラグの初期化処理を追加。

SMSequencerThread::dealloc

同期オブジェクトの破棄処理を追加。

SMSequencerThread::run

スレッド終了時に同期オブジェクトをシグナル状態にする処理を追加。 スレッド実行中フラグをON/OFFする処理を追加。

SMSequencerThread::waitFinish

スレッド終了待機メソッドを追加。

2019-11-30 11:41 Updated by: yknk
Comment

対策6:Wavetableシンセサイザ制御の修正

SMWavetableSynthCtrl

オーディオセッションのアクティブ化の前にサンプラーユニットのプロパティ設定を実施するように、 Wavetable読み込み処理のタイミングを変更する。

変更前
  Initialize -> _CreateAUGraph -> _InitSamplerUnits:サンプラーユニットのWavetable読み込みを実施
  Open -> _InitSamplerUnits:サンプラーユニットのWavetable読み込みを実施
変更後
  Initialize  -> _CreateAUGraph -> _InitSamplerUnits:サンプラーユニットのプロパティ設定を実施
  Open -> _SetupSamplerUnits:サンプラーユニットのWavetable読み込みを実施

SMWavetableSynthCtrl::Open

サンプラーユニット初期化処理の呼び出しを、セットアップ処理の呼び出しに変更。

SMWavetableSynthCtrl::_CreateAUGraph

サンプラーユニット初期化処理の呼び出しを追加。

SMWavetableSynthCtrl::_InitSamplerUnits

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::_SetupSamplerUnits

サンプラーユニットセットアップメソッドを追加。 SMWavetableSynthCtrl::_InitSamplerUnits からWavetable読み込み処理をこちらに移動。

2019-11-30 11:43 Updated by: yknk
Comment

対策7:ファイル一覧リフレッシュ機能追加

iTunesのファイル共有でMIDITrailのDocumentsフォルダにファイルをコピーしたとき、ファイル一覧を更新できるようにする。 これまでMIDITrailはバックグラウンドに遷移するとアプリは終了し、次回アプリを起動した時にファイル一覧を作成し直すことができた。 しかしバックグラウンドに遷移してもアプリが終了しなくなるため、ファイル一覧を作成し直すタイミングがない。 ファイル一覧ビューにリフレッシュ機能を追加し、テーブルビューを下に引き下げる操作で更新ができるようにする。

MTFileViewCtrl

メンバにリフレッシュ制御オブジェクト m_pRefreshCtrl を追加。

MTFileViewCtrl::viewDidLoad

リフレッシュ制御を生成し、テーブルビューに登録する処理を追加。

MTFileViewCtrl::makeFileCellForIndexPath

セルの詳細テキストラベルに空文字を設定する処理を追加。 ファイル一覧のリフレッシュで、ファイルなしからファイルありに切り替わった時、 "You can import your MIDI files through iTunes File Sharing."のテキストが 表示されたままにならないようにするため。

MTFileViewCtrl::refreshTable

リフレッシュ操作イベントハンドラを追加。ファイル一覧を更新する。

MTSettingBGIMGViewCtrl

メンバにリフレッシュ制御オブジェクト m_pRefreshCtrl を追加。

MTSettingBGIMGViewCtrl::viewDidLoad

リフレッシュ制御を生成し、テーブルビューに登録する処理を追加。

MTSettingBGIMGViewCtrl::makeFileCellForIndexPath

セルの詳細テキストラベルに空文字を設定する処理を追加。 ファイル一覧のリフレッシュで、ファイルなしからファイルありに切り替わった時、 "You can import your image files(*.jpg *.png) through iTunes File Sharing."のテキストが 表示されたままにならないようにするため。

MTSettingBGIMGViewCtrl::refreshTable

リフレッシュ操作イベントハンドラを追加。ファイル一覧を更新する。

MTSettingWavetableViewCtrl

メンバにリフレッシュ制御オブジェクト m_pRefreshCtrl を追加。

MTSettingWavetableViewCtrl::viewDidLoad

リフレッシュ制御を生成し、テーブルビューに登録する処理を追加。

MTSettingWavetableViewCtrl::refreshTable

リフレッシュ操作イベントハンドラを追加。ファイル一覧を更新する。

2019-11-30 11:43 Updated by: yknk
Comment

対策8:リファクタリング

SMWavetableSynthCtrl.mm

改行コードが混在していたため、LFに統一した。

SMWavetableSynthCtrl::_InitMixerUnit

macOS版の実装と合わせるため、ボリューム設定処理を追加。 iOSではボリューム設定なしでも音は出たが、macOSではデフォルト値がゼロのため音が出ず、 ボリューム設定の処理を追加していた。

2019-11-30 11:43 Updated by: yknk
  • Resolution Update from None to Fixed
  • Status Update from Open to Closed
2019-12-01 01:28 Updated by: yknk
Comment

対策9:MIDITrail-Info.plist 修正

アプリをリリースするため、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."

MIDITrail-Info.plist

"Application does not run in background"を削除した。(対策1でNOに変更した項目)

Attachment File List

No attachments

Edit

Please login to add comment to this ticket » Login