Windows MCI (「Media Control Interface」) を使用して、特に MIDI および MP3 ファイルを再生するためのいくつかの基本的な C++ プログラムを作成しました。以前は Windows XP で完全に動作していました。最近、私は Windows 10 に移行し、現在は動作することもありますが (どのような状況かはわかりません)、ほとんどの場合、MP3 または MIDI ファイルを再生せずにすぐに終了します。奇妙なことに、エラー表示 (0 以外のリターン コード) が表示されません。関連するすべての呼び出しに MCI_WAIT オプションを含めるようにしました。プログラムはコマンド ライン プログラムであり、グラフィカルではありません。助けてください!
OK、これが PLAYSIM(PLE) コードの読みやすい形式です (申し訳ありませんが、stackoverflow はあまり使用しません)。メインラインは非常に基本的なものであることに注意してください。この実装のデバイスのタイプは、ファイル タイプから推測されます。ファイル タイプは常に驚くほど機能します (ファイル タイプが正しくないかサポートされていない場合は、「サイレント エラー」ではなく、メッセージが表示されます)。OPEN の前に CLOSE を置こうとしましたが、それは許可されていません。また、ある種の「MCI (再) 初期化呼び出し」を探しましたが、見つかりませんでした。以前は必要ありませんでした。
--->>> さらに単純なバージョンについては、最後を参照してください。そのバージョンは、どの Windows システムでも「コンパイル可能」である必要があります。
このバグを修正するように Microsoft に通知するにはどうすればよいですか???
// ╔══════════════════════════════════════════════╗
// ║..............................................║
// ║.┌────┐.┌┐.....┌────┐.┌┐..┌┐.┌────┐.┌┐.┌────┐.║
// ║.│┌──┐│.││.....│┌──┐│.││..││.│┌───┘.││.│┌┐┌┐│.║
// ║.│└──┘│.││.....│└──┘│.│└──┘│.│└───┐.││.││││││.║
// ║.│┌───┘.││.....│┌──┐│.└─┐┌─┘.└───┐│.││.││└┘││.║
// ║.││.....│└───┐.││..││...││...┌───┘│.││.││..││.║
// ║.└┘.....└────┘.└┘..└┘...└┘...└────┘.└┘.└┘..└┘.║ Reinier Bakels
// ║..............................................║ 17 January 2016
// ╚══════════════════════════════════════════════╝
/*
\borland\bcc55\include\.h
\borland\bcc55\include\mmsystem.h
\borland\bcc55\include\winbase.h
*/
#define NAME_COMMANDS
#include "\rbb\boilerpl.h"
#include "\rbb\dis.h"
#include "\rbb\print.h"
#include "\rbb\ps.h"
#include "\rbb\gct.h" // getCurrentTime()
#include <windows>
#include <mmsystem>
#include <io>
#ifdef NAME_COMMANDS
const char * commandNames[] = {
"" , // 0x0800
"" , // 0x0801
"" , // 0x0802
"Open" , // 0x0803
"Close" , // 0x0804
"Escape" , // 0x0805
"Play" , // 0x0806
"Seek" , // 0x0807
"Stop" , // 0x0808
"Pause" , // 0x0809
"Info" , // 0x080A
"GetDevCaps" , // 0x080B
"Spin" , // 0x080C
"Set" , // 0x080D
"Step" , // 0x080E
"Record" , // 0x080F
"Sysinfo" , // 0x0810
"Break" , // 0x0811
"" , // 0x0812
"Save" , // 0x0813
"Status" // 0x0814
};
#endif
DWORD mci( MCIDEVICEID devID , UINT uCmd , void * parms , DWORD options = 0 )
{
DWORD rc ;
#ifdef NAME_COMMANDS
fputs( commandNames[ uCmd - DRV_MCI_FIRST ] , stdout ); putchar(' ');
#endif
if ( rc = mciSendCommand( devID , uCmd , options , (DWORD) parms )) {
disint( rc );
TCHAR errorMessage[MAXERRORLENGTH];
if ( mciGetErrorString( rc , errorMessage , sizeof errorMessage )) {
CharToOem( errorMessage , errorMessage );
puts( errorMessage );
} else {
puts( "(unknown)" );
} /* endif */
} else {
puts( "OK.");
} /* endif */
return rc ;
}
int main( int argc , char ** argv )
{
boilerPlate();
if ( argc < 2 ) { puts("no arg."); return 0 ; }
char * fileName = *++argv ; disstr( fileName ); if ( access( fileName ,0 )) { say(File does not exist); return 0 ; }
MCI_OPEN_PARMS openParms = {0};
MCI_PLAY_PARMS playParms = {0};
MCI_GENERIC_PARMS genericParms = {0}; // only contains dwCallback
openParms.lpstrElementName = fileName ;
mci(0, MCI_OPEN , & openParms , MCI_WAIT | MCI_OPEN_ELEMENT ); // MCI_OPEN_SHAREABLE not allowed!
MCIDEVICEID devID = openParms.wDeviceID ; if ( devID != 1 ) dishex( devID ); // don't know why, but it seems to be always one
__int64 before = getCurrentTime();
if (! mci( devID, MCI_PLAY , & playParms , MCI_WAIT ))
printf( "\tcompleted with zero return code in %G seconds.\n", 1e-7f * ( getCurrentTime() - before ));
mci( devID, MCI_CLOSE , & genericParms );
return 0 ;
}
さらに簡単に:
// PLAYSIM even more simplified
#include <stdio>
#include <windows>
#include <mmsystem>
#include <io>
DWORD mci( const char * commandName , MCIDEVICEID devID , UINT uCmd , void * parms , DWORD options = 0 )
{
DWORD rc = mciSendCommand( devID , uCmd , options , (DWORD) parms );
fputs( commandName , stdout ); puts( rc ? " failed." : " OK." );
return rc ;
}
int main( int argc , char ** argv )
{
if ( argc < 2 ) { puts("no arg."); return 0 ; }
char * fileName = *++argv ; if ( access( fileName ,0 )) { puts( "File does not exist."); return 0 ; }
MCI_OPEN_PARMS openParms = {0};
MCI_PLAY_PARMS playParms = {0};
MCI_GENERIC_PARMS genericParms = {0}; // only contains dwCallback
openParms.lpstrElementName = fileName ;
mci( "Open ", 0 , MCI_OPEN , & openParms , MCI_WAIT | MCI_OPEN_ELEMENT );
mci( "Play " , openParms.wDeviceID , MCI_PLAY , & playParms , MCI_WAIT );
mci( "Close" , openParms.wDeviceID , MCI_CLOSE , & genericParms );
return 0 ;
}