Microsoft DirectX 8.0 (C++) |
パフォーマンス メッセージを送信する。このメソッドは、トラックの演奏時に呼び出される。ツールによって呼び出され、新しいデータをパフォーマンスに挿入する場合もある。
HRESULT SendPMsg( DMUS_PMSG* pPMSG );
成功した場合は S_OK を返す。
失敗した場合は、次のいずれかのエラー値を返す。
DMUS_E_NO_MASTER_CLOCK |
DMUS_E_ALREADY_SENT |
E_INVALIDARG |
E_POINTER |
タイム スタンプが rtTime と mtTime のどちらになっているかに応じて、dwFlags メンバ (「DMUS_PMSG」を参照) は DMUS_PMSGF_MUSICTIME と DMUS_PMSGF_REFTIME のどちらかを含んでいなければならない。また、メッセージのタイプに応じて、dwFlags は DMUS_PMSGF_TOOL_QUEUE、DMUS_PMSGF_TOOL_ATTIME、または DMUS_PMSGF_TOOL_IMMEDIATE いずれかの適切な配信タイプを含んでいなければならない。どれも指定しない場合、デフォルトとして DMUS_PMSGF_TOOL_IMMEDIATE が使われる。
メッセージのタイムが 0 に設定され、dwFlags メンバが DMUS_PMSGF_REFTIME を含んでいる場合、このメッセージは即座に送り出すものとしてキューに挿入される。
ほとんどの場合は、SendPMsg を呼び出す前に IDirectMusicGraph8::StampPMsg メソッドをメッセージに対して呼び出すべきである。ただし、メッセージをメインの出力ツールへ直接送信する場合は、このステップを省略してもよい。パフォーマンス グラフからのみメッセージを渡す場合は、IDirectMusicPerformance8::QueryInterface を呼び出すことで、IDirectMusicGraph8 インターフェイスを取得する。それ以外の場合は、IDirectMusicSegment8::QueryInterface を呼び出すことによって、このインターフェイスを取得する。IDirectMusicPerformance8::GetGraph や IDirectMusicSegment8::GetGraph を呼び出すことで、インターフェイスを取得しようとしてはならない。これらのメソッドが返すのは、グラフ オブジェクトへのポインタであり、パフォーマンスやセグメントの IDirectMusicGraph8 インターフェイスの実装へのポインタではない。
パフォーマンスは通常、処理の終わったメッセージを解放する。詳細については、IDirectMusicPerformance8::FreePMsg の「注意」を参照すること。
次のサンプル コードは、システム エクスクルーシブ メッセージとテンポ メッセージの割り当て方法と送信方法を示している。
// pPerformance は有効な IDirectMusicPerformance8 ポインタであり、 mtTime は初期化済みの変数 MUSIC_TIME // であると仮定する。 IDirectMusicGraph* pGraph; // パフォーマンスからグラフ ポインタを取得する。セグメント グラフを使って // メッセージを渡す場合は、セグメント オブジェクトの代わりに // QueryInterface を使用する。 if ( SUCCEEDED( pPerformance->QueryInterface( IID_IDirectMusicGraph, (void**)&pGraph ))) { // 適切なサイズの DMUS_SYSEX_PMSG を割り当て、 // システム エクスクルーシブ データをそれに読み込ませる。 DMUS_SYSEX_PMSG* pSysEx; if ( SUCCEEDED( pPerformance->AllocPMsg( sizeof(DMUS_SYSEX_PMSG) + m_dwSysExLength, (DMUS_PMSG**)&pSysEx ))) { ZeroMemory(pSysEx, sizeof(DMUS_NOTE_PMSG)); pSysEx->dwSize = sizeof(DMUS_SYSEX_PMSG); pSysEx->dwLen = dwSysExLength; pSysEx->mtTime = mtTime; pSysEx->dwFlags = DMUS_PMSGF_MUSICTIME; pSysEx->dwType = DMUS_PMSGT_SYSEX; // m_pbSysExData は、長さが m_dwSysExLength のデータを保持する // 配列へのポインタであると仮定する。 memcpy( pSysEx->abData, m_pbSysExData, m_dwSysExLength ); pGraph->StampPMsg( (DMUS_PMSG*)pSysEx ); if (FAILED(pPerformance->SendPMsg( (DMUS_PMSG*)pSysEx ))) { pPerformance->FreePMsg( (DMUS_PMSG*)pSysEx ); } } // タイム mtTime のテンポを 120 bpm に変更する。 DMUS_TEMPO_PMSG* pTempo; if( SUCCEEDED( pPerformance->AllocPMsg( sizeof(DMUS_TEMPO_PMSG), (DMUS_PMSG**)&pTempo ))) { pTempo->dwSize = sizeof(DMUS_TEMPO_PMSG); pTempo->dblTempo = 120; pTempo->mtTime = mtTime; pTempo->dwFlags = DMUS_PMSGF_MUSICTIME; pTempo->dwType = DMUS_PMSGT_TEMPO; pGraph->StampPMsg( (DMUS_PMSG*)pTempo ); if (FAILED(pPerformance->SendPMsg( (DMUS_PMSG*)pTempo ))) { pPerformance->FreePMsg( (DMUS_PMSG*)pTempo ); } } pGraph->Release(); }
次のサンプル コードは、dwTrackID によって識別されるトラックに関連付けられたノートメッセージを送信する関数を示す。メッセージが DirectMusicTrack オブジェクトから生成されていない場合、仮想トラック ID は 0 でなければならない。
HRESULT CreateNotePMsg(IDirectMusicPerformance8* pPerformance, MUSIC_TIME mtTime, DWORD dwTrackID) { // Note PMessage を割り当てる。 DMUS_NOTE_PMSG* pNote = NULL; HRESULT hr = pPerformance->AllocPMsg( sizeof(DMUS_NOTE_PMSG), (DMUS_PMSG**) &pNote); if (FAILED(hr)) return hr; pNote->dwSize = sizeof(DMUS_NOTE_PMSG); // Note Pmessage のサイズ。 pNote->rtTime = 0; // 無視される。 pNote->mtTime = mtTime; // ノートの演奏タイム。 pNote->dwFlags = DMUS_PMSGF_MUSICTIME; // mtTime フィールドを使う。 pNote->dwPChannel = 5; // PChannel 5 で演奏する。 pNote->dwVirtualTrackID = dwTrackID; // パラメータからのトラック ID。 // 次の 2 つのフィールドは、メッセージを初めて送信するときに、 // NULL に設定しなければならない。これらのフィールドは、 // IDirectMusicGraph::StampPMsg で更新される。 pNote->pTool = NULL; pNote->pGraph = NULL; pNote->dwType = DMUS_PMSGT_NOTE; pNote->dwVoiceID = 0; // 常に 0。 pNote->dwGroupID = 0xFFFFFFFF; // すべてのトラック グループ。 pNote->punkUser = NULL; // 常に NULL。 // 現在の拍子記号をパフォーマンスから取得し、 // 小節と拍の情報を計算する。 DMUS_TIMESIGNATURE TimeSig; MUSIC_TIME mtNext; hr = pPerformance->GetParam(GUID_TimeSignature, 0xFFFFFFFF, 0, mtTime, &mtNext, &TimeSig); if (FAILED(hr)) return hr; // TimeSig.mtTime を再計算し、 // pPerformance->TimeToRhythm が予期する値を取得する。 TimeSig.mtTime += mtTime; // 現在のコードをパフォーマンスから取得し、 // ノートの値を作成する。 DMUS_CHORD_KEY Chord; hr = pPerformance->GetParam(GUID_ChordParam, 0xFFFFFFFF, 0, mtTime, &mtNext, &Chord); if (FAILED(hr)) return hr; // オクターブ 5、コード音 2 (5 度)、スケールを持つノートを作成する。 // オフセット 1 (=> 6 度)、変化音なし。 WORD wMusicValue = 0x5210; // DMUS_PLAYMODE_PEDALPOINT を // pPerformance->MusicToMIDI での演奏モードとして使う。 BYTE bPlayModeFlags = DMUS_PLAYMODE_PEDALPOINT; // DMUS_NOTE_PMSG に固有なフィールドを入力する。 pNote->wMusicValue = wMusicValue; hr = pPerformance->MusicToMIDI( wMusicValue, &Chord, bPlayModeFlags, 0, &(pNote->bMidiValue)); if (FAILED(hr)) return hr; hr = pPerformance->TimeToRhythm( TimeSig.mtTime, &TimeSig, &(pNote->wMeasure), &(pNote->bBeat), &(pNote->bGrid), &(pNote->nOffset)); if (FAILED(hr)) return hr; pNote->mtDuration = DMUS_PPQ; // 4 分音符の持続時間。 pNote->bVelocity = 120; // MIDI のベロシティ (0 〜 127)。 pNote->bFlags = DMUS_NOTEF_NOTEON; // 常にこの値に設定する。 pNote->bTimeRange = 250; // 開始タイムを大幅にランダム化する。 pNote->bDurRange = 5; // 持続時間をわずかにランダム化する。 pNote->bVelRange = 0; // ベロシティはランダム化しない。 pNote->bPlayModeFlags = bPlayModeFlags; pNote->bSubChordLevel = 0; // ノートはサブコード レベル 0 を使う。 pNote->cTranspose = 0; // 転調はない。 // メッセージにパフォーマンス グラフのスタンプを付ける。 IDirectMusicGraph* pGraph; hr = pPerformance->QueryInterface( IID_IDirectMusicGraph, (void**)&pGraph ); if (FAILED(hr)) return hr; pGraph->StampPMsg( (DMUS_PMSG*)pNote ); pGraph->Release(); // 最後にメッセージを送信する。 hr = pPerformance->SendPMsg( (DMUS_PMSG*)pNote); if (FAILED(hr)) { pPerformance->FreePMsg( (DMUS_PMSG*)pNote); return hr; } return S_OK; }
ヘッダー : dmusici.h で宣言。
IDirectMusicTool8::ProcessPMsg、メッセージ、DirectMusic メッセージ、DirectMusic ツール