ゲームのインタラクティブミュージックを作成する時、音楽のビートに関する情報が必要です。サウンドエンジンから、ミュージック通知を使用してこの情報を要求することができます。ビートは、再生中の主要な音楽セグメントによって決定されます。セグメントには様々な拍子があるので、再生中の音楽によってビートが変化します。再生中の音楽がない場合は、通知は行われません。
ミュージックコールバックには、以下の2種類がある。
音楽に関するマーカー通知を受信したい場合は、アプリケーションを設計する時に注意しなければならない特殊事項があります:
AK_MusicSyncBeat = 0x0100, // Enable notifications on Music Beat. AK_MusicSyncBar = 0x0200, // Music Bar の通知を有効にします。 AK_MusicSyncEntry = 0x0400, // Music Entry Point の通知を有効にします。 AK_MusicSyncExit = 0x0800, // Music Exit Point の通知を有効にします。 AK_MusicSyncGrid = 0x1000, // Music Grid の通知を有効にします。 AK_MusicSyncUserCue = 0x2000, // Music User Cue の通知を有効にします。 AK_MusicSyncPoint = 0x4000, // Music 同期ポイントの通知を有効にします。 AK_MusicSyncAll = 0xff00, // AK_MusicSync登録に関するすべての通知を受信する場合は、このフラグを使用します。
イベント終了時に通知を受信したい場合、フラグはビット単位の排他であるため、AK_EndOfEvent
| AK_MusicSyncBeat
を使用する必要があります。
AkPlayingID AK::SoundEngine::PostEvent( AkUniqueID in_eventID, // Unique ID of the event AkGameObjectID in_gameObjectID, // Associated game object ID AkUInt32 in_uFlags = 0, // Bitmask: see AkCallbackType AkCallbackFunc in_pfnCallback = NULL, // Callback function void * in_pCookie = NULL // Callback cookie that will be sent to the callback function // along with additional information );
static void MusicCallback( AkCallbackType in_eType, // Type of callback reason, in this case it could be AK_MusicSyncBeat AkCallbackInfo* in_pCallbackInfo // Pointer to callback information structure, in this case // AkMusicSyncCallbackInfo*. )
AK_MusicSyncBar
通知を処理したいだけであれば、他のイベントタイプを受信した場合には返す必要があります。in_pCallbackInfo
を型キャストすることができます。ミュージック通知の場合は、AkMusicSyncCallbackInfo です。/// Callback information structure corresponding to Ak_MusicSync struct AkMusicSyncCallbackInfo : public AkCallbackInfo { AkPlayingID playingID; ///< Playing ID of Event, returned by PostEvent() AkCallbackType musicSyncType; ///< Would be either AK_MusicSyncEntry, AK_MusicSyncBeat, AK_MusicSyncBar, AK_MusicSyncExit, AK_MusicSyncGrid, AK_MusicSyncPoint or AK_MusicSyncUserCue. AkReal32 fBeatDuration; ///< Beat Duration in seconds. AkReal32 fBarDuration; ///< Bar Duration in seconds. AkReal32 fGridDuration; ///< Grid duration in seconds. AkReal32 fGridOffset; ///< Grid offset in seconds. };
AK_MusicSyncBeat
と AK_MusicSyncBar
の両方に4/4拍子で登録すると、バーごとに4つのビート通知+バー自体でバー通知1つを受け取ることになります。"0" 拍子も1ビートおよび1バーと数えられ、ほとんどのケースで、AK_MusicSyncEntry
も同様です。よって、バー、ビート、エントリーポイントを登録した場合、音楽が開始すると3つのコールバックを連続して受け取ることになります。AK_MusicSyncExit
通知は、再生中セグメントの終端に到達した場合にのみ送信されます。再生中のセグメントが終了する前にに別のセグメントに音楽がスイッチする場合、現行の AK_MusicSyncExit
通知は送信されません。上記に示したコールバック関数で、ミュージック プレイリストの次のアイテムの選択を手作業での管理にも使用できます。これは次のフラグを追加することで実行できます。
AK_MusicPlaylistSelect = 0x0040 // Callback triggered when music playlist container must select the next item to play.
この種類のイベントを受け取った場合、コールバック関数はパラメーター in_pCallbackInfo
を、 AkMusicPlaylistCallbackInfo型へ型変換する必要があります。
/// Callback information structure corresponding to Ak_MusicPlaylistSelect struct AkMusicPlaylistCallbackInfo : public AkEventCallbackInfo { AkPlayingID playlistID; ///< ID of active node in music playlist container AkUInt32 uNumPlaylistItems; ///< Number of items in playlist node (may be segments or other playlists) AkUInt32 uPlaylistSelection; ///< Selection: set by sound engine, modified by callback function (if not in range 0 <= uPlaylistSelection < uNumPlaylistItems then ignored) AkUInt32 uPlaylistItemDone; ///< Playlist node done: set by sound engine, modified by callback function (if set to anything but 0 then the current playlist item is done, and uPlaylistSelection is ignored) };
アクティブなプレイリストノードは、数値 playlistID
が示します。サウンドエンジンは、コールバック関数の呼び出しの前に、プレイリストノードの次のアイテムを選択します。このセレクションは、 uPlaylistSelection
ならびに uPlaylistItemDone
の数値に含まれています。もし、uPlaylistItemDone
が 0 にセットさている場合には、 uPlaylistSelection
がプレイリストノードで再生する次のアイテムを決定します。もし、 uPlaylistItemDone
に 0 が設定されていない場合には、現在のプレイリストノードが終了します (親ノードがアクティブノードになりま)。uPlaylistSelection
ならびに uPlaylistItemDone
の両方の数値を、コールバック関数によって変更することができます。
通知は、バッファがハードウェアに引き継がれた時に送信されます。つまり、通知の送信時とその再生時の間に一定の遅延が起こります。この遅延により、アプリケーションは、マーカーに関する情報を収集し、マーカーと関連付けられたサウンドが実際に再生される前にこれを処理する余裕を得ることができます。
この遅延はプラットフォーム依存であることにご注意ください。
コールバックは、サウンドエンジンのメインスレッドから実行されます。つまり、アプリケーションは、必要な情報を通知から収集し、即時に返さなければなりません。なんらかの処理が必要な場合は、通知から関連情報がコピーされた後に別のスレッドで実行されなければなりません。
アプリケーションがスレッドを長く保持しすぎると、サウンドエンジンがアンダーラン状態に陥り、出力が再生を停止する可能性があります。