#include #include WaveDevice::WaveDevice(UINT waveDeviceID,DeviceType waveDeviceType,Window &windowHandler) : mMMOpenHandler(this,&WaveDevice::mmOpenHandler), mMMCloseHandler(this,&WaveDevice::mmCloseHandler), mMMDoneHandler(this,&WaveDevice::mmDoneHandler), mWaveDeviceID(waveDeviceID), mDeviceType(waveDeviceType), mWindowHandler(windowHandler), mhWaveOut(0), mGlobalWaveHeader(1,GMEM_MOVEABLE) { getDeviceCapabilities(); insertHandlers(); } WaveDevice::WaveDevice(const WaveDevice &someWaveDevice) : mMMOpenHandler(this,&WaveDevice::mmOpenHandler), mMMCloseHandler(this,&WaveDevice::mmCloseHandler), mMMDoneHandler(this,&WaveDevice::mmDoneHandler), mWindowHandler(someWaveDevice.mWindowHandler), mhWaveOut(0), mGlobalWaveHeader(1,GMEM_MOVEABLE) { insertHandlers(); *this=someWaveDevice; } WaveDevice::~WaveDevice() { closeDevice(); removeHandlers(); } WORD WaveDevice::openDevice(WaveFormatPCM &waveFormatPCM) { MMRESULT mmResult; closeDevice(); mmResult=::waveOutOpen(&mhWaveOut,mWaveDeviceID,(LPWAVEFORMAT)&waveFormatPCM,(UINT)((HWND)mWindowHandler),0L,WAVE_ALLOWSYNC|CALLBACK_WINDOW); if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;} return TRUE; } WORD WaveDevice::closeDevice(void) { MMRESULT mmResult; if(!mhWaveOut)return FALSE; mmResult=::waveOutReset(mhWaveOut); if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;} mmResult=::waveOutClose(mhWaveOut); if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;} mhWaveOut=0; return TRUE; } WaveDevice &WaveDevice::operator=(const WaveDevice &someWaveDevice) { mWaveDeviceID=someWaveDevice.mWaveDeviceID; mDeviceType=someWaveDevice.mDeviceType; mWaveInCaps=someWaveDevice.mWaveInCaps; mWaveOutCaps=someWaveDevice.mWaveOutCaps; return *this; } void WaveDevice::insertHandlers(void) { mWindowHandler.insertHandler(VectorHandler::MMOpenHandler,&mMMOpenHandler); mWindowHandler.insertHandler(VectorHandler::MMCloseHandler,&mMMCloseHandler); mWindowHandler.insertHandler(VectorHandler::MMDoneHandler,&mMMDoneHandler); } void WaveDevice::removeHandlers(void) { mWindowHandler.removeHandler(VectorHandler::MMOpenHandler,&mMMOpenHandler); mWindowHandler.removeHandler(VectorHandler::MMCloseHandler,&mMMCloseHandler); mWindowHandler.removeHandler(VectorHandler::MMDoneHandler,&mMMDoneHandler); } WORD WaveDevice::play(WaveForm &someWaveForm,PlayMode playMode) { MMRESULT mmResult; WaveFormatPCM waveFormatPCM((FormatChunk&)someWaveForm); if(WaveFormat::PulseCodeModulation!=waveFormatPCM.formatTag()){genericErrorMessage(InvalidFormat);return FALSE;} if(!openDevice(waveFormatPCM))return FALSE; ((WaveHeader*)mGlobalWaveHeader)->setData((char*)(((PureSample&)someWaveForm).sampleData())); ((WaveHeader*)mGlobalWaveHeader)->setBufferLength(((PureSample&)someWaveForm).numSamples()); ((WaveHeader*)mGlobalWaveHeader)->userData((DWORD)this); mmResult=::waveOutPrepareHeader(mhWaveOut,(WAVEHDR*)((WaveHeader*)mGlobalWaveHeader),sizeof(WAVEHDR)); if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;} mmResult=::waveOutWrite(mhWaveOut,(WAVEHDR*)((WaveHeader*)mGlobalWaveHeader),sizeof(WAVEHDR)); if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;} if(Wait==playMode){while(mhWaveOut)yieldTask();} return TRUE; } void WaveDevice::yieldTask(void)const { MSG msg; if(::PeekMessage(&msg,0,0,0,PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } CallbackData::ReturnType WaveDevice::mmOpenHandler(CallbackData &/*someCallbackData*/) { return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType WaveDevice::mmCloseHandler(CallbackData &/*someCallbackData*/) { return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType WaveDevice::mmDoneHandler(CallbackData &someCallbackData) { WaveHeader &waveHeader(*((WaveHeader*)someCallbackData.lParam())); if(waveHeader.userData()==(DWORD)this) { ::waveOutUnprepareHeader((HWAVEOUT)someCallbackData.wParam(),(LPWAVEHDR)someCallbackData.lParam(),sizeof(WAVEHDR)); closeDevice(); } return (CallbackData::ReturnType)FALSE; }