C++:Получение данных из MIDI-сообщения (DWORD)

StackOverflow https://stackoverflow.com/questions/1982743

  •  22-09-2019
  •  | 
  •  

Вопрос

Я написал простое 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 при обратном вызове...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top