Platform SDK: DirectX

IDirectMusicPerformance::SendPMsg

IDirectMusicPerformance::SendPMsg メソッドは、パフォーマンス メッセージを送信する。このメソッドは、トラックの演奏時に呼び出される。ツールによって呼び出され、新しいデータをパフォーマンスに挿入する場合もある。

HRESULT SendPMsg(
  DMUS_PMSG* pPMSG
);

パラメータ

pPMSG
IDirectMusicPerformance::AllocPMsg によって割り当てられるメッセージ。

戻り値

成功すれば 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 ツール