gpt4 book ai didi

c - 为什么 MIDI 音序器在 Windows 10 上无法第二次播放

转载 作者:行者123 更新时间:2023-11-30 17:12:07 26 4
gpt4 key购买 nike

多年来,我一直使用 Windows 中的高级 MIDI 接口(interface)来播放 MIDI 文件作为游戏中的背景音乐。现在我从几个升级到Windows 10的人那里听说背景音乐将第一次播放(启动程序后),但是一旦完成,它就无法再次启动(或开始播放下一个MIDI文件) 。我自己还没有安装 Windows 10,但我已经组合了几个调试程序,当程序第二次尝试启动 MIDI 文件播放时,在 PlayMusic() 中调用:

mciSendCommand(MCIwDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms);

返回值 343 (MCIERR_SEQ_NOMIDIPRESENT)。但如果退出程序并再次启动,则可以使后台MIDI再次播放。

我有两个函数:PlayMusic(char *fname) 和 StopMusic(),它们用于启动和停止 MIDI 文件的播放,还有一个全局变量 MusicPlaying,用于跟踪音乐文件当前是否正在播放。然后,主窗口处理程序处理 MM_MCINOTIFY 消息,当收到 MCI_NOTIFY_SUCCESSFUL 时,它会向我的主代码排队通知音乐已完成,然后该主代码最终将再次调用(如果需要)PlayMusic()再次开始播放文件。以下是代码块(MusicPlaying 是知道 MIDI 文件是否处于事件状态的全局变量):

//*********************************************************
void StopMusic() {

if( MusicPlaying ) {
mciSendCommand(MCIwDeviceID, MCI_STOP, MCI_WAIT, 0);
mciSendCommand(MCIwDeviceID, MCI_CLOSE, MCI_WAIT, 0);
MusicPlaying = 0;
}
}

//**********************************************************************
void PlayMusic(char *pMem) {

MCIERROR dwReturn;

StopMusic(); // stop any previously playing music
// BuildPath() just adds the appropriate folder info for the file
BuildPath(pMem, DIR_MUSIC, FALSE);

// Open the device by specifying the device name and device element.
// MCI will attempt to choose the MIDI Mapper as the output port.
mciOpenParms.dwCallback = 0;
mciOpenParms.wDeviceID = 0;
mciOpenParms.lpstrDeviceType = "sequencer";//NULL;
mciOpenParms.lpstrElementName = (TCHAR *)TmpPath;
mciOpenParms.lpstrAlias = NULL;
dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_WAIT | MCI_OPEN_ELEMENT, (DWORD)(LPVOID) &mciOpenParms);
if( dwReturn ) return; // Failed to open device, bail out
// Begin playback. The window procedure function for the parent window
// will be notified with an MM_MCINOTIFY message when playback is
// complete. At that time, the window procedure closes the device.
MCIwDeviceID = mciOpenParms.wDeviceID;
mciPlayParms.dwCallback = (DWORD)(hWndMain);
dwReturn = mciSendCommand(MCIwDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms);
if( dwReturn ) { // if error
mciSendCommand(MCIwDeviceID, MCI_CLOSE, 0, 0); // close MCI device
return; // and bail out
}
MusicPlaying = 1;
}

在主窗口消息处理器中,当 MIDI 文件播放完毕时:

case MM_MCINOTIFY:
//***** SEE "NOTE" BELOW FOR DEBUG CODE INSERTED HERE *****
// various MIDI messages, we only care about termination
switch( wParam ) {
case MCI_NOTIFY_ABORTED: // value of 4
case MCI_NOTIFY_FAILURE:
case MCI_NOTIFY_SUPERSEDED:
break;
case MCI_NOTIFY_SUCCESSFUL: // value of 1
mciSendCommand(MCIwDeviceID, MCI_CLOSE, 0, 0);
MusicPlaying = 0;
AddMsg(KHDR_MUSIC_DONE, 0, 0, 0); // Queue msg that music finished
break;
default:
break;
}
return 0;

正常的事件顺序是:

Main game code calls PlayMusic() to start a MIDI playing
(Nothing in StopMusic() since nothing's playing first time)
MCI_OPEN
MCI_PLAY
MusicPlaying = 1;
MainWnd MM_MCINOTIFY MCI_NOTIFY_SUCCESSFUL when MIDI finished
MCI_CLOSE
MusicPlaying = 0;
queue KHDR_MUSIC_DONE msg to main game code
Main game code eventually sends another PlayMusic() command

如果某些原因导致主游戏代码过早停止音乐,那么它将调用 StopMusic() ,这将:

MCI_STOP
MCI_CLOSE
MusicPlaying = 0;

注意:(参见上面 MM_MCINOTIFY 中的“**** SEE 'NOTE'...”行)作为调试的一部分,我在此时插入了一个 MessageBox 调用以显示正在接收的通知。使用 Win 10 的用户看到的消息与我使用早期版本的 Windows 时看到的消息完全相同:发生 SUCCESSFUL 时 wParam=1 和 lParam=1,发生 ABORTED 时 wParam=4 和 lParam=1。但更关键的是:此时发生了 MessageBox,然后当用户在 MessageBox 上单击“确定”时,MIDI 文件就重新启动了!我的第一个想法是,消息框出现和被点击的时间延迟给了 MIDI 系统“重置”的时间。但进一步的测试,插入代码以将“MUSIC_DONE”消息的排队延迟 2 秒到我的主代码,对问题没有任何影响。所以看起来这可能与从我的主窗口到 MessageBox 窗口并返回的上下文切换有关,而不是任何时间延迟。

我发现一个网页讨论了 Windows 8 上 MIDI 系统发生的变化,这可能与它有关,除了我的 MIDI 播放代码似乎在播放第一个文件时没有遇到任何问题,它只是拒绝播放任何后续内容。该页面位于:

http://coolsoft.altervista.org/en/blog/2013/03/what-happened-midi-mapper-windows-8

我还听说另一个开发者的另一个游戏程序也有同样的问题:它会播放一次背景音乐,然后 MIDI 系统似乎打嗝。

那么,大问题:有谁知道需要做什么才能让 Windows 10 顺利播放连续的 MIDI 文件?

最佳答案

首先,我强烈建议您使用 Win 10 系统进行调试,即使它是在虚拟机中。由于Win 10是免费升级,所以这应该不成问题。

当您调用 mciSendCommand(..., MCI_CLOSE, ...) 时,请在第三个参数中指定 MCI_WAIT。 0 在这里无效。也许在 Win 10 上,这会导致您的代码不等待关闭完成。

关于c - 为什么 MIDI 音序器在 Windows 10 上无法第二次播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31797304/

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