-
mciSendString
Hi!
I'm using mciSendString function to play my .wav files. Now I tried to play .mp3's too but I get an error MCIERR_INTERNAL which is explained in the MSDN library like this "A problem occurred in initializing MCI. Try restarting the Windows operating".This error only happens when I want to play mp3's.
How to avoid this problem? And is there anything else that I should be aware of when using mciSendString function?
Thanks.
-
-
Please, help me with this problem!
-
What version of Windows are you running? The MCI interface will play MP3s, but only on versions 2000 & XP.
Also, you have to set the media type to 'autodetect'. I have never found a way to specify MP3 in the MCI interface, although I suspect it may be possible, it's undocumented.
Happy Christmas.
-
I have XP and 98. In XP the mp3's are not working and in 98 the wav's and mp3's are working but only the first time. If I run the wav play again it won't play. How do I set media type to autodetect?
Happy Christmas.
-
I'm away from my main computer, so I'm speaking from memory. Also, I've not used mciSendString, but have used mciSendCommand, which appears to be equivalent, but passes data structures instead of string commands.
>In XP the mp3's are not working
Mmm. Don't know why. Sorry.
>and in 98 the wav's and mp3's are working but only the first time
Are they mp3s working from your program? I always found my mci code wouldn't work with mp3 on 98/95 (return unrecognised media type error), but may be it's just an issue of having the right codec.
>If I run the wav play again it won't play.
Are you closing the wav media? I understand that it is not possible to play two wavs at the same time from the same process.
>How do I set media type to autodetect?
Don't know using mciSendString. But using the sendCommand version, there is a media type member in the MCI_OPEN data structure. You can specify the media type here, and there is also an 'autodetect' value. However, I've never found an MP3 value.
-
I don't close the media. How do I do that? I guess I have to open it too, right?
This is my code:
Code:
.
.
.
char Buffer[80] = {0}, ErrorMsg[128] = {0};
DWORD MCIError = 0;
sprintf (Buffer, "play %s", File);
MCIError = mciSendString (Buffer, 0, 0, 0);
if (MCIError != 0)
{
mciGetErrorString (MCIError, ErrorMsg, 128);
// temporary error checking
printf ("%s", ErrorMsg);
.
.
.
}
-
Normally with MCI you have to open the device before you can play, and then make sure you close it afterwards.
I'm not sure about your mciSendString code, because it doesn't seem to return an identifier for the device you have open. Had a (very) quick glance at MSDN with regard to mciSendString, but could find little on the string commands you should send.
Without reading up on mciSendString, I'm not sure I could help you further. May I suggest you use mciSendCommand instead, which (if nothing else) appears to be better documented. I could even send you some code I have written for this, if it would help.
-
I'll try to use mciSendCommand function and, please, post the code.
-
The following example should open any device. I have taken the code from the attached files, but have stripped it down to make it simpler. Note the lpstrElementName, which is used to specify the filename. Note that id of the device (which returned from by the MCI_OPEN call) is stored in a variable called pDevice, and is used on all subsequent calls to the open device. Also note, the MCI_WAIT flag, which will cause the mciSendCommand not to return until it has completed.
Notice that 'lpstrDeviceType = MCI_ALL_DEVICE_ID'. This will open anything, including movies (a window will be created for these if you don't specify one). You can specify specific devices if you wish, such as MCI_DEVTYPE_WAVEFORM_AUDIO (wave) or MCI_DEVTYPE_SEQUENCER (midi), but I do not know the specific type for mp3 (if anyone knows - please tell me), although MCI_ALL_DEVICE_ID seems to work for 2000 & XP.
I have also attached a C++ AudioPlayer class, which makes use of the code snippets below. The class holds the device id privately, and provides open, play, stop, pause methods etc. There is also a errStr() method to return a string describing the error (if any) caused by the last method called; it will return an empty string if there is no error. Any error is reset after each method call. Also note that the pause() method actually calls stop(), but stores the fact that it has been paused. This is to simulate pause, because the midi device does not support an MCI PAUSE command. Finally, I am using a string class called AnsiString. This is C++ Builder speak, but it should be easy to replace this with std:string or char* (also remove #include <vcl.h>).
Code:
// Device id
MCIDEVICEID pDevice = 0;
// Setup open params block
MCI_OPEN_PARMS op;
op.dwCallback = 0;
op.lpstrDeviceType = (char*)MCI_ALL_DEVICE_ID;
op.lpstrElementName = "C:\Filename.here";
op.lpstrAlias = 0;
// Send command
if ( mciSendCommand( 0, MCI_OPEN,
MCI_OPEN_ELEMENT | MCI_WAIT,
(DWORD)&op) == 0)
{
// Success on open
pDevice = op.wDeviceID;
}
else
{
// FAIL
}
The following will play an open device of id 'pDevice'
Code:
CI_PLAY_PARMS pp;
pp.dwCallback = 0;
if ( mciSendCommand(pDevice, MCI_PLAY, MCI_WAIT, (DWORD)&pp) == 0)
{
// SUCCESS
}
else
{
// FAIL
}
The following will stop a playing device, but will not close it.
Code:
MCI_GENERIC_PARMS gp;
gp.dwCallback = 0;
if (mciSendCommand(pDevice, MCI_STOP, MCI_WAIT, (DWORD)&gp) == 0);
{
// SUCCESS
}
else
{
// FAIL
}
And the following will close the device, after which the pDevice id is 'dead'.
Code:
MCI_GENERIC_PARMS gp;
gp.dwCallback = 0;
if ( mciSendCommand(pDevice, MCI_CLOSE, MCI_WAIT, (DWORD)&gp) == 0)
{
// SUCCESS
pDevice = 0;
}
else
{
// FAIL
}