2009-12-30 70 views
4

我已經用C++編寫了一個簡單的MIDI控制檯應用程序。這是整個事情:C++:從MIDI信息中獲取數據(DWORD)

#include <windows.h> 
#include <iostream> 
#include <math.h> 
using namespace std; 
void CALLBACK midiInputCallback(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { 
switch (wMsg) { 
    case MIM_MOREDATA: 
    case MIM_DATA: 
    cout << dwParam1 << " "; 
    PlaySound("jingle.wav", NULL, SND_ASYNC | SND_FILENAME); 
    break; 
} 
} 
int main() { 
unsigned int numDevs = midiInGetNumDevs(); 
cout << numDevs << " MIDI devices connected:" << endl; 
MIDIINCAPS inputCapabilities; 
for (unsigned int i = 0; i < numDevs; i++) { 
    midiInGetDevCaps(i, &inputCapabilities, sizeof(inputCapabilities)); 
    cout << "[" << i << "] " << inputCapabilities.szPname << endl; 
} 
int portID; 
cout << "Enter the port which you want to connect to: "; 
cin >> portID; 
cout << "Trying to connect with the device on port " << portID << "..." << endl; 
LPHMIDIIN device = new HMIDIIN[numDevs]; 
int flag = midiInOpen(&device[portID], portID, (DWORD)&midiInputCallback, 0, CALLBACK_FUNCTION); 
if (flag != MMSYSERR_NOERROR) { 
    cout << "Error opening MIDI port." << endl; 
    return 1; 
} else { 
    cout << "You are now connected to port " << portID << "!" << endl; 
    midiInStart(device[portID]); 
} 
while (1) {} 
} 

你可以看到,有一個回調函數來處理來自設備的傳入MIDI消息。 Here is the description of this function on MSDN。在該頁面上,他們說dwParam1dwParam2的含義被指定爲消息類型(wMsg),如MIM_DATA

如果查找MIM_DATA的文檔,我可以看到它是一個雙字(DWORD?),它有一個「高位字」和「低位字」。現在我怎樣才能獲得數據,如發送數據的MIDI設備上的控件名稱以及它發送的值?

我將不勝感激,如果有人能糾正我的代碼,如果它可以做得更好。

謝謝:)

回答

5

要訪問你需要使用dwParam1dwParam2並調用宏HIWORDLOWORD從他們那裏得到的高和低字中的數據。分別使用HIBYTELOBYTE從這些單詞中獲取數據。在MIM_DATA的情況下,不幸的是這是字節編碼的MIDI數據,所以你必須找到那些的具體含義 - 這些記錄在這裏 - MIDI Messages

但是你的代碼有一個潛在的問題 - 正如我們在MSDN網頁閱讀:

「應用程序不應該從 回調函數內調用任何 多媒體功能,因爲這樣做可以 事業死鎖。其他系統 功能可以安全地從 調用回調「。

而你在回調調用PlaySound ...

+0

這真的很酷。 :)它的作品,沒想到它會那麼簡單! 並感謝您提供這樣快速和有益的答覆。 – Midas 2009-12-30 22:12:44

+0

感謝您關於'PlaySound'的說明。這只是一個嘗試,在那裏使用該功能,所以我仍然可以改變這一點。 – Midas 2009-12-31 09:28:30