/* The original version of this program can be found at http://damb.dk */
#include <windows.h>
#include <iostream>
#include <iomanip>
#include <fstream>
typedef struct
{
WAVEFORMATEX wfx;
WORD wID;
DWORD fdwFlags;
WORD nBlockSize;
WORD nFramesPerBlock;
WORD nCodecDelay;
}MPEGLAYER3WAVEFORMAT;
#define MPEGLAYER3_WFX_EXTRA_BYTES 12
#define WAVE_FORMAT_MPEGLAYER3 0x0055
#define SAMPLE_RATE 22050
#define MP3_BLOCK_SIZE 522
#define MPEGLAYER3_FLAG_PADDING_OFF 0x00000002
void CALLBACK CallBackProc(HWAVEOUT hwo, UINT uMsg, DWORD, DWORD dwParam1, DWORD)
{
if(uMsg == WOM_DONE)
{
MMRESULT MMResult;
WAVEHDR *WaveHeader = (WAVEHDR *)dwParam1;
if((MMResult = waveOutUnprepareHeader(hwo, WaveHeader, sizeof(WAVEHDR))) != MMSYSERR_NOERROR)
{
char Text[256];
waveOutGetErrorText(MMResult, Text, sizeof(Text));
std::cout << "Failed to unprepare: " << Text << std::endl;
}
free(WaveHeader->lpData);
}
}
bool PlayMP3(const char* aBuffer, int aSize)
{
HWAVEOUT WaveHandle;
WAVEHDR WaveHeader;
MMRESULT MMResult;
MPEGLAYER3WAVEFORMAT Mp3Format;
Mp3Format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
Mp3Format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
Mp3Format.wfx.nChannels = 1;
Mp3Format.wfx.nAvgBytesPerSec = 24 * 1024/8;
Mp3Format.wfx.wBitsPerSample = 0;
Mp3Format.wfx.nBlockAlign = 1;
Mp3Format.wfx.nSamplesPerSec = SAMPLE_RATE;
Mp3Format.fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
Mp3Format.nBlockSize = 144 * 24*1024/SAMPLE_RATE; //MP3_BLOCK_SIZE;
Mp3Format.nFramesPerBlock = 1;
Mp3Format.nCodecDelay = 1393;
Mp3Format.wID = 1;
if(waveOutOpen(&WaveHandle, WAVE_MAPPER, (WAVEFORMATEX *)&Mp3Format, (DWORD )CallBackProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
{
std::cerr << "Failed to open Wave!" << std::endl;
return false;
}
memset(&WaveHeader, 0, sizeof(WaveHeader));
aBuffer += 4; // Skip header for now
aSize -= 4;
WaveHeader.lpData = (char *)aBuffer;
WaveHeader.dwBufferLength = aSize;
WaveHeader.dwBytesRecorded = aSize;
WaveHeader.dwLoops = 1;
WaveHeader.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
if(waveOutPrepareHeader(WaveHandle, &WaveHeader, sizeof(WaveHeader)) != MMSYSERR_NOERROR)
{
std::cout << "Failed to prepare header!" << std::endl;
return false;
}
if((MMResult = waveOutWrite(WaveHandle, &WaveHeader, sizeof(WaveHeader))) != MMSYSERR_NOERROR)
{
char Text[256];
waveOutGetErrorText(MMResult, Text, sizeof(Text));
std::cout << "Failed to write: " << Text << std::endl;
return false;
}
while(!(WaveHeader.dwFlags & WHDR_DONE))
Sleep(100);
if((MMResult = waveOutClose(WaveHandle)) != MMSYSERR_NOERROR)
{
char Text[256];
waveOutGetErrorText(MMResult, Text, sizeof(Text));
std::cout << "Failed to close: " << Text << std::endl;
return false;
}
return true;
}
int main()
{
std::ifstream inFile("test.mp3", std::ios::binary);
if(inFile)
{
// Find the size of the file:
int size;
inFile.seekg(0, std::ios::end);
size = inFile.tellg();
inFile.seekg(0, std::ios::beg);
// read the data from the file
char *buffer = new char[size];
inFile.read(buffer, size);
PlayMP3(buffer, size);
delete [] buffer;
}
else
{
std::cout << "failed to open the file" << std::endl;
}
}