gpt4 book ai didi

c - 使用 Windows MIDI API 时出现问题(播放时没有回调)

转载 作者:可可西里 更新时间:2023-11-01 14:44:25 25 4
gpt4 key购买 nike

我有一个 USB 连接的 MIDI 键盘。它在其他应用程序中工作正常。但是,在我自己的程序中却没有。 midiInOpen() 调用通过,我收到一个回调(来自打开设备),但在弹奏键盘时我没有收到任何回调。

通过使用 midiInGetDevCaps(),我可以看到我使用的是正确的设备。

有什么想法吗?其他(商业)应用程序可以使用其他一些 API 吗?

static void CALLBACK myFunc(HMIDIIN handle, UINT uMsg,
DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) {
printf("Callback!"\n);
}

int main() {

unsigned long result;
HMIDIIN inHandle;

result = midiInOpen(&inHandle, 0, (DWORD)myFunc, 0, CALLBACK_FUNCTION);
if (result)
{
printf("There was an error opening MIDI\n");
}

while(1) { Sleep(1); }
}

最佳答案

您需要调用midiInstart .您还需要发送消息。如果您调用 Sleep 而不是为输入提供服务,则不会发生任何事情。

这里有一点 tutorial on Windows MIDI .

这是我为 Win MIDI 输入编写的类 ( WinMidiIn ) 的摘录(删除了很​​多错误处理,类成员类型可以从它们作为参数传递给的调用中推断出来):

{
MMRESULT res = ::midiInOpen(&mMidiIn, mDeviceIdx, (DWORD_PTR)MidiInCallbackProc, (DWORD_PTR)this,
CALLBACK_FUNCTION | MIDI_IO_STATUS);
if (MMSYSERR_NOERROR != res)
return;

const int kDataBufLen = 512;
int idx;
for (idx = 0; idx < MIDIHDR_CNT; ++idx)
{
mMidiHdrs[idx].lpData = (LPSTR) ::malloc(kDataBufLen);
mMidiHdrs[idx].dwBufferLength = kDataBufLen;

res = ::midiInPrepareHeader(mMidiIn, &mMidiHdrs[idx], (UINT)sizeof(MIDIHDR));
res = ::midiInAddBuffer(mMidiIn, &mMidiHdrs[idx], sizeof(MIDIHDR));
}

res = ::midiInStart(mMidiIn);

for (;;)
{
DWORD result;
MSG msg;

// Read all of the messages in this next loop,
// removing each message as we read it.
while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// If it is a quit message, exit.
if (msg.message == WM_QUIT)
break;

// Otherwise, dispatch the message.
::DispatchMessage(&msg);
}

// Wait for any message sent or posted to this queue
// or for one of the passed handles be set to signaled.
result = ::MsgWaitForMultipleObjects(1, &mDoneEvent, FALSE, INFINITE, QS_ALLINPUT);

// The result tells us the type of event we have.
if (result == (WAIT_OBJECT_0 + 1))
{
// New messages have arrived.
// Continue to the top of the always while loop to
// dispatch them and resume waiting.
continue;
}
else if (WAIT_TIMEOUT == result)
continue;
else if (WAIT_OBJECT_0 == result)
break; // done event fired
else
break; // ??
}

res = ::midiInReset(mMidiIn);

for (idx = 0; idx < MIDIHDR_CNT; ++idx)
{
res = ::midiInUnprepareHeader(mMidiIn, &mMidiHdrs[idx], (UINT)sizeof(MIDIHDR));
::free(mMidiHdrs[idx].lpData);
mMidiHdrs[idx].lpData = NULL;
}

res = ::midiInClose(mMidiIn);
mMidiIn = NULL;
}



void CALLBACK
MidiInCallbackProc(HMIDIIN hmi,
UINT wMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2)
{
MMRESULT res;
LPMIDIHDR hdr;
WinMidiIn * _this = (WinMidiIn *) dwInstance;

switch (wMsg)
{
case MIM_DATA:
// dwParam1 is the midi event with status in the low byte of the low word
// dwParam2 is the event time in ms since the start of midi in
// data: LOBYTE(dwParam1), HIBYTE(dwParam1), LOBYTE(HIWORD(dwParam1))
break;
case MIM_ERROR:
break;
case MIM_LONGDATA:
// dwParam1 is the lpMidiHdr
// dwParam2 is the event time in ms since the start of midi in
hdr = (LPMIDIHDR) dwParam1;
// sysex: (byte*)hdr->lpData, (int)hdr->dwBytesRecorded
res = ::midiInAddBuffer(_this->mMidiIn, hdr, sizeof(MIDIHDR));
break;
case MIM_LONGERROR:
hdr = (LPMIDIHDR) dwParam1;
res = ::midiInAddBuffer(_this->mMidiIn, hdr, sizeof(MIDIHDR));
break;
}
}

关于c - 使用 Windows MIDI API 时出现问题(播放时没有回调),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5727215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com