0

I have written some basic C++ programs using the Windows MCI ("Media Control Interface"), notably for playing MIDI and MP3 files. They used to work perfectly on Windows XP. Recently I moved to Windows 10 and now they sometimes work (I have no clue under what conditions), but mostly they terminate immediately, without playing the MP3 or MIDI file. The strange thing is that I get no error indication (nonzero return code). I made sure to include the MCI_WAIT option on all pertinent calls. The programs are command line programs, not graphical. PLEASE HELP!

OK, here is the PLAYSIM(PLE) code in a better readable form (sorry I do not use stackoverflow very often). You will note that the mainline is extremely basic. The type of device in this implementation is inferred from the file type - which always worked marvelously (and an incorrect or unsupported file type causes a message, not a "silent failure"). I tried to precede the OPEN by a CLOSE but that is not allowed. I also looked for some sort of "MCI (re-)initialization call", but did not find it - and it was never needed before.

--->>> For an even simpler version see at the end. That version should be "compileable" on any Windows system.

How can I alert Microsoft to fix this bug???

// ╔══════════════════════════════════════════════╗
// ║..............................................║
// ║.┌────┐.┌┐.....┌────┐.┌┐..┌┐.┌────┐.┌┐.┌────┐.║
// ║.│┌──┐│.││.....│┌──┐│.││..││.│┌───┘.││.│┌┐┌┐│.║
// ║.│└──┘│.││.....│└──┘│.│└──┘│.│└───┐.││.││││││.║
// ║.│┌───┘.││.....│┌──┐│.└─┐┌─┘.└───┐│.││.││└┘││.║
// ║.││.....│└───┐.││..││...││...┌───┘│.││.││..││.║
// ║.└┘.....└────┘.└┘..└┘...└┘...└────┘.└┘.└┘..└┘.║ 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 ;
}

Yet simpler:

// 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 ;
}
  • Can you show your code? – selbie Jan 17 '16 at 06:31
  • MCI_OPEN_PARMS openParms = {0}; MCI_PLAY_PARMS playParms = {0}; MCI_GENERIC_PARMS genericParms = {0}; openParms.lpstrElementName = fileName ; mci(0, MCI_OPEN , & openParms , MCI_WAIT | MCI_OPEN_ELEMENT ); // MCI_OPEN_SHAREABLE not allowed! MCIDEVICEID devID = openParms.wDeviceID ; mci( devID, MCI_PLAY , & playParms , MCI_WAIT ); mci( devID, MCI_CLOSE , & genericParms ); return 0 ; } – Reinier Bakels Jan 17 '16 at 06:39
  • Hopefully the above code is readable. I have written this little program to concentrate on the essence. Meanwhile I found that the program fails once it is terminated by control break, and works again after the systems is restarted. So it appears that WIndows cleanup is not OK after an abnormal termination of the program. – Reinier Bakels Jan 17 '16 at 06:41
  • Reinier - Please post your code in your question, and not as a comment. And format it using appropriate markdown. (i.e. indent each code line with 4 spaces). Ideally, you post a minimal complete example (that someone can compile and debug without much effort). – selbie Jan 17 '16 at 06:48
  • I have don what you asked. Hope you find a clue! – Reinier Bakels Jan 17 '16 at 07:20

0 Answers0