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)
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.