C++:Получение данных из MIDI-сообщения (DWORD)
Вопрос
Я написал простое MIDI-консольное приложение на C ++.Вот в чем дело в целом:
#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-сообщений с устройства. Вот описание этой функции в MSDN.На этой странице они говорят, что значение dwParam1
и dwParam2
указаны для типа сообщения (wMsg
), как MIM_DATA
.
Если я посмотрю документацию по MIM_DATA
, Я вижу , что это двойное слово (DWORD
?) и что в нем есть "высокое слово" и "низкое слово".Как я могу теперь получить такие данные, как имя элемента управления на MIDI-устройстве, которое отправило данные, и какое значение оно отправляет?
Я был бы признателен, если кто-нибудь сможет исправить мой код, если это можно сделать лучше.
Спасибо :)
Решение
Для доступа к данным вам необходимо использовать dwParam1
и dwParam2
и вызовите макросы HIWORD
и LOWORD
чтобы услышать от них высокие и низкие слова.Соответственно используйте HIBYTE
и LOBYTE
чтобы извлечь данные из этих слов.В случае MIM_DATA
, к сожалению, это MIDI-данные в байтовом кодировании, поэтому вам придется найти конкретные значения для них - они задокументированы здесь -- MIDI - Сообщения.
Однако в вашем коде есть потенциальная проблема - как мы читаем на страницах MSDN:
"Приложения не должны вызывать какие-либо мультимедийные функции изнутри функции обратного вызова, поскольку это может вызвать взаимоблокировку.Другая система функции можно безопасно вызывать из обратного вызова".
И вы вызываете PlaySound при обратном вызове...