127 lines
4.0 KiB
C++
127 lines
4.0 KiB
C++
#include <sample/device.hpp>
|
|
#include <sample/waveform.hpp>
|
|
|
|
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;
|
|
}
|
|
|