DirectMusic之播放MIDI

DirectMusic之播放MIDI

DirectMusic主要用於播放midi數據,而且你無需寫分析器.DirectMusic自動完成所有操作,本.演示程式按ALT鍵彈出MENU再Open打開midi音檔.按+/-鍵控制音量.本想編譯X64版本卻出現『REGDB_E_CLASSNOTREG Class not registered.』所以只有x86程式下載:

DirectMusic是建基於DirectSound,不過DirectMusic會在Init()中自啟動它.DirectMusic是Dirext中第一個完全COM化組件,所以DirectMusic無需LIB庫.只需以下幾個頭文檔.

#include “..\DirectX\Include\dmplugin.h”

#include “..\DirectX\Include\dmksctrl.h”

#include “..\DirectX\Include\dmusici.h”

#include “..\DirectX\Include\dmusicc.h”

#include “..\DirectX\Include\dmusicf.h”

但安裝最新DXSDK安裝包(DX11),以上幾文件頭文件據然穩唔倒.我只可在舊版SDK拷貝過來工程文檔下.如果你把文檔拷貝到工程檔案下還需要小小修改#include <dmplugin.h>改為#include “dmplugin.h”

而編譯時DirectMusic有大量GUID無法鏈接.出現LNK2001下錯誤.

“錯誤  LNK2001        無法解析的外部符號 _CLSID_DirectMusicPerformance”

古計是從”dxguid.lib”刪除左.無需執著這些小問題.只要自已加上即可.你需要初此化GUID宏指令

#define INIT_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)   const GUID name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}

並把下面GUID複製到全域變量

INIT_GUID(CLSID_DirectMusicPerformance, 0xd2ac2881, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicSegment,     0xd2ac2882, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicSegmentState,0xd2ac2883, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicGraph,       0xd2ac2884, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicStyle,       0xd2ac288a, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicChordMap,    0xd2ac288f, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicComposer,    0xd2ac2890, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicLoader,      0xd2ac2892, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicBand,        0x79ba9e00, 0xb6ee, 0x11d1, 0x86, 0xbe, 0x0, 0xc0, 0x4f, 0xbf, 0x8f, 0xef);

INIT_GUID(GUID_Download,            0xd2ac28a7,0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(GUID_Unload,              0xd2ac28a8,  0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(GUID_StandardMIDIFile,    0x6621075, 0xe92e, 0x11d1, 0xa8, 0xc5, 0x0, 0xc0, 0x4f, 0xa3, 0x72, 0x6e);

INIT_GUID(GUID_DirectMusicAllTypes, 0xd2ac2893, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(GUID_PerfMasterVolume,    0xd2ac28b1, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicLoader, 0x2ffaaca2, 0x5dca, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);

INIT_GUID(IID_IDirectMusicGetLoader, 0x68a04844, 0xd13d, 0x11d1, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);

INIT_GUID(IID_IDirectMusicObject, 0xd2ac28b5, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicSegment, 0xf96029a2, 0x4282, 0x11d2, 0x87, 0x17, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicSegmentState, 0xa3afdcc7, 0xd3ee, 0x11d1, 0xbc, 0x8d, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xeb);

INIT_GUID(IID_IDirectMusicPerformance, 0x7d43d03, 0x6523, 0x11d2, 0x87, 0x1d, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicGraph, 0x2befc277, 0x5497, 0x11d2, 0xbc, 0xcb, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xeb);

INIT_GUID(IID_IDirectMusicStyle, 0xd2ac28bd, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicChordMap, 0xd2ac28be, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicComposer, 0xd2ac28bf, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicBand, 0xd2ac28c0, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicLoader8, 0x19e7c08c, 0xa44, 0x4e6a, 0xa1, 0x16, 0x59, 0x5a, 0x7c, 0xd5, 0xde, 0x8c);

INIT_GUID(IID_IDirectMusicPerformance8, 0x679c4137, 0xc62e, 0x4147, 0xb2, 0xb4, 0x9d, 0x56, 0x9a, 0xcb, 0x25, 0x4c);

INIT_GUID(IID_IDirectMusicSegment8, 0xc6784488, 0x41a3, 0x418f, 0xaa, 0x15, 0xb3, 0x50, 0x93, 0xba, 0x42, 0xd4);

INIT_GUID(IID_IDirectMusicSegmentState8, 0xa50e4730, 0xae4, 0x48a7, 0x98, 0x39, 0xbc, 0x4, 0xbf, 0xe0, 0x77, 0x72);

INIT_GUID(IID_IDirectMusicStyle8, 0xfd24ad8a, 0xa260, 0x453d, 0xbf, 0x50, 0x6f, 0x93, 0x84, 0xf7, 0x9, 0x85);

接口對像 簡介
IDirectMusic 你無需自已創建DirectMusic,因為她會自動創建
IDirectMusicPerformance 對MIDI播放進行控制,構建該對象時同時創建IDirectMusic
IDirectMusicLoader 用於加載音頻文檔,如MIDI.這樣你以擁有MIDI的載入器
IDirectMusicSegment Segment代表音樂數據塊
IDirectMusicSegmentState 數據塊狀態
IDirectMusicProt MIDI音樂輸出硬件設備.微軟合成器
IDirectMusic 擁有一個DSP(Digital Signal Processing)MIDI數字實時轉換器

下面是IDirectMusic播放MIDI代碼簡介:

1.首先你必須初此化COM

CoInitialize(NULL);

2.創建DirectMusicPerformance接口

IDirectMusicPerformance    *DirectMusic_Performance = NULL;

CoCreateInstance(CLSID_DirectMusicPerformance,NULL, CLSCTX_INPROC,             IID_IDirectMusicPerformance,(LPVOID*)&DirectMusic_Performance);

3.初此化 DirectMusicPerformance設置為audiopath,自動構建IDirectMusic和IDirectSound接口

DirectMusic_Performance->Init(NULL, NULL, hWnd);

4.增加數字輸出播放端口,使用微軟合成器作為默認設備

DirectMusic_Performance->AddPort(NULL);

5.創建MIDI載入器

IDirectMusicLoader  * DirectMusic_Loader = NULL;

CoCreateInstance(CLSID_DirectMusicLoader,NULL,CLSCTX_INPROC,                   IID_IDirectMusicLoader8,(LPVOID*)&DirectMusic_Loader);

6.你需要在初此化時設定音量

long volume = DMUS_VOLUME_MAX;

DirectMusic_Performance->SetGlobalParam(GUID_PerfMasterVolume, &volume, sizeof(long));

7.載入midi音檔. DirectMusic非常聰面.你只需給出『路徑』和『文檔名』即可完成MIDI載入

DMUS_OBJECTDESC objdesc;

memset(&objdesc, 0, sizeof(DMUS_OBJECTDESC));// 清零

objdesc.dwSize = sizeof(DMUS_OBJECTDESC);

objdesc.guidClass = CLSID_DirectMusicSegment;

objdesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME;

8.Utf8轉換為UNICODE寬字符

MultiByteToWideChar(CP_UTF8, NULL, filename, (int)strlen(filename), objdesc.wszFileName, DMUS_MAX_FILENAME);//文檔名

MultiByteToWideChar(CP_UTF8, NULL, category, (int)strlen(category), objdesc.wszCategory, DMUS_MAX_CATEGORY);//路徑

9.設置當前搜索目錄

hResult = DirectMusic_Loader->SetSearchDirectory(GUID_DirectMusicAllTypes, objdesc.wszCategory, false);

10.如果MIDI音檔編譯進資源文檔(resource)或者自已讀取MIDI音檔數據

objdesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_MEMORY;

objdesc.pbMemData = data;//指向midi數據

objdesc.llMemLength = size;// 數據長度

11.獲取IDirectMusicSegment音色庫接口,並自動載入midi數據

IDirectMusicSegment      * segment;

DirectMusic_Loader->GetObject(&objdesc,IID_IDirectMusicSegment,(void**)&segment);

12.指定音色庫segment

segment->SetParam(GUID_StandardMIDIFile,-1,0,0,DirectMusic_Performance);

13.將音色庫segment載入到IDirectMusicPerformance

segment->SetParam(GUID_Download, -1, 0, 0, DirectMusic_Performance);

14.設置循環播放

segment->SetRepeats(DMUS_SEG_REPEAT_INFINITE);

15.單次循環播放

midi->segment->SetRepeats(0);

16.終於可以播放MIDI音檔

IDirectMusicSegmentState * segstate;

DirectMusic_Performance->PlaySegment(segment,0,0, &segstate);

17.停止MIDI播放

DirectMusic_Performance->Stop(segment, NULL, 0, 0);

18.禦載DLS樂器段

segment->SetParam(GUID_Unload, -1, 0, 0, (void*)DirectMusic_Performance);

19.釋放指定MIDI音樂段.

segment->Release();

20.停止播放所有的MIDI音樂段

DirectMusic_Performance->Stop(NULL,NULL, 0, 0);

21.關閉IDirectMusicPerformance對像.

DirectMusic_Performance->CloseDown();

22.釋放IDirectMusicPerformance對像.

DirectMusic_Performance->Release();

23.釋放載入器.

DirectMusic_Loader->Release();

評論