在 Windows 中使用 MIDI 流时出现问题
Posted
技术标签:
【中文标题】在 Windows 中使用 MIDI 流时出现问题【英文标题】:Problem using MIDI streams in Windows 【发布时间】:2010-01-21 08:33:12 【问题描述】:我正在使用 C++ 和 Windows API 编写一个 Windows 程序,并且我试图在 MIDI 流中对 MIDI 消息进行排队,但是当我尝试这样做时收到一个奇怪的错误。如果我使用midiOutShortMsg
将非排队 MIDI 消息发送到流,它可以正常工作。但是,midiStreamOut
始终返回错误代码 68,即 #define
d 到 MCIERR_WAVE_OUTPUTUNSPECIFIED
。 midiOutGetErrorText
给出了以下错误描述:
当前的 MIDI 映射器设置是指系统上未安装的 MIDI 设备。使用 MIDI Mapper 编辑设置。
我使用的是 Windows 7(64 位)并尝试使用 MIDI_MAPPER 和我系统上所有四个 MIDI 输出设备的设备 ID 打开 MIDI 流,但仍然收到完全相同的错误消息。
这是打开 MIDI 流的代码:
UINT device_id = MIDI_MAPPER; //Also tried 0, 1, 2 and 3
midiStreamOpen( &midi, &device_id, 1, ( DWORD_PTR )hwnd, 0, CALLBACK_WINDOW );
这是发送 MIDI 消息的代码:
MIDIHDR header;
MIDIEVENT *event;
event = ( MIDIEVENT * )malloc( sizeof( *event ) );
event->dwDeltaTime = delta_time;
event->dwStreamID = 0;
event->dwEvent = ( MEVT_F_SHORT | MEVT_SHORTMSG ) << 24 | ( msg & 0x00FFFFFF );
header.lpData = ( LPSTR )event;
header.dwBufferLength = sizeof( *event );
header.dwBytesRecorded = sizeof( *event );
header.dwUser = 0;
header.dwFlags = 0;
header.dwOffset = 0;
midiOutPrepareHeader( ( HMIDIOUT )midi, &header, sizeof( header ) );
midiStreamOut( midi, &header, sizeof( header ) );
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:问题是我使用整个事件结构作为 MIDI 流的缓冲区。事实证明,结构的第四个成员,dwParms
,实际上应该从短消息中省略。要更正已发布问题中的代码,可以将其中两行代码更改为以下内容:
header.dwBufferLength = sizeof( *event ) - sizeof( event->dwParms );
header.dwBytesRecorded = sizeof( *event ) - sizeof( event->dwParms );
向流中添加多个事件时,实际上只使用 DWORD
s 的数组比使用 MIDIEVENT
结构要容易得多。
对于使用 Windows API 进行 MIDI 编程的其他任何人,请注意某些 MSDN 文档具有误导性、不充分或完全错误。
MIDIEVENT
结构的文档说明如下:
dwParms
如果 dwEvent 指定 MEVT_F_SHORT,请不要在流缓冲区中使用该成员。
这是模棱两可的,因为不清楚“使用”是指“包含”而不是“指定”。
以下是程序员需要注意的文档中的另外两个缺陷:
dw事件
事件代码和事件参数或长度。 [...] 该成员的高字节包含标志和事件代码。必须指定 MEVT_F_LONG 或 MEVT_F_SHORT 标志。 MEVT_F_CALLBACK 标志是可选的。
当检查头文件时,MEVT_F_
预处理器定义实际上指定了完整的DWORD
s 而不仅仅是单个标志,因此在我的问题代码中,指定此成员的行应该如下所示:
event->dwEvent = MEVT_F_SHORT | MEVT_SHORTMSG << 24 | ( msg & 0x00FFFFFF );
除此之外,还发现包含 MIDIHDR 结构的内存应该保留到缓冲区播放完毕,因此对于大多数实现来说,它应该分配在堆上而不是堆栈上。
【讨论】:
以上是关于在 Windows 中使用 MIDI 流时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
在 C 中通过串行/COM 端口发送 MIDI 数据时出现问题
UnicodeDecodeError:解析 Midi 文件时出现 Utf-8 解码错误
在 Windows 上安装 python-midi 包时出错
在 Ant Media Server 中使用 WebRTC 观看带有 B 帧的 rtmp 流时出现抖动问题