Platform SDK: DirectX |
IDirectMusicPerformance::SendPMsg メソッドは、パフォーマンス メッセージを送信する。このメソッドは、トラックの演奏時に呼び出される。ツールによって呼び出され、新しいデータをパフォーマンスに挿入する場合もある。
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 を呼び出す前に IDirectMusicGraph::StampPMsg メソッドをメッセージに対して呼び出すべきである。ただし、メッセージをメインの出力ツールへ直接送信する場合は、このステップを省略してもよい。メッセージをパフォーマンス グラフだけに渡したい場合は、IDirectMusicPerformance::QueryInterface を呼び出すことによって、IDirectMusicGraph インターフェイスを取得する。それ以外の場合は、IDirectMusicSegment::QueryInterface を呼び出すことによって、このインターフェイスを取得する。IDirectMusicPerformance::GetGraph または IDirectMusicSegment::GetGraph を呼び出してこのインターフェイスを取得しようとしないこと。これらのメソッドは、グラフ オブジェクトへのポインタを返すものであり、パフォーマンスまたはセグメントに対する IDirectMusicGraph インターフェイスの実装へのポインタは返さない。
パフォーマンスは通常、処理の終わったメッセージを解放する。詳細については、「IDirectMusicPerformance::FreePMsg」の「注意」を参照すること。
次のサンプル コードは、システム エクスクルーシブ メッセージとテンポ メッセージの割り当て方法と送信方法を示す。
/* pPerformance は有効な IDirectMusicPerformance ポインタであり、 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 ))) { // すべてのフィールドは、AllocPMsgAll メソッドから // 0 に初期化される。 // m_pbSysExData は、長さが m_dwSysExLength のデータを含む // 配列へのポインタであると仮定する。 memcpy( pSysEx->abData, m_pbSysExData, m_dwSysExLength ); pSysEx->dwSize = sizeof(DMUS_SYSEX_PMSG); pSysEx->dwLen = dwSysExLength; pSysEx->mtTime = mtTime; pSysEx->dwFlags = DMUS_PMSGF_MUSICTIME; pSysEx->dwType = DMUS_PMSGT_SYSEX; 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(IDirectMusicPerformance* 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; // DirectX 6.1 の場合は常に 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; }
Windows NT/2000 : Windows 2000 が必要。
Windows 95/98 : Windows 95 以降が必要。Windows 95 用に再配布可能な形で使用可能。
ヘッダー : dmusici.h で宣言。
IDirectMusicTool::ProcessPMsg、メッセージ、DirectMusic メッセージ、DirectMusic ツール