> I thought mciSendCommand should play mp3's though?...
I can assure you that it does. Here's my full code. Header followed by cpp. I use Borland C++ Builder, hence the AnsiString type (an equivilent to STL string). It should be trivial to port this code to VC++.
Sorry for the long post, but hope this is helpful.
Code:
#ifndef audio_playerH
#define audio_playerH
#include <mmsystem.h>
//---------------------------------------------------------------------------
// CLASS AudioPlayer
//---------------------------------------------------------------------------
class AudioPlayer
{
private:
bool pPaused;
bool pErr;
char pErrStr[128];
MCIDEVICEID pDevice;
AnsiString pFileName;
bool open(const AnsiString& fName, int deviceType, bool playNow);
int setErrCode(int errCode);
void setErrStr(char* estr);
public:
AudioPlayer();
~AudioPlayer();
bool openWav(const AnsiString& fName, bool playNow = false);
bool openMp3(const AnsiString& fName, bool playNow = false);
bool openMidi(const AnsiString& fName, bool playNow = false);
AnsiString getFileName() const;
bool play();
void stop();
void close();
void pause();
int length();
int position();
bool isOpen();
bool playing();
bool paused();
bool err() const;
AnsiString errStr() const;
};
//---------------------------------------------------------------------------
#endif
Code:
#include <vcl.h> // This is a Borland include
#pragma hdrstop
#include "audio_player.h"
#include <sysutils.hpp>
#include <string.h>
//---------------------------------------------------------------------------
// CLASS AudioPlayer : PRIVATE METHODS
//---------------------------------------------------------------------------
bool AudioPlayer::open(const AnsiString& fName, int deviceType, bool playNow)
{
// Open new file
close();
if (!pErr)
{
MCI_OPEN_PARMS op;
op.dwCallback = NULL;
op.lpstrDeviceType = (char*)deviceType;
op.lpstrElementName = fName.c_str();
op.lpstrAlias = NULL;
int flags = 0;
if (deviceType != MCI_ALL_DEVICE_ID)
flags = MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID;
// Send command to
if ( setErrCode( mciSendCommand( NULL, MCI_OPEN,
MCI_OPEN_ELEMENT | MCI_WAIT | flags,
(DWORD)&op) ) == 0)
{
// Success on open - set time format to milliseconds
pDevice = op.wDeviceID;
pFileName = fName;
MCI_SET_PARMS sp;
sp.dwCallback = NULL;
sp.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
if ( setErrCode( mciSendCommand(pDevice, MCI_SET,
MCI_SET_TIME_FORMAT | MCI_WAIT, (DWORD)&sp) ) == 0)
{
if (playNow)
return play();
else
return true;
}
else
close();
}
}
return false;
}
//---------------------------------------------------------------------------
int AudioPlayer::setErrCode(int errCode)
{
// Set error code
if (errCode == 0)
{
pErr = false;
pErrStr[0] = '\0';
}
else
{
if (!mciGetErrorString(errCode, pErrStr, sizeof(pErrStr)))
strcpy(pErrStr, "Unknown media device error");
pErr = true;
}
return errCode;
}
//---------------------------------------------------------------------------
void AudioPlayer::setErrStr(char* estr)
{
// Set error string
if (estr == NULL)
{
pErr = false;
pErrStr[0] = '\0';
}
else
{
strcpy(pErrStr, estr);
pErr = true;
}
}
//---------------------------------------------------------------------------
// CLASS AudioPlayer : PUBLIC METHODS
//---------------------------------------------------------------------------
AudioPlayer::AudioPlayer()
{
// Constructor
pPaused = false;
setErrCode(0);
}
//---------------------------------------------------------------------------
AudioPlayer::~AudioPlayer()
{
// Destructor - stop playing
try
{
close();
}
catch(...)
{
}
}
//---------------------------------------------------------------------------
bool AudioPlayer::openWav(const AnsiString& fName, bool playNow)
{
// Open wave audio
return open(fName, MCI_DEVTYPE_WAVEFORM_AUDIO, playNow);
}
//---------------------------------------------------------------------------
bool AudioPlayer::openMp3(const AnsiString& fName, bool playNow)
{
// open mp3
return open(fName, MCI_ALL_DEVICE_ID, playNow);
}
//---------------------------------------------------------------------------
bool AudioPlayer::openMidi(const AnsiString& fName, bool playNow)
{
// Open midi
return open(fName, MCI_DEVTYPE_SEQUENCER, playNow);
}
//---------------------------------------------------------------------------
AnsiString AudioPlayer::getFileName() const
{
// Return open filename
return pFileName;
}
//---------------------------------------------------------------------------
bool AudioPlayer::play()
{
// Play current audio file or resume playing
if (pDevice != NULL)
{
if (pPaused)
{
// Play from current position
MCI_PLAY_PARMS pp;
pp.dwCallback = NULL;
if ( setErrCode( mciSendCommand(pDevice, MCI_PLAY, MCI_NOTIFY, (DWORD)&pp) ) == 0)
{
pPaused = false;
return true;
}
}
else
{
// Play file from start
stop();
if (!pErr)
{
MCI_PLAY_PARMS pp;
pp.dwCallback = NULL;
pp.dwFrom = 0;
if ( setErrCode( mciSendCommand(pDevice, MCI_PLAY, MCI_NOTIFY | MCI_FROM, (DWORD)&pp) ) == 0)
return true;
}
}
}
else
setErrStr("MCI audio device is closed");
return false;
}
//---------------------------------------------------------------------------
void AudioPlayer::stop()
{
// Stop playing (& rewind)
pPaused = false;
setErrCode(0);
if (pDevice != NULL)
{
MCI_GENERIC_PARMS gp;
gp.dwCallback = NULL;
setErrCode( mciSendCommand(pDevice, MCI_STOP, MCI_WAIT, (DWORD)&gp) );
}
}
//---------------------------------------------------------------------------
void AudioPlayer::close()
{
// Stop & reset filename
stop();
if (pDevice != NULL)
{
MCI_GENERIC_PARMS gp;
gp.dwCallback = NULL;
if ( setErrCode( mciSendCommand(pDevice, MCI_CLOSE, MCI_WAIT, (DWORD)&gp) ) == 0)
{
pFileName = "";
pDevice = NULL;
}
}
}
//---------------------------------------------------------------------------
void AudioPlayer::pause()
{
// Pause playing (by calling stop)
stop();
if (pErr == 0)
pPaused = true;
}
//---------------------------------------------------------------------------
int AudioPlayer::length()
{
// Get audio length in millisecs
setErrCode(0);
if (pDevice != NULL)
{
MCI_STATUS_PARMS sp;
sp.dwCallback = NULL;
sp.dwItem = MCI_STATUS_LENGTH;
if ( setErrCode( mciSendCommand(pDevice, MCI_STATUS,
MCI_WAIT | MCI_STATUS_ITEM, (DWORD)&sp) ) == 0)
return sp.dwReturn;
}
return -1;
}
//---------------------------------------------------------------------------
int AudioPlayer::position()
{
// Get audio position in millisecs
setErrCode(0);
if (pDevice != NULL)
{
MCI_STATUS_PARMS sp;
sp.dwCallback = NULL;
sp.dwItem = MCI_STATUS_POSITION;
if ( setErrCode( mciSendCommand(pDevice, MCI_STATUS,
MCI_WAIT | MCI_STATUS_ITEM, (DWORD)&sp) ) == 0)
return sp.dwReturn;
}
return -1;
}
//---------------------------------------------------------------------------
bool AudioPlayer::isOpen()
{
// Is audio file open
setErrCode(0);
return (pDevice != NULL);
}
//---------------------------------------------------------------------------
bool AudioPlayer::playing()
{
// Is audio playing
setErrCode(0);
if (pDevice != NULL)
{
MCI_STATUS_PARMS sp;
sp.dwCallback = NULL;
sp.dwItem = MCI_STATUS_MODE;
if ( setErrCode(mciSendCommand(pDevice, MCI_STATUS,
MCI_WAIT | MCI_STATUS_ITEM, (DWORD)&sp) ) == 0)
return (sp.dwReturn == MCI_MODE_PLAY);
}
return false;
}
//---------------------------------------------------------------------------
bool AudioPlayer::paused()
{
// Is audio paused
setErrCode(0);
return pPaused;
}
//---------------------------------------------------------------------------
bool AudioPlayer::err() const
{
// Was an error raised in the last operation
return pErr;
}
//---------------------------------------------------------------------------
AnsiString AudioPlayer::errStr() const
{
// Get error string
if (pErr)
return pErrStr;
else
return "";
}
//---------------------------------------------------------------------------