Microsoft DirectX 8.0 (C++)

IDirectMusicPerformance8::SendPMsg

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

HRESULT SendPMsg(
  DMUS_PMSG* pPMSG
);

パラメータ

pPMSG
IDirectMusicPerformance8::AllocPMsg によって割り当てられたメッセージ。この構造体は、DMUS_PMSG の派生タイプである。「DirectMusic メッセージ」を参照すること。

戻り値

成功した場合は S_OK を返す。

失敗した場合は、次のいずれかのエラー値を返す。

DMUS_E_NO_MASTER_CLOCK
DMUS_E_ALREADY_SENT
E_INVALIDARG
E_POINTER

注意

タイム スタンプが rtTimemtTime のどちらになっているかに応じて、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::GetGraphIDirectMusicSegment8::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 ツール