gpt4 book ai didi

c++ - 在 Windows 中使用 MIDI 流时出现问题

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

我正在使用 C++ 和 Windows API 编写一个 Windows 程序,并且试图在 MIDI 流中对 MIDI 消息进行排队,但是当我尝试这样做时收到一个奇怪的错误。如果我使用 midiOutShortMsg 将非排队的 MIDI 消息发送到流,它可以正常工作。但是,midiStreamOut 始终返回错误代码 68,这是 #defined 到 MCIERR_WAVE_OUTPUTUNSPECIFIEDmidiOutGetErrorText 给出了以下错误描述:

The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.

我正在使用 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 ) );

我该如何解决这个问题?

最佳答案

问题是我将整个事件结构用作 MIDI 流的缓冲区。事实证明,结构的第四个成员 dwParms 实际上应该从短消息中省略。要更正已发布问题中的代码,可以将其中两行代码更改为以下内容:

header.dwBufferLength = sizeof( *event ) - sizeof( event->dwParms );
header.dwBytesRecorded = sizeof( *event ) - sizeof( event->dwParms );

当向流中添加多个事件时,使用 DWORD 数组实际上比使用 MIDIEVENT 结构要容易得多。

对于使用 Windows API 进行 MIDI 编程的任何其他人,请注意某些 MSDN 文档具有误导性、不充分或完全错误。

MIDIEVENT 结构的文档说明如下:

dwParms

If dwEvent specifies MEVT_F_SHORT, do not use this member in the stream buffer.

这是模棱两可的,因为不清楚“使用”是指“包含”还是“指定”。

程序员需要注意文档中的另外两个缺陷:

dwEvent

Event code and event parameters or length. [...] The high byte of this member contains flags and an event code. Either the MEVT_F_LONG or MEVT_F_SHORT flag must be specified. The MEVT_F_CALLBACK flag is optional.

检查头文件时,MEVT_F_ 预处理器定义实际上指定了完整的 DWORD 而不仅仅是单个标志,因此在我的问题代码中,该行指定此成员应如下所示:

event->dwEvent = MEVT_F_SHORT | MEVT_SHORTMSG << 24 | ( msg & 0x00FFFFFF );

除此之外,还发现包含 MIDIHDR 结构的内存应该保留到缓冲区播放完毕,因此对于大多数实现来说,它应该分配在堆上而不是堆栈上。

关于c++ - 在 Windows 中使用 MIDI 流时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2107831/

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