1

I play an MP3 sound using the following mciSendString

mciSendString("play \"mysound.mp3\"", NULL, 0, 0);

The above works just fine. But from what I've seen around the web, people use all kinds of wrappers for the above code. Some first send open command then play, then wait for notification, then send close command, they also use aliases for files etc.

My question is - is all this necessary? My primary interest is just to play a file and do it in async manner. The above command appears to do all the cleanup so my question is - is it really required to use open or close command and notifications when the sound has been played to properly release memory and deallocate sound and is there an advantage to doing so.

From what I can see in the debugger it appears that on execution of above command the system loads required DLLs, then starts some threads and as soon as the playback ends, the threads exit and the DLLs are unloaded. So my guess is that open/close are optional because the system does all the allocation/deallocation automatically, but I may be wrong. Am I leaking some memory or resources if I just call the above line and nothing else?

Here is what the debug log shows - all I can conclude from this log that the thread is closed and that the the DLL files are unloaded:

Module Load: MCIQTZ32.dll. No Debug Info. Base Address: $61D80000. Process Project1.exe (368)
Thread Start: Thread ID: 492. Process Project1.exe (368)
Module Load: SETUPAPI.dll. No Debug Info. Base Address: $77920000. Process Project1.exe (368)
Module Unload: SETUPAPI.dll. Process Project1.exe (368)
Thread Start: Thread ID: 1344. Process Project1.exe (368)
Thread Start: Thread ID: 640. Process Project1.exe (368)
Thread Exit: Thread ID: 1344. Process Project1.exe (368)
Thread Exit: Thread ID: 640. Process Project1.exe (368)
Thread Start: Thread ID: 468. Process Project1.exe (368)
Thread Start: Thread ID: 1120. Process Project1.exe (368)
Module Load: SETUPAPI.dll. No Debug Info. Base Address: $77920000. Process Project1.exe (368)
Module Unload: SETUPAPI.dll. Process Project1.exe (368)
Thread Start: Thread ID: 1692. Process Project1.exe (368)
Thread Start: Thread ID: 1384. Process Project1.exe (368)
Thread Start: Thread ID: 204. Process Project1.exe (368)
Thread Start: Thread ID: 1572. Process Project1.exe (368)
Thread Exit: Thread ID: 1692. Process Project1.exe (368)
Thread Exit: Thread ID: 1384. Process Project1.exe (368)
Thread Exit: Thread ID: 1572. Process Project1.exe (368)
Thread Exit: Thread ID: 204. Process Project1.exe (368)
Thread Exit: Thread ID: 1120. Process Project1.exe (368)
Thread Exit: Thread ID: 468. Process Project1.exe (368)
Module Unload: MCIQTZ32.dll. Process Project1.exe (368)
Thread Exit: Thread ID: 492. Process Project1.exe (368)
Coder12345
  • 3,431
  • 3
  • 33
  • 73
  • Have you tried using `PlaySound()` instead? As long as a suitable MP3 driver is installed, it should play. And it has an `SND_ASYNC` flag available. – Remy Lebeau Jan 24 '14 at 19:12
  • I used it but it only works for WAV files on WinXP (without any additional drivers I cannot count on) while `mciSendString` works with MP3 with default XP installation. Async is not a problem, that works with mci as well. My main concern is releasing and cleaning up resources after use and does the mci do it automatically after the above command. – Coder12345 Jan 24 '14 at 19:40

1 Answers1

2

I found the answer elsewhere so I'm sharing it.

It appears that the play command by itself is perfectly valid.

So here are a couple of ways to call this:

// (a)
mciSendString("open waveaudio!MyFile.wav alias MyFile",NULL,0,0);
mciSendString("play MyFile wait",NULL,0,0);
mciSendString("close MyFile",NULL,0,0);

// (b)
mciSendString("open MyFile.wav alias MyFile",NULL,0,0);
mciSendString("play MyFile wait",NULL,0,0);
mciSendString("close MyFile",NULL,0,0);

// (c)
mciSendString("play MyFile.wav wait",NULL,0,0); // no open or alias used

Answer found on MSDN Forums.

Once important thing worth noting is thatmciSendString will fail miserably if you supply it with filename with spaces in the path (e.g. C:\Program Files...). Even if you enclose this into quotes it won't help. The solution is to use GetShortPathName Windows function to get a DOS-like path from NTFS path name and which doesn't have spaces in it.

Coder12345
  • 3,431
  • 3
  • 33
  • 73
  • It's actually a pain using aliases when dealing with ports other than the default when playing midi files. If the default port of 0 is opened already with `midioutopen`, mciSendString with _open_ & _alias_ arguments returns a `MCIERR_SEQ_PORT_INUSE`. – Laurie Stearn May 15 '17 at 06:12
  • to overcome filename with spaces put " " to enclose: mciSendString('PLAY "'+exepath+'\mytest.wav'+'"', 'nil', 0, 0); – Max Kleiner Aug 20 '21 at 07:58