Initial
This commit is contained in:
121
sample/hold/CHUNKID.HPP
Normal file
121
sample/hold/CHUNKID.HPP
Normal file
@@ -0,0 +1,121 @@
|
||||
#ifndef _SAMPLE_CHUNKID_HPP_
|
||||
#define _SAMPLE_CHUNKID_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_STRING_HPP_
|
||||
#include <common/string.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MEMFILE_HPP_
|
||||
#include <common/memfile.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_OPENFILE_HPP_
|
||||
#include <common/openfile.hpp>
|
||||
#endif
|
||||
|
||||
class ChunkID
|
||||
{
|
||||
public:
|
||||
ChunkID(void);
|
||||
ChunkID(const ChunkID &someChunkID);
|
||||
virtual ~ChunkID();
|
||||
ChunkID &operator=(const ChunkID &someChunkID);
|
||||
ChunkID &operator=(String chunkIDString);
|
||||
WORD operator==(const ChunkID &someChunkID)const;
|
||||
WORD operator==(const String &chunkIDString)const;
|
||||
MemFile &ChunkID::operator>>(MemFile &someMemFile)const;
|
||||
FileHandle &ChunkID::operator<<(FileHandle &someFileHandle);
|
||||
String chunkID(void)const;
|
||||
WORD size(void)const;
|
||||
String toString(void)const;
|
||||
private:
|
||||
enum {MaxLength=4};
|
||||
void initChunk(void);
|
||||
|
||||
char mChunkID[MaxLength];
|
||||
};
|
||||
|
||||
inline
|
||||
ChunkID::ChunkID(void)
|
||||
{
|
||||
initChunk();
|
||||
}
|
||||
|
||||
inline
|
||||
ChunkID::ChunkID(const ChunkID &someChunkID)
|
||||
{
|
||||
initChunk();
|
||||
*this=someChunkID;
|
||||
}
|
||||
|
||||
inline
|
||||
ChunkID::~ChunkID()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
ChunkID &ChunkID::operator=(const ChunkID &someChunkID)
|
||||
{
|
||||
::memcpy(mChunkID,someChunkID.mChunkID,sizeof(mChunkID));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
ChunkID &ChunkID::operator=(String chunkIDString)
|
||||
{
|
||||
if(chunkIDString.length()>sizeof(mChunkID))chunkIDString.length(sizeof(mChunkID));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD ChunkID::operator==(const ChunkID &someChunkID)const
|
||||
{
|
||||
return (!::memcmp(mChunkID,someChunkID.mChunkID,sizeof(mChunkID))?TRUE:FALSE);
|
||||
}
|
||||
|
||||
inline
|
||||
WORD ChunkID::operator==(const String &chunkIDString)const
|
||||
{
|
||||
return chunkID()==chunkIDString;
|
||||
}
|
||||
|
||||
inline
|
||||
MemFile &ChunkID::operator>>(MemFile &someMemFile)const
|
||||
{
|
||||
someMemFile.write((char*)mChunkID,sizeof(mChunkID));
|
||||
return someMemFile;
|
||||
}
|
||||
|
||||
inline
|
||||
FileHandle &ChunkID::operator<<(FileHandle &someFileHandle)
|
||||
{
|
||||
someFileHandle.read((BYTE*)mChunkID,sizeof(mChunkID));
|
||||
return someFileHandle;
|
||||
}
|
||||
|
||||
inline
|
||||
String ChunkID::chunkID(void)const
|
||||
{
|
||||
String chunkString;
|
||||
::memcpy(chunkString,mChunkID,sizeof(mChunkID));
|
||||
return chunkString;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD ChunkID::size(void)const
|
||||
{
|
||||
return sizeof(mChunkID);
|
||||
}
|
||||
|
||||
inline
|
||||
void ChunkID::initChunk(void)
|
||||
{
|
||||
::memset(mChunkID,0,sizeof(mChunkID));
|
||||
}
|
||||
|
||||
inline
|
||||
String ChunkID::toString(void)const
|
||||
{
|
||||
return String("<CHUNKID> ChunkID=")+String(mChunkID).quotes()+String("</CHUNKID>");
|
||||
}
|
||||
#endif
|
||||
8
sample/hold/DATACHNK.CPP
Normal file
8
sample/hold/DATACHNK.CPP
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <sample/datachnk.hpp>
|
||||
|
||||
FileHandle &DataChunk::operator<<(FileHandle &someFileHandle)
|
||||
{
|
||||
mChunkID<<someFileHandle;
|
||||
someFileHandle.read((BYTE*)&mLengthData,sizeof(mLengthData));
|
||||
return someFileHandle;
|
||||
}
|
||||
88
sample/hold/DATACHNK.HPP
Normal file
88
sample/hold/DATACHNK.HPP
Normal file
@@ -0,0 +1,88 @@
|
||||
#ifndef _SAMPLE_DATACHUNK_HPP_
|
||||
#define _SAMPLE_DATACHUNK_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MEMFILE_HPP_
|
||||
#include <common/memfile.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_OPENFILE_HPP_
|
||||
#include <common/openfile.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_CHUNKID_HPP_
|
||||
#include <sample/chunkid.hpp>
|
||||
#endif
|
||||
|
||||
class DataChunk
|
||||
{
|
||||
public:
|
||||
DataChunk(void);
|
||||
virtual ~DataChunk();
|
||||
MemFile &operator>>(MemFile &someMemFile)const;
|
||||
FileHandle &operator<<(FileHandle &someFileHandle);
|
||||
LONG length(void)const;
|
||||
void length(LONG length);
|
||||
DWORD size(void)const;
|
||||
String toString(void)const;
|
||||
private:
|
||||
void initChunk(void);
|
||||
ChunkID mChunkID;
|
||||
LONG mLengthData;
|
||||
};
|
||||
|
||||
inline
|
||||
DataChunk::DataChunk(void)
|
||||
{
|
||||
initChunk();
|
||||
}
|
||||
|
||||
inline
|
||||
DataChunk::~DataChunk()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
LONG DataChunk::length(void)const
|
||||
{
|
||||
return mLengthData;
|
||||
}
|
||||
|
||||
inline
|
||||
void DataChunk::length(LONG length)
|
||||
{
|
||||
mLengthData=length;
|
||||
}
|
||||
|
||||
inline
|
||||
MemFile &DataChunk::operator>>(MemFile &someMemFile)const
|
||||
{
|
||||
mChunkID>>someMemFile;
|
||||
someMemFile.write((char*)&mLengthData,sizeof(mLengthData));
|
||||
return someMemFile;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD DataChunk::size(void)const
|
||||
{
|
||||
return mChunkID.size()+sizeof(DWORD);
|
||||
}
|
||||
|
||||
inline
|
||||
void DataChunk::initChunk(void)
|
||||
{
|
||||
mChunkID=String("data");
|
||||
return;
|
||||
}
|
||||
|
||||
inline
|
||||
String DataChunk::toString(void)const
|
||||
{
|
||||
String strDataChunk;
|
||||
strDataChunk+=String("<DATACHUNK>");
|
||||
strDataChunk+=mChunkID.toString();
|
||||
strDataChunk+=String(" LengthData=")+String().fromInt(mLengthData).quotes();
|
||||
strDataChunk+=String("<DATACHUNK/>");
|
||||
return strDataChunk;
|
||||
}
|
||||
#endif
|
||||
|
||||
77
sample/hold/DEVHNDLR.CPP
Normal file
77
sample/hold/DEVHNDLR.CPP
Normal file
@@ -0,0 +1,77 @@
|
||||
#include <sample/devhndlr.hpp>
|
||||
#include <common/string.hpp>
|
||||
|
||||
void DeviceHandler::insertHandlers(void)
|
||||
{
|
||||
mWindowHandler.insertHandler(VectorHandler::MMOpenHandler,&mMMOpenHandler);
|
||||
mWindowHandler.insertHandler(VectorHandler::MMCloseHandler,&mMMCloseHandler);
|
||||
mWindowHandler.insertHandler(VectorHandler::MMDoneHandler,&mMMDoneHandler);
|
||||
}
|
||||
|
||||
void DeviceHandler::removeHandlers(void)
|
||||
{
|
||||
mWindowHandler.removeHandler(VectorHandler::MMOpenHandler,&mMMOpenHandler);
|
||||
mWindowHandler.removeHandler(VectorHandler::MMCloseHandler,&mMMCloseHandler);
|
||||
mWindowHandler.removeHandler(VectorHandler::MMDoneHandler,&mMMDoneHandler);
|
||||
}
|
||||
|
||||
void DeviceHandler::mmSystemErrorMessage(MMRESULT mmResult)const
|
||||
{
|
||||
String errorString;
|
||||
::waveOutGetErrorText(mmResult,(LPSTR)errorString,String::MaxString);
|
||||
message(errorString);
|
||||
}
|
||||
|
||||
void DeviceHandler::genericErrorMessage(ErrorCode errorCode)const
|
||||
{
|
||||
if(errorCode==InvalidFormat)message("Invalid Format.");
|
||||
else if(errorCode==InvalidDeviceHandle)message("Invalid Device Handle.");
|
||||
else if(errorCode==InvalidHeader)message("Invalid Header.");
|
||||
else message("Unknown Error.");
|
||||
return;
|
||||
}
|
||||
|
||||
WORD DeviceHandler::operator==(const DeviceHandler &/*someDeviceHandler*/)const
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CallbackData::ReturnType DeviceHandler::mmOpenHandler(CallbackData &someCallbackData)
|
||||
{
|
||||
openHandler(someCallbackData);
|
||||
return (CallbackData::ReturnType)FALSE;
|
||||
}
|
||||
|
||||
CallbackData::ReturnType DeviceHandler::mmCloseHandler(CallbackData &someCallbackData)
|
||||
{
|
||||
closeHandler(someCallbackData);
|
||||
return (CallbackData::ReturnType)FALSE;
|
||||
}
|
||||
|
||||
CallbackData::ReturnType DeviceHandler::mmDoneHandler(CallbackData &someCallbackData)
|
||||
{
|
||||
doneHandler(someCallbackData);
|
||||
return (CallbackData::ReturnType)FALSE;
|
||||
}
|
||||
|
||||
// virtuals
|
||||
|
||||
void DeviceHandler::openHandler(CallbackData &/*someCallbackData*/)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void DeviceHandler::closeHandler(CallbackData &/*someCallbackData*/)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void DeviceHandler::doneHandler(CallbackData &/*someCallbackData*/)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void DeviceHandler::message(const String &strErrorMessage)const
|
||||
{
|
||||
::MessageBox(::GetFocus(),(LPSTR)(String&)strErrorMessage,(LPSTR)"DeviceHandler",MB_OK);
|
||||
}
|
||||
70
sample/hold/DEVHNDLR.HPP
Normal file
70
sample/hold/DEVHNDLR.HPP
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef _SAMPLE_DEVICEHANDLER_HPP_
|
||||
#define _SAMPLE_DEVICEHANDLER_HPP_
|
||||
#ifndef _COMMON_WINDOW_HPP_
|
||||
#include <common/window.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MMSYSTEM_HPP_
|
||||
#include <common/mmsystem.hpp>
|
||||
#endif
|
||||
|
||||
class DeviceHandler
|
||||
{
|
||||
public:
|
||||
enum PlayMode{Wait,NoWait};
|
||||
DeviceHandler(Window &windowHandler);
|
||||
DeviceHandler(const DeviceHandler &someDeviceHandler);
|
||||
virtual ~DeviceHandler();
|
||||
WORD operator==(const DeviceHandler &someDeviceHandler)const;
|
||||
DeviceHandler &operator=(const DeviceHandler &someDeviceHandler);
|
||||
protected:
|
||||
enum ErrorCode{InvalidFormat,InvalidDeviceHandle,InvalidHeader};
|
||||
virtual void openHandler(CallbackData &someCallbackData);
|
||||
virtual void closeHandler(CallbackData &someCallbackData);
|
||||
virtual void doneHandler(CallbackData &someCallbackData);
|
||||
virtual void message(const String &strErrorMessage)const;
|
||||
void mmSystemErrorMessage(MMRESULT mmResult)const;
|
||||
void genericErrorMessage(ErrorCode errorCode)const;
|
||||
private:
|
||||
void insertHandlers(void);
|
||||
void removeHandlers(void);
|
||||
CallbackData::ReturnType mmOpenHandler(CallbackData &someCallbackData);
|
||||
CallbackData::ReturnType mmCloseHandler(CallbackData &someCallbackData);
|
||||
CallbackData::ReturnType mmDoneHandler(CallbackData &someCallbackData);
|
||||
Callback<DeviceHandler> mMMOpenHandler;
|
||||
Callback<DeviceHandler> mMMCloseHandler;
|
||||
Callback<DeviceHandler> mMMDoneHandler;
|
||||
Window &mWindowHandler;
|
||||
};
|
||||
|
||||
inline
|
||||
DeviceHandler::DeviceHandler(Window &windowHandler)
|
||||
: mWindowHandler(windowHandler)
|
||||
{
|
||||
mMMOpenHandler.setCallback(this,&DeviceHandler::mmOpenHandler);
|
||||
mMMCloseHandler.setCallback(this,&DeviceHandler::mmCloseHandler);
|
||||
mMMDoneHandler.setCallback(this,&DeviceHandler::mmDoneHandler);
|
||||
insertHandlers();
|
||||
}
|
||||
|
||||
inline
|
||||
DeviceHandler::DeviceHandler(const DeviceHandler &someDeviceHandler)
|
||||
: mWindowHandler(someDeviceHandler.mWindowHandler)
|
||||
{
|
||||
mMMOpenHandler.setCallback(this,&DeviceHandler::mmOpenHandler);
|
||||
mMMCloseHandler.setCallback(this,&DeviceHandler::mmCloseHandler);
|
||||
mMMDoneHandler.setCallback(this,&DeviceHandler::mmDoneHandler);
|
||||
insertHandlers();
|
||||
}
|
||||
|
||||
inline
|
||||
DeviceHandler::~DeviceHandler()
|
||||
{
|
||||
removeHandlers();
|
||||
}
|
||||
|
||||
inline
|
||||
DeviceHandler &DeviceHandler::operator=(const DeviceHandler &/*someDeviceHandler*/)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
126
sample/hold/DEVICE.CPP
Normal file
126
sample/hold/DEVICE.CPP
Normal file
@@ -0,0 +1,126 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
118
sample/hold/DEVICE.HPP
Normal file
118
sample/hold/DEVICE.HPP
Normal file
@@ -0,0 +1,118 @@
|
||||
#ifndef _SAMPLE_DEVICE_HPP_
|
||||
#define _SAMPLE_DEVICE_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_WINDOW_HPP_
|
||||
#include <common/window.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEOUTDEVICE_HPP_
|
||||
#include <sample/waveout.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEINDEVICE_HPP_
|
||||
#include <sample/wavein.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEHEADER_HPP_
|
||||
#include <sample/wavehdr.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEFORM_HPP_
|
||||
#include <sample/wave.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEFORMATPCM_HPP_
|
||||
#include <sample/pcmform.hpp>
|
||||
#endif
|
||||
|
||||
class WaveDevice
|
||||
{
|
||||
public:
|
||||
enum DeviceType{InputDevice,OutputDevice,InvalidDevice};
|
||||
enum PlayMode{Wait,NoWait};
|
||||
WaveDevice(UINT waveDeviceID,DeviceType waveDeviceType,Window &windowHandler);
|
||||
WaveDevice(const WaveDevice &someWaveDevice);
|
||||
~WaveDevice();
|
||||
WORD play(WaveForm &waveForm,PlayMode playMode=NoWait);
|
||||
WORD operator==(const WaveDevice &someWaveDevice)const;
|
||||
WaveDevice &operator=(const WaveDevice &someWaveDevice);
|
||||
void waveDeviceID(UINT deviceID);
|
||||
UINT waveDeviceID(void)const;
|
||||
void waveDeviceType(DeviceType waveDeviceType);
|
||||
DeviceType waveDeviceType(void)const;
|
||||
private:
|
||||
enum ErrorCode{InvalidFormat};
|
||||
void yieldTask(void)const;
|
||||
void getDeviceCapabilities(void);
|
||||
void insertHandlers(void);
|
||||
void removeHandlers(void);
|
||||
void mmSystemErrorMessage(MMRESULT mmResult)const;
|
||||
void genericErrorMessage(ErrorCode errorCode)const;
|
||||
WORD closeDevice(void);
|
||||
WORD openDevice(WaveFormatPCM &waveFormatPCM);
|
||||
CallbackData::ReturnType mmOpenHandler(CallbackData &someCallbackData);
|
||||
CallbackData::ReturnType mmCloseHandler(CallbackData &someCallbackData);
|
||||
CallbackData::ReturnType mmDoneHandler(CallbackData &someCallbackData);
|
||||
Callback<WaveDevice> mMMOpenHandler;
|
||||
Callback<WaveDevice> mMMCloseHandler;
|
||||
Callback<WaveDevice> mMMDoneHandler;
|
||||
UINT mWaveDeviceID;
|
||||
DeviceType mDeviceType;
|
||||
WaveInCaps mWaveInCaps;
|
||||
WaveOutCaps mWaveOutCaps;
|
||||
HWAVEOUT mhWaveOut;
|
||||
GlobalData<WaveHeader> mGlobalWaveHeader;
|
||||
Window &mWindowHandler;
|
||||
};
|
||||
|
||||
inline
|
||||
void WaveDevice::waveDeviceID(UINT deviceID)
|
||||
{
|
||||
mWaveDeviceID=deviceID;
|
||||
getDeviceCapabilities();
|
||||
}
|
||||
|
||||
inline
|
||||
UINT WaveDevice::waveDeviceID(void)const
|
||||
{
|
||||
return mWaveDeviceID;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveDevice::waveDeviceType(DeviceType waveDeviceType)
|
||||
{
|
||||
mDeviceType=waveDeviceType;
|
||||
getDeviceCapabilities();
|
||||
}
|
||||
|
||||
inline
|
||||
WaveDevice::DeviceType WaveDevice::waveDeviceType(void)const
|
||||
{
|
||||
return mDeviceType;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveDevice::getDeviceCapabilities(void)
|
||||
{
|
||||
if(mDeviceType==InputDevice)::waveInGetDevCaps(mWaveDeviceID,&((WAVEINCAPS&)mWaveInCaps),sizeof(mWaveInCaps));
|
||||
else if(mDeviceType==OutputDevice)::waveOutGetDevCaps(mWaveDeviceID,&((WAVEOUTCAPS&)mWaveOutCaps),sizeof(mWaveOutCaps));
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveDevice::operator==(const WaveDevice &someWaveDevice)const
|
||||
{
|
||||
return (mDeviceType==someWaveDevice.mDeviceType&&mWaveDeviceID==someWaveDevice.mWaveDeviceID);
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveDevice::mmSystemErrorMessage(MMRESULT mmResult)const
|
||||
{
|
||||
String errorString;
|
||||
::waveOutGetErrorText(mmResult,(LPSTR)errorString,String::MaxString);
|
||||
::MessageBox(::GetFocus(),(LPSTR)errorString,(LPSTR)"WaveDevice",MB_OK);
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveDevice::genericErrorMessage(ErrorCode errorCode)const
|
||||
{
|
||||
if(errorCode==InvalidFormat)::MessageBox(::GetFocus(),(LPSTR)"Invalid Format.",(LPSTR)"WaveDevice",MB_OK);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
166
sample/hold/FMTCHNK.HPP
Normal file
166
sample/hold/FMTCHNK.HPP
Normal file
@@ -0,0 +1,166 @@
|
||||
#ifndef _SAMPLE_FORMATCHUNK_HPP_
|
||||
#define _SAMPLE_FORMATCHUNK_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MMSYSTEM_HPP_
|
||||
#include <common/mmsystem.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MEMFILE_HPP_
|
||||
#include <common/memfile.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_OPENFILE_HPP_
|
||||
#include <common/openfile.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_FILEIO_HPP_
|
||||
#include <common/fileio.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_CHUNKID_HPP_
|
||||
#include <sample/chunkid.hpp>
|
||||
#endif
|
||||
|
||||
class FormatChunk
|
||||
{
|
||||
public:
|
||||
enum {WaveFormatPCM=0x01,NumChannels=0x01,BlockAlign=0x01,BitsPerSample=0x08};
|
||||
FormatChunk(void);
|
||||
FormatChunk(const FormatChunk &someFormatChunk);
|
||||
virtual ~FormatChunk();
|
||||
MemFile &operator>>(MemFile &someMemFile)const;
|
||||
FileHandle &operator<<(FileHandle &someFileHandle);
|
||||
FormatChunk &operator=(const FormatChunk &someFormatChunk);
|
||||
WORD formatTag(void)const;
|
||||
void formatTag(WORD formatTag);
|
||||
WORD channels(void)const;
|
||||
void channels(WORD channels);
|
||||
DWORD samplesPerSecond(void)const;
|
||||
void samplesPerSecond(DWORD samplesPerSecond);
|
||||
DWORD averageBytesPerSecond(void)const;
|
||||
void averageBytesPerSecond(DWORD averageBytesPerSecond);
|
||||
WORD blockAlign(void)const;
|
||||
void blockAlign(WORD blockAlign);
|
||||
WORD bitsPerSample(void)const;
|
||||
void bitsPerSample(WORD bitsPerSample);
|
||||
WORD size(void)const;
|
||||
String toString(void)const;
|
||||
private:
|
||||
void initChunk(void);
|
||||
ChunkID mChunkID;
|
||||
DWORD mSize;
|
||||
WORD mFormatTag;
|
||||
WORD mChannels;
|
||||
DWORD mSamplesPerSecond;
|
||||
DWORD mAvgBytesPerSecond;
|
||||
WORD mBlockAlign;
|
||||
WORD mBitsPerSample;
|
||||
WORD mExtraInfo;
|
||||
};
|
||||
|
||||
inline
|
||||
FormatChunk::FormatChunk(void)
|
||||
: mSize(0), mFormatTag(WaveFormatPCM), mChannels(NumChannels), mSamplesPerSecond(0),
|
||||
mAvgBytesPerSecond(0), mBlockAlign(BlockAlign), mBitsPerSample(0), mExtraInfo(0)
|
||||
{
|
||||
initChunk();
|
||||
}
|
||||
|
||||
inline
|
||||
FormatChunk::FormatChunk(const FormatChunk &someFormatChunk)
|
||||
: mSize(0), mFormatTag(WaveFormatPCM), mChannels(NumChannels), mSamplesPerSecond(0),
|
||||
mAvgBytesPerSecond(0), mBlockAlign(BlockAlign), mBitsPerSample(0), mExtraInfo(0)
|
||||
{
|
||||
initChunk();
|
||||
*this=someFormatChunk;
|
||||
}
|
||||
|
||||
inline
|
||||
FormatChunk::~FormatChunk()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
WORD FormatChunk::formatTag(void)const
|
||||
{
|
||||
return mFormatTag;
|
||||
}
|
||||
|
||||
inline
|
||||
void FormatChunk::formatTag(WORD formatTag)
|
||||
{
|
||||
mFormatTag=formatTag;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD FormatChunk::channels(void)const
|
||||
{
|
||||
return mChannels;
|
||||
}
|
||||
|
||||
inline
|
||||
void FormatChunk::channels(WORD channels)
|
||||
{
|
||||
mChannels=channels;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD FormatChunk::samplesPerSecond(void)const
|
||||
{
|
||||
return mSamplesPerSecond;
|
||||
}
|
||||
|
||||
inline
|
||||
void FormatChunk::samplesPerSecond(DWORD samplesPerSecond)
|
||||
{
|
||||
mSamplesPerSecond=samplesPerSecond;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD FormatChunk::averageBytesPerSecond(void)const
|
||||
{
|
||||
return mAvgBytesPerSecond;
|
||||
}
|
||||
|
||||
inline
|
||||
void FormatChunk::averageBytesPerSecond(DWORD averageBytesPerSecond)
|
||||
{
|
||||
mAvgBytesPerSecond=averageBytesPerSecond;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD FormatChunk::blockAlign(void)const
|
||||
{
|
||||
return mBlockAlign;
|
||||
}
|
||||
|
||||
inline
|
||||
void FormatChunk::blockAlign(WORD blockAlign)
|
||||
{
|
||||
mBlockAlign=blockAlign;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD FormatChunk::bitsPerSample(void)const
|
||||
{
|
||||
return mBitsPerSample;
|
||||
}
|
||||
|
||||
inline
|
||||
void FormatChunk::bitsPerSample(WORD bitsPerSample)
|
||||
{
|
||||
mBitsPerSample=bitsPerSample;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD FormatChunk::size(void)const
|
||||
{
|
||||
return mSize+mChunkID.size();
|
||||
}
|
||||
|
||||
inline
|
||||
void FormatChunk::initChunk(void)
|
||||
{
|
||||
mChunkID=String("fmt ");
|
||||
mSize=(mChunkID.size()+sizeof(mSize)+sizeof(mFormatTag)+sizeof(mChannels)+sizeof(mSamplesPerSecond)+
|
||||
sizeof(mAvgBytesPerSecond)+sizeof(mBlockAlign)+sizeof(mBitsPerSample))-(mChunkID.size()+sizeof(mSize));
|
||||
}
|
||||
#endif
|
||||
100
sample/hold/GENCHNK.HPP
Normal file
100
sample/hold/GENCHNK.HPP
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef _SAMPLE_GENERICCHUNK_HPP_
|
||||
#define _SAMPLE_GENERICCHUNK_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_GLOBALDATA_HPP_
|
||||
#include <common/gdata.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MEMFILE_HPP_
|
||||
#include <common/memfile.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_OPENFILE_HPP_
|
||||
#include <common/openfile.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_CHUNKID_HPP_
|
||||
#include <sample/chunkid.hpp>
|
||||
#endif
|
||||
|
||||
class GenericChunk : public GlobalData<BYTE>
|
||||
{
|
||||
public:
|
||||
GenericChunk(void);
|
||||
GenericChunk(const GenericChunk &someGenericChunk);
|
||||
virtual ~GenericChunk();
|
||||
GenericChunk &operator=(const GenericChunk &someGenericChunk);
|
||||
WORD operator==(const GenericChunk &someGenericChunk)const;
|
||||
MemFile &operator>>(MemFile &someMemFile)const;
|
||||
FileHandle &operator<<(FileHandle &someFileHandle);
|
||||
const ChunkID &chunkID(void)const;
|
||||
DWORD chunkLength(void)const;
|
||||
private:
|
||||
ChunkID mChunkID;
|
||||
};
|
||||
|
||||
inline
|
||||
GenericChunk::GenericChunk(void)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
GenericChunk::GenericChunk(const GenericChunk &someGenericChunk)
|
||||
{
|
||||
*this=someGenericChunk;
|
||||
}
|
||||
|
||||
inline
|
||||
GenericChunk::~GenericChunk()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
GenericChunk &GenericChunk::operator=(const GenericChunk &someGenericChunk)
|
||||
{
|
||||
mChunkID=someGenericChunk.mChunkID;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD GenericChunk::operator==(const GenericChunk &someGenericChunk)const
|
||||
{
|
||||
return (mChunkID==someGenericChunk.mChunkID&&
|
||||
(GlobalData<BYTE>&)*this==(GlobalData<BYTE>&)someGenericChunk);
|
||||
}
|
||||
|
||||
inline
|
||||
MemFile &GenericChunk::operator>>(MemFile &someMemFile)const
|
||||
{
|
||||
DWORD lengthData(size());
|
||||
|
||||
mChunkID>>someMemFile;
|
||||
someMemFile.write((char*)&lengthData,sizeof(lengthData));
|
||||
someMemFile.write((char*)(BYTE*)&(((GlobalData<BYTE>&)*this).operator[](0)),lengthData);
|
||||
return someMemFile;
|
||||
}
|
||||
|
||||
inline
|
||||
FileHandle &GenericChunk::operator<<(FileHandle &someFileHandle)
|
||||
{
|
||||
DWORD lengthData;
|
||||
|
||||
mChunkID<<someFileHandle;
|
||||
someFileHandle.read((BYTE*)&lengthData,sizeof(lengthData));
|
||||
size(lengthData);
|
||||
// someFileHandle.read((BYTE*)((GlobalData<BYTE>&)*this),lengthData);
|
||||
someFileHandle.read(&(((GlobalData<BYTE>&)*this).operator[](0)),lengthData);
|
||||
return someFileHandle;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD GenericChunk::chunkLength(void)const
|
||||
{
|
||||
return mChunkID.size()+size()+sizeof(DWORD);
|
||||
}
|
||||
|
||||
inline
|
||||
const ChunkID &GenericChunk::chunkID(void)const
|
||||
{
|
||||
return mChunkID;
|
||||
}
|
||||
#endif
|
||||
95
sample/hold/INCAPS.HPP
Normal file
95
sample/hold/INCAPS.HPP
Normal file
@@ -0,0 +1,95 @@
|
||||
#ifndef _SAMPLE_WAVEINCAPS_HPP_
|
||||
#define _SAMPLE_WAVEINCAPS_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_STRING_HPP_
|
||||
#include <common/string.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MMSYSTEM_HPP_
|
||||
#include <common/mmsystem.hpp>
|
||||
#endif
|
||||
|
||||
class WaveInCaps : private WAVEINCAPS
|
||||
{
|
||||
public:
|
||||
WaveInCaps(const WaveInCaps &someWaveInCaps);
|
||||
WaveInCaps(void);
|
||||
~WaveInCaps();
|
||||
WaveInCaps &operator=(const WaveInCaps &someWaveInCaps);
|
||||
operator WAVEINCAPS &(void);
|
||||
UINT manufacturerID(void)const;
|
||||
UINT productID(void)const;
|
||||
WORD driverVersion(void)const;
|
||||
String productName(void)const;
|
||||
DWORD supportedFormats(void)const;
|
||||
UINT channels(void)const;
|
||||
private:
|
||||
};
|
||||
|
||||
inline
|
||||
WaveInCaps::WaveInCaps(const WaveInCaps &someWaveInCaps)
|
||||
{
|
||||
*this=someWaveInCaps;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveInCaps::WaveInCaps(void)
|
||||
{
|
||||
::memset(this,0,sizeof(*this));
|
||||
}
|
||||
|
||||
inline
|
||||
WaveInCaps::~WaveInCaps()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
UINT WaveInCaps::manufacturerID(void)const
|
||||
{
|
||||
return WAVEINCAPS::wMid;
|
||||
}
|
||||
|
||||
inline
|
||||
UINT WaveInCaps::productID(void)const
|
||||
{
|
||||
return WAVEINCAPS::wPid;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveInCaps::driverVersion(void)const
|
||||
{
|
||||
return WAVEINCAPS::vDriverVersion;
|
||||
}
|
||||
|
||||
inline
|
||||
String WaveInCaps::productName(void)const
|
||||
{
|
||||
return String(WAVEINCAPS::szPname);
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD WaveInCaps::supportedFormats(void)const
|
||||
{
|
||||
return WAVEINCAPS::dwFormats;
|
||||
}
|
||||
|
||||
inline
|
||||
UINT WaveInCaps::channels(void)const
|
||||
{
|
||||
return WAVEINCAPS::wChannels;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveInCaps::operator WAVEINCAPS &(void)
|
||||
{
|
||||
return *((WAVEINCAPS*)this);
|
||||
}
|
||||
|
||||
inline
|
||||
WaveInCaps &WaveInCaps::operator=(const WaveInCaps &someWaveInCaps)
|
||||
{
|
||||
::memcpy(this,&someWaveInCaps,sizeof(*this));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
36
sample/hold/MAIN.CPP
Normal file
36
sample/hold/MAIN.CPP
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <common/array.hpp>
|
||||
#include <sample/purewave.hpp>
|
||||
#include <sample/wave.hpp>
|
||||
|
||||
int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE /*hPrevInstance*/,LPSTR /*lpszCmdLine*/,int /*nCmdShow*/)
|
||||
{
|
||||
Array<WaveForm> waveForms;
|
||||
PureWave pureWave;
|
||||
|
||||
waveForms.size(2);
|
||||
// waveForms[0]="C:\\WINDOWS\\MEDIA\\DSSHOTGN.WAV";
|
||||
// waveForms[0]="c:\\winnt\\media\\ctmelody.wav";
|
||||
|
||||
|
||||
|
||||
waveForms[0]="D:\\Program Files\\FruityLoops3\\Samples\\Packs\\Basic\\Kicks\\Kick.wav";
|
||||
waveForms[1]="D:\\Program Files\\FruityLoops3\\Samples\\Packs\\Basic\\Kicks\\C_Kick.wav";
|
||||
|
||||
::OutputDebugString(waveForms[0].toString()+String("\n"));
|
||||
::OutputDebugString(waveForms[1].toString()+String("\n"));
|
||||
|
||||
// waveForms[0]+=waveForms[1];
|
||||
|
||||
|
||||
::OutputDebugString(waveForms[0].toString()+String("\n"));
|
||||
|
||||
|
||||
// return 0;
|
||||
for(int index=0;index<3;index++)
|
||||
{
|
||||
pureWave.play(waveForms[0],DeviceHandler::Wait);
|
||||
}
|
||||
// pureWave.play(waveForms[0],DeviceHandler::Wait);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
103
sample/hold/OUTCAPS.HPP
Normal file
103
sample/hold/OUTCAPS.HPP
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifndef _SAMPLE_WAVEOUTCAPS_HPP_
|
||||
#define _SAMPLE_WAVEOUTCAPS_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MMSYSTEM_HPP_
|
||||
#include <common/mmsystem.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_STRING_HPP_
|
||||
#include <common/string.hpp>
|
||||
#endif
|
||||
|
||||
class WaveOutCaps : private WAVEOUTCAPS
|
||||
{
|
||||
public:
|
||||
WaveOutCaps(void);
|
||||
WaveOutCaps(const WaveOutCaps &someWaveOutCaps);
|
||||
~WaveOutCaps();
|
||||
WaveOutCaps &operator=(const WaveOutCaps &someWaveOutCaps);
|
||||
operator WAVEOUTCAPS &(void)const;
|
||||
UINT manufacturerID(void)const;
|
||||
UINT productID(void)const;
|
||||
MMVERSION driverVersion(void)const;
|
||||
String productName(void)const;
|
||||
DWORD supportedFormats(void)const;
|
||||
WORD channels(void)const;
|
||||
DWORD optionalSupport(void)const;
|
||||
private:
|
||||
};
|
||||
|
||||
inline
|
||||
WaveOutCaps::WaveOutCaps(const WaveOutCaps &someWaveOutCaps)
|
||||
{
|
||||
*this=someWaveOutCaps;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveOutCaps::WaveOutCaps(void)
|
||||
{
|
||||
::memset(this,0,sizeof(*this));
|
||||
}
|
||||
|
||||
inline
|
||||
WaveOutCaps::~WaveOutCaps()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
UINT WaveOutCaps::manufacturerID(void)const
|
||||
{
|
||||
return WAVEOUTCAPS::wMid;
|
||||
}
|
||||
|
||||
inline
|
||||
UINT WaveOutCaps::productID(void)const
|
||||
{
|
||||
return WAVEOUTCAPS::wPid;
|
||||
}
|
||||
|
||||
inline
|
||||
MMVERSION WaveOutCaps::driverVersion(void)const
|
||||
{
|
||||
return WAVEOUTCAPS::vDriverVersion;
|
||||
}
|
||||
|
||||
inline
|
||||
String WaveOutCaps::productName(void)const
|
||||
{
|
||||
return WAVEOUTCAPS::szPname;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD WaveOutCaps::supportedFormats(void)const
|
||||
{
|
||||
return WAVEOUTCAPS::dwFormats;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveOutCaps::channels(void)const
|
||||
{
|
||||
return WAVEOUTCAPS::wChannels;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
DWORD WaveOutCaps::optionalSupport(void)const
|
||||
{
|
||||
return WAVEOUTCAPS::dwSupport;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveOutCaps::operator WAVEOUTCAPS &(void)const
|
||||
{
|
||||
return *((WAVEOUTCAPS*)this);
|
||||
}
|
||||
|
||||
inline
|
||||
WaveOutCaps &WaveOutCaps::operator=(const WaveOutCaps &someWaveOutCaps)
|
||||
{
|
||||
::memcpy(this,&someWaveOutCaps,sizeof(*this));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
82
sample/hold/PCMFORM.HPP
Normal file
82
sample/hold/PCMFORM.HPP
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef _SAMPLE_WAVEFORMATPCM_HPP_
|
||||
#define _SAMPLE_WAVEFORMATPCM_HPP_
|
||||
#ifndef _SAMPLE_WAVEFORMATEX_HPP_
|
||||
#include <sample/wavefmex.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_FORMATCHUNK_HPP_
|
||||
#include <sample/fmtchnk.hpp>
|
||||
#endif
|
||||
|
||||
class WaveFormatPCM : public WaveFormatEx
|
||||
{
|
||||
public:
|
||||
WaveFormatPCM(void);
|
||||
WaveFormatPCM(const WaveFormatPCM &someWaveFormatPCM);
|
||||
WaveFormatPCM(const FormatChunk &someFormatChunk);
|
||||
~WaveFormatPCM();
|
||||
WaveFormatPCM &operator=(const WaveFormatPCM &someWaveFormatPCM);
|
||||
WaveFormatPCM &operator=(const FormatChunk &someFormatChunk);
|
||||
operator PCMWAVEFORMAT &(void)const;
|
||||
WORD bitsPerSample(void)const;
|
||||
void bitsPerSample(WORD bitsPerSample);
|
||||
private:
|
||||
WORD mBitsPerSample;
|
||||
};
|
||||
|
||||
inline
|
||||
WaveFormatPCM::WaveFormatPCM(void)
|
||||
: mBitsPerSample(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatPCM::WaveFormatPCM(const WaveFormatPCM &someWaveFormatPCM)
|
||||
: WaveFormatEx((WaveFormatEx&)*this), mBitsPerSample(someWaveFormatPCM.mBitsPerSample)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatPCM::WaveFormatPCM(const FormatChunk &someFormatChunk)
|
||||
{
|
||||
*this=someFormatChunk;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatPCM::~WaveFormatPCM()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatPCM &WaveFormatPCM::operator=(const WaveFormatPCM &someWaveFormatPCM)
|
||||
{
|
||||
mBitsPerSample=someWaveFormatPCM.mBitsPerSample;
|
||||
(WaveFormatEx&)*this=(WaveFormatEx&)someWaveFormatPCM;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatPCM::operator PCMWAVEFORMAT &(void)const
|
||||
{
|
||||
return *((PCMWAVEFORMAT*)this);
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveFormatPCM::bitsPerSample(void)const
|
||||
{
|
||||
return mBitsPerSample;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormatPCM::bitsPerSample(WORD bitsPerSample)
|
||||
{
|
||||
mBitsPerSample=bitsPerSample;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatPCM &WaveFormatPCM::operator=(const FormatChunk &someFormatChunk)
|
||||
{
|
||||
(WaveFormatEx&)*this=someFormatChunk;
|
||||
bitsPerSample(someFormatChunk.bitsPerSample());
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
48
sample/hold/PURESMPL.CPP
Normal file
48
sample/hold/PURESMPL.CPP
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <sample/puresmpl.hpp>
|
||||
|
||||
PureSample &PureSample::operator=(const PureSample &somePureSample)
|
||||
{
|
||||
numSamples(somePureSample.numSamples());
|
||||
if(!isOkay())return *this;
|
||||
copySampleData(&(((GlobalData<BYTE>&)mSampleData).operator[](0)),&(((GlobalData<BYTE>&)somePureSample.mSampleData).operator[](0)),numSamples());
|
||||
return *this;
|
||||
}
|
||||
|
||||
PureSample &PureSample::operator+=(const PureSample &somePureSample)
|
||||
{
|
||||
PureSample mixedSample;
|
||||
DWORD clampOne;
|
||||
DWORD clampTwo;
|
||||
UHUGE *lpMixedSample;
|
||||
UHUGE *lpSampleOne;
|
||||
UHUGE *lpSampleTwo;
|
||||
|
||||
if(numSamples()>somePureSample.numSamples())
|
||||
{
|
||||
clampOne=somePureSample.numSamples();
|
||||
clampTwo=numSamples();
|
||||
lpSampleOne=sampleData();
|
||||
lpSampleTwo=((PureSample&)somePureSample).sampleData();
|
||||
}
|
||||
else
|
||||
{
|
||||
clampOne=numSamples();
|
||||
clampTwo=somePureSample.numSamples();
|
||||
lpSampleOne=((PureSample&)somePureSample).sampleData();
|
||||
lpSampleTwo=sampleData();
|
||||
}
|
||||
mixedSample.numSamples(clampTwo);
|
||||
lpMixedSample=mixedSample.sampleData();
|
||||
for(DWORD sampleIndex=0;sampleIndex<clampOne;sampleIndex++)
|
||||
*(lpMixedSample+sampleIndex)=((WORD)*(lpSampleOne+sampleIndex)+(WORD)*(lpSampleTwo+sampleIndex))>>0x01;
|
||||
for(;sampleIndex<clampTwo;sampleIndex++)
|
||||
*(lpMixedSample+sampleIndex)=((WORD)*(lpSampleOne+sampleIndex));
|
||||
*this=mixedSample;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void PureSample::copySampleData(UHUGE *lpDstSample,UHUGE *lpSrcSample,DWORD numBytes)
|
||||
{
|
||||
::memcpy(lpDstSample,lpSrcSample,numBytes);
|
||||
}
|
||||
|
||||
112
sample/hold/PURESMPL.HPP
Normal file
112
sample/hold/PURESMPL.HPP
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef _SAMPLE_PURESAMPLE_HPP_
|
||||
#define _SAMPLE_PURESAMPLE_HPP_
|
||||
#ifndef _COMMON_TYPES_HPP_
|
||||
#include <common/types.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MEMFILE_HPP_
|
||||
#include <common/memfile.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_OPENFILE_HPP_
|
||||
#include <common/openfile.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_GLOBALDATA_HPP_
|
||||
#include <common/gdata.hpp>
|
||||
#endif
|
||||
|
||||
// This object holds the sample data as bytes. It does not know anything about the internal
|
||||
// makeup of the sample (ie) does not know how many bits per sample
|
||||
|
||||
class PureSample
|
||||
{
|
||||
public:
|
||||
PureSample(void);
|
||||
PureSample(const PureSample &somePureSample);
|
||||
virtual ~PureSample();
|
||||
PureSample &operator=(const PureSample &somePureSample);
|
||||
PureSample &operator+=(const PureSample &somePureSample);
|
||||
DWORD numSamples(void)const;
|
||||
void numSamples(DWORD numSamples);
|
||||
UHUGE *sampleData(void);
|
||||
WORD isOkay(void)const;
|
||||
MemFile &operator>>(MemFile &someMemFile)const;
|
||||
FileHandle &operator<<(FileHandle &someFileHandle);
|
||||
String toString(void)const;
|
||||
private:
|
||||
void copySampleData(UHUGE *lpDstSample,UHUGE *lpSrcSamples,DWORD numBytes);
|
||||
DWORD mNumSamples;
|
||||
GlobalData<BYTE> mSampleData;
|
||||
};
|
||||
|
||||
inline
|
||||
PureSample::PureSample(void)
|
||||
: mNumSamples(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
PureSample::PureSample(const PureSample &somePureSample)
|
||||
{
|
||||
*this=somePureSample;
|
||||
}
|
||||
|
||||
inline
|
||||
PureSample::~PureSample()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD PureSample::numSamples(void)const
|
||||
{
|
||||
return mNumSamples;
|
||||
}
|
||||
|
||||
inline
|
||||
void PureSample::numSamples(DWORD numSamples)
|
||||
{
|
||||
mNumSamples=numSamples;
|
||||
mSampleData.size(mNumSamples,GMEM_MOVEABLE);
|
||||
}
|
||||
|
||||
inline
|
||||
UHUGE *PureSample::sampleData(void)
|
||||
{
|
||||
if(!isOkay())return (UHUGE*)0;
|
||||
return (UHUGE*)&mSampleData[0];
|
||||
}
|
||||
|
||||
inline
|
||||
MemFile &PureSample::operator>>(MemFile &someMemFile)const
|
||||
{
|
||||
if(!isOkay())return someMemFile;
|
||||
someMemFile.write((char*)(UHUGE*)&(((GlobalData<BYTE>&)mSampleData)[0]),mNumSamples);
|
||||
return someMemFile;
|
||||
}
|
||||
|
||||
inline
|
||||
FileHandle &PureSample::operator<<(FileHandle &someFileHandle)
|
||||
{
|
||||
if(!isOkay())return someFileHandle;
|
||||
someFileHandle.read((BYTE*)(UHUGE*)&mSampleData[0],mNumSamples);
|
||||
return someFileHandle;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD PureSample::isOkay(void)const
|
||||
{
|
||||
return mSampleData.isOkay();
|
||||
}
|
||||
|
||||
inline
|
||||
String PureSample::toString(void)const
|
||||
{
|
||||
String strPureSample;
|
||||
strPureSample+="<PURESAMPLE>";
|
||||
strPureSample+=String(" NumSamples=")+String().fromInt(mNumSamples).quotes();
|
||||
strPureSample+=String(" SampleData=")+String().fromInt(mSampleData.size()).quotes();
|
||||
strPureSample+=String("<PURESAMPLE/>");
|
||||
return strPureSample;
|
||||
}
|
||||
#endif
|
||||
58
sample/hold/PUREWAVE.CPP
Normal file
58
sample/hold/PUREWAVE.CPP
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <sample/purewave.hpp>
|
||||
#include <common/assert.hpp>
|
||||
#include <sample/wave.hpp>
|
||||
|
||||
PureWave::~PureWave()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
PureWave::PureWave(void)
|
||||
: mhProcessInstance(processInstance()), mClassNameString("PLAYBACKSAMPLEDOUTPUT")
|
||||
{
|
||||
UINT numOutputDevices;
|
||||
UINT numInputDevices;
|
||||
registerClass();
|
||||
createWindow();
|
||||
numOutputDevices=::waveOutGetNumDevs();
|
||||
numInputDevices=::waveInGetNumDevs();
|
||||
for(short deviceIndex=0;deviceIndex<numOutputDevices;deviceIndex++)
|
||||
mWaveOutDeviceBlock.insert(&WaveOutDevice(deviceIndex,*this));
|
||||
for(deviceIndex=0;deviceIndex<numInputDevices;deviceIndex++)
|
||||
mWaveInDeviceBlock.insert(&WaveInDevice(deviceIndex,*this));
|
||||
}
|
||||
|
||||
void PureWave::registerClass(void)const
|
||||
{
|
||||
WNDCLASS wndClass;
|
||||
|
||||
if(::GetClassInfo(mhProcessInstance,(LPSTR)mClassNameString,(WNDCLASS FAR*)&wndClass))return;
|
||||
wndClass.style =CS_HREDRAW|CS_VREDRAW;
|
||||
wndClass.lpfnWndProc =(WNDPROC)Window::WndProc;
|
||||
wndClass.cbClsExtra =0;
|
||||
wndClass.cbWndExtra =sizeof(PureWave*);
|
||||
wndClass.hInstance =mhProcessInstance;
|
||||
wndClass.hIcon =::LoadIcon(NULL,IDI_APPLICATION);
|
||||
wndClass.hCursor =::LoadCursor(NULL,IDC_ARROW);
|
||||
wndClass.hbrBackground =(HBRUSH)::GetStockObject(WHITE_BRUSH);
|
||||
wndClass.lpszMenuName =0;
|
||||
wndClass.lpszClassName =(LPSTR)mClassNameString;
|
||||
::RegisterClass(&wndClass);
|
||||
assert(0!=::GetClassInfo(mhProcessInstance,(LPSTR)mClassNameString,(WNDCLASS FAR*)&wndClass));
|
||||
}
|
||||
|
||||
void PureWave::createWindow(void)
|
||||
{
|
||||
assert(0!=::CreateWindow((LPSTR)mClassNameString,(LPSTR)mClassNameString,
|
||||
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
|
||||
NULL,NULL,mhProcessInstance,(LPSTR)this));
|
||||
show(SW_HIDE);
|
||||
update();
|
||||
}
|
||||
|
||||
WORD PureWave::play(WaveForm &someWaveForm,DeviceHandler::PlayMode playMode)
|
||||
{
|
||||
if(!mWaveOutDeviceBlock.size())return FALSE;
|
||||
return (mWaveOutDeviceBlock[0]).play(someWaveForm,playMode);
|
||||
}
|
||||
|
||||
58
sample/hold/PUREWAVE.HPP
Normal file
58
sample/hold/PUREWAVE.HPP
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef _SAMPLE_PUREWAVE_HPP_
|
||||
#define _SAMPLE_PUREWAVE_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_WINDOW_HPP_
|
||||
#include <common/window.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MMSYSTEM_HPP_
|
||||
#include <common/mmsystem.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_STRING_HPP_
|
||||
#include <common/string.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_BLOCK_HPP_
|
||||
#include <common/block.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_DEVICEHANDLER_HPP_
|
||||
#include <sample/devhndlr.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEINDEVICE_HPP_
|
||||
#include <sample/wavein.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEOUTDEVICE_HPP_
|
||||
#include <sample/waveout.hpp>
|
||||
#endif
|
||||
|
||||
class WaveForm;
|
||||
|
||||
class PureWave : private Window
|
||||
{
|
||||
public:
|
||||
PureWave(void);
|
||||
~PureWave();
|
||||
WORD play(WaveForm &someWaveForm,DeviceHandler::PlayMode playMode=DeviceHandler::NoWait);
|
||||
UINT numInputDevices(void)const;
|
||||
UINT numOutputDevices(void)const;
|
||||
private:
|
||||
void registerClass(void)const;
|
||||
void createWindow(void);
|
||||
Block<WaveOutDevice> mWaveOutDeviceBlock;
|
||||
Block<WaveInDevice> mWaveInDeviceBlock;
|
||||
HINSTANCE mhProcessInstance;
|
||||
String mClassNameString;
|
||||
};
|
||||
|
||||
inline
|
||||
UINT PureWave::numInputDevices(void)const
|
||||
{
|
||||
return mWaveInDeviceBlock.size();
|
||||
}
|
||||
|
||||
inline
|
||||
UINT PureWave::numOutputDevices(void)const
|
||||
{
|
||||
return mWaveOutDeviceBlock.size();
|
||||
}
|
||||
#endif
|
||||
65
sample/hold/SAMPLE.CPP
Normal file
65
sample/hold/SAMPLE.CPP
Normal file
@@ -0,0 +1,65 @@
|
||||
#include <common/array.hpp>
|
||||
#include <sample/purewave.hpp>
|
||||
#include <sample/wave.hpp>
|
||||
#include <sample/sample.hpp>
|
||||
|
||||
PureWave *lpPureWave=0;
|
||||
PureVector<WaveForm> waveForms;
|
||||
|
||||
#if defined(__FLAT__)
|
||||
BOOL WINAPI DllEntryPoint(HINSTANCE /*hInstance*/,DWORD reasonCode,LPVOID /*lpvReserved*/)
|
||||
{
|
||||
switch(reasonCode)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH :
|
||||
// createInstanceData(hInstance);
|
||||
break;
|
||||
case DLL_PROCESS_DETACH :
|
||||
// destroyInstanceData();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
int CALLBACK _export LibMain(HINSTANCE hInstance,WORD /*wDataSeg*/,WORD /*wHeapSize*/,LPSTR /*lpszCmdLine*/)
|
||||
{
|
||||
createInstanceData(hInstance);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int CALLBACK _export WEP(int /*nExitType*/)
|
||||
{
|
||||
destroyInstanceData();
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
short CALLBACK _export play(WORD waveFormIndex,WORD waitFlag)
|
||||
{
|
||||
if(!lpPureWave)return FALSE;
|
||||
if(waveFormIndex>=waveForms.size())return FALSE;
|
||||
return lpPureWave->play(waveForms[waveFormIndex],waitFlag?DeviceHandler::Wait:DeviceHandler::NoWait);
|
||||
}
|
||||
|
||||
short CALLBACK _export preLoadSamples(Block<String> &pathFileNames)
|
||||
{
|
||||
if(!lpPureWave)return FALSE;
|
||||
|
||||
waveForms.size(pathFileNames.size());
|
||||
for(short index=0;index<waveForms.size();index++)waveForms[index]=pathFileNames[index];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CALLBACK _export createInstanceData(HINSTANCE hInstance)
|
||||
{
|
||||
destroyInstanceData();
|
||||
lpPureWave=new PureWave(hInstance);
|
||||
}
|
||||
|
||||
void CALLBACK _export destroyInstanceData(void)
|
||||
{
|
||||
if(lpPureWave){delete lpPureWave;lpPureWave=0;}
|
||||
waveForms.size(0);
|
||||
}
|
||||
|
||||
|
||||
17
sample/hold/SAMPLE.HPP
Normal file
17
sample/hold/SAMPLE.HPP
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _SAMPLE_SAMPLE_HPP_
|
||||
#define _SAMPLE_SAMPLE_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_BLOCK_HPP_
|
||||
#include <common/block.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_STRING_HPP_
|
||||
#include <common/string.hpp>
|
||||
#endif
|
||||
|
||||
short CALLBACK _export play(WORD waveFormIndex,WORD waitFlag);
|
||||
short CALLBACK _export preLoadSamples(Block<String> &pathFileNames);
|
||||
void CALLBACK _export createInstanceData(HINSTANCE hInstance);
|
||||
void CALLBACK _export destroyInstanceData(void);
|
||||
#endif
|
||||
22
sample/hold/STDTMPL.CPP
Normal file
22
sample/hold/STDTMPL.CPP
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef _MSC_VER
|
||||
#define _EXPAND_VECTOR_TEMPLATES_
|
||||
#define _EXPAND_BLOCK_TEMPLATES_
|
||||
#include <common/pvector.hpp>
|
||||
#include <common/pvector.tpp>
|
||||
#include <common/block.hpp>
|
||||
#include <common/block.tpp>
|
||||
#include <common/gdata.hpp>
|
||||
#include <common/gdata.tpp>
|
||||
#include <common/callback.hpp>
|
||||
#include <common/callback.tpp>
|
||||
#include <common/string.hpp>
|
||||
#include <common/point.hpp>
|
||||
#include <sample/purewave.hpp>
|
||||
#include <sample/wave.hpp>
|
||||
|
||||
typedef PureVector<WaveForm> a;
|
||||
typedef Block<String> c;
|
||||
typedef Block<CallbackPointer> d;
|
||||
typedef PureVector<Point> e;
|
||||
typedef GlobalData<BYTE> f;
|
||||
#endif
|
||||
163
sample/hold/WAVE.CPP
Normal file
163
sample/hold/WAVE.CPP
Normal file
@@ -0,0 +1,163 @@
|
||||
#include <sample/wave.hpp>
|
||||
#include <common/memfile.hpp>
|
||||
#include <common/openfile.hpp>
|
||||
|
||||
WaveForm::WaveForm(String wavePathFileName)
|
||||
{
|
||||
initWaveForm();
|
||||
wavePathFileName.lower();
|
||||
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
|
||||
mWavePathFileName=wavePathFileName;
|
||||
FileHandle waveFile(wavePathFileName,FileHandle::Read,FileHandle::ShareReadWrite);
|
||||
if(!waveFile.isOkay())return;
|
||||
waveFile.read((BYTE*)&mHeaderString,sizeof(mHeaderString));
|
||||
waveFile.read((BYTE*)&mLengthData,sizeof(mLengthData));
|
||||
waveFile.read((BYTE*)&mSubHeaderString,sizeof(mSubHeaderString));
|
||||
mFormatChunk<<waveFile;
|
||||
while(TRUE)
|
||||
{
|
||||
ChunkID chunkID;
|
||||
chunkID<<waveFile;
|
||||
waveFile.seek(-chunkID.size(),FileHandle::SeekCurrent);
|
||||
if(chunkID==String("data")){mDataChunk<<waveFile;break;}
|
||||
mGenericChunks.insert(&GenericChunk());
|
||||
mGenericChunks[mGenericChunks.size()-1]<<waveFile;
|
||||
}
|
||||
mSampleData.numSamples(mDataChunk.length());
|
||||
mSampleData<<waveFile;
|
||||
waveFile.close();
|
||||
}
|
||||
|
||||
WaveForm WaveForm::operator+(const WaveForm &someWaveForm)
|
||||
{
|
||||
WaveForm waveForm(*this);
|
||||
waveForm+=someWaveForm;
|
||||
return waveForm;
|
||||
}
|
||||
|
||||
WaveForm &WaveForm::operator=(const WaveForm &someWaveForm)
|
||||
{
|
||||
initWaveForm();
|
||||
mLengthData=someWaveForm.mLengthData;
|
||||
mFormatChunk=someWaveForm.mFormatChunk;
|
||||
mDataChunk=someWaveForm.mDataChunk;
|
||||
mSampleData=someWaveForm.mSampleData;
|
||||
return *this;
|
||||
}
|
||||
|
||||
WaveForm &WaveForm::operator+=(const WaveForm &someWaveForm)
|
||||
{
|
||||
if(mLengthData<someWaveForm.mLengthData)
|
||||
{
|
||||
mLengthData=someWaveForm.mLengthData;
|
||||
mFormatChunk=someWaveForm.mFormatChunk;
|
||||
mDataChunk=someWaveForm.mDataChunk;
|
||||
}
|
||||
mSampleData+=someWaveForm.mSampleData;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool WaveForm::operator==(const WaveForm &/*someWaveForm*/)const
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool WaveForm::operator<<(FileHandle &waveFile)
|
||||
{
|
||||
if(!waveFile.isOkay())return FALSE;
|
||||
initWaveForm();
|
||||
waveFile.read((BYTE*)&mHeaderString,sizeof(mHeaderString));
|
||||
waveFile.read((BYTE*)&mLengthData,sizeof(mLengthData));
|
||||
waveFile.read((BYTE*)&mSubHeaderString,sizeof(mSubHeaderString));
|
||||
mFormatChunk<<waveFile;
|
||||
while(TRUE)
|
||||
{
|
||||
ChunkID chunkID;
|
||||
chunkID<<waveFile;
|
||||
waveFile.seek(-chunkID.size(),FileHandle::SeekCurrent);
|
||||
if(chunkID==String("data")){mDataChunk<<waveFile;break;}
|
||||
mGenericChunks.insert(&GenericChunk());
|
||||
mGenericChunks[mGenericChunks.size()-1]<<waveFile;
|
||||
}
|
||||
mSampleData.numSamples(mDataChunk.length());
|
||||
mSampleData<<waveFile;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void WaveForm::initWaveForm(void)
|
||||
{
|
||||
mLengthData=0;
|
||||
mExtensionString=".wav";
|
||||
mWaveString="WAVE";
|
||||
mRiffString="RIFF";
|
||||
::memcpy(mHeaderString,mRiffString,mRiffString.length());
|
||||
::memcpy(mSubHeaderString,mWaveString,mWaveString.length());
|
||||
}
|
||||
|
||||
bool WaveForm::save(String wavePathFileName)
|
||||
{
|
||||
DWORD waveFileLength((long)sizeof(mHeaderString)+(long)sizeof(mLengthData)+(long)sizeof(mSubHeaderString)+(long)sizeof(FormatChunk)+(long)sizeof(DataChunk)+(long)mSampleData.numSamples());
|
||||
wavePathFileName.upper();
|
||||
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
|
||||
MemFile waveFile(wavePathFileName,waveFileLength);
|
||||
mLengthData=mSampleData.numSamples()+sizeof(mSubHeaderString)+mFormatChunk.size()+mDataChunk.size();
|
||||
for(short chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mLengthData+=mGenericChunks[chunkIndex].chunkLength();
|
||||
waveFile.write((char*)&mHeaderString,sizeof(mHeaderString));
|
||||
waveFile.write((char*)&mLengthData,sizeof(mLengthData));
|
||||
waveFile.write((char*)&mSubHeaderString,sizeof(mSubHeaderString));
|
||||
mFormatChunk>>waveFile;
|
||||
mDataChunk.length(mSampleData.numSamples());
|
||||
for(chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mGenericChunks[chunkIndex]>>waveFile;
|
||||
mDataChunk>>waveFile;
|
||||
mSampleData>>waveFile;
|
||||
return waveFile.flushBuffer();
|
||||
}
|
||||
|
||||
bool WaveForm::save(String wavePathFileName,const PureSample &somePureSample,DWORD samplesPerSecond,DWORD avgBytesPerSecond)
|
||||
{
|
||||
DWORD waveFileLength((long)sizeof(mHeaderString)+(long)sizeof(mLengthData)+(long)sizeof(mSubHeaderString)+(long)sizeof(FormatChunk)+(long)sizeof(DataChunk)+(long)somePureSample.numSamples());
|
||||
|
||||
wavePathFileName.upper();
|
||||
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
|
||||
MemFile waveFile(wavePathFileName,waveFileLength);
|
||||
mLengthData=somePureSample.numSamples()+sizeof(mSubHeaderString)+mFormatChunk.size()+mDataChunk.size();
|
||||
for(short chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mLengthData+=mGenericChunks[chunkIndex].chunkLength();
|
||||
waveFile.write((char*)&mHeaderString,sizeof(mHeaderString));
|
||||
waveFile.write((char*)&mLengthData,sizeof(mLengthData));
|
||||
waveFile.write((char*)&mSubHeaderString,sizeof(mSubHeaderString));
|
||||
mFormatChunk.formatTag(FormatChunk::WaveFormatPCM);
|
||||
mFormatChunk.channels(FormatChunk::NumChannels);
|
||||
mFormatChunk.samplesPerSecond(samplesPerSecond);
|
||||
mFormatChunk.averageBytesPerSecond(avgBytesPerSecond);
|
||||
mFormatChunk.blockAlign(FormatChunk::BlockAlign);
|
||||
mFormatChunk.bitsPerSample(FormatChunk::BitsPerSample);
|
||||
mFormatChunk>>waveFile;
|
||||
mDataChunk.length(somePureSample.numSamples());
|
||||
for(chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mGenericChunks[chunkIndex]>>waveFile;
|
||||
mDataChunk>>waveFile;
|
||||
somePureSample>>waveFile;
|
||||
return waveFile.flushBuffer();
|
||||
}
|
||||
|
||||
String WaveForm::toString(void)const
|
||||
{
|
||||
String strWaveForm;
|
||||
|
||||
strWaveForm+=String("<WAVEFORM>");
|
||||
strWaveForm+=String(" Header=")+String(mHeaderString).quotes();
|
||||
strWaveForm+=String(" LengthData=")+String().fromInt(mLengthData).quotes();
|
||||
strWaveForm+=String(" SubHeader=")+String(mSubHeaderString).quotes();
|
||||
strWaveForm+=String(" ")+mFormatChunk.toString();
|
||||
for(int index=0;index<mGenericChunks.size();index++)
|
||||
{
|
||||
strWaveForm+=((Block<GenericChunk>&)mGenericChunks)[index].chunkID().toString();
|
||||
}
|
||||
strWaveForm+=mDataChunk.toString();
|
||||
strWaveForm+=mSampleData.toString();
|
||||
strWaveForm+=String(" WavePathFileName=")+mWavePathFileName.quotes();
|
||||
strWaveForm+=String(" Extension=")+mExtensionString.quotes();
|
||||
strWaveForm+=String(" WaveString=")+mWaveString.quotes();
|
||||
strWaveForm+=String(" RiffString=")+mRiffString.quotes();
|
||||
strWaveForm+=String("</WAVEFORM>");
|
||||
return strWaveForm;
|
||||
}
|
||||
114
sample/hold/WAVE.HPP
Normal file
114
sample/hold/WAVE.HPP
Normal file
@@ -0,0 +1,114 @@
|
||||
#ifndef _SAMPLE_WAVEFORM_HPP_
|
||||
#define _SAMPLE_WAVEFORM_HPP_
|
||||
#ifndef _COMMON_STDIO_HPP_
|
||||
#include <common/stdio.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_STRING_HPP_
|
||||
#include <common/string.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_BLOCK_HPP_
|
||||
#include <common/block.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_PURESAMPLE_HPP_
|
||||
#include <sample/puresmpl.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_DATACHUNK_HPP_
|
||||
#include <sample/datachnk.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_FORMATCHUNK_HPP_
|
||||
#include <sample/fmtchnk.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_GENERICCHUNK_HPP_
|
||||
#include <sample/genchnk.hpp>
|
||||
#endif
|
||||
|
||||
class WaveForm
|
||||
{
|
||||
public:
|
||||
WaveForm(void);
|
||||
WaveForm(String wavePathFileName);
|
||||
WaveForm(const WaveForm &someWaveForm);
|
||||
virtual ~WaveForm();
|
||||
WaveForm &operator=(const WaveForm &someWaveForm);
|
||||
WaveForm &operator=(const String &wavePathFileName);
|
||||
WaveForm &operator+=(const WaveForm &someWaveForm);
|
||||
WaveForm operator+(const WaveForm &someWaveForm);
|
||||
bool operator==(const WaveForm &someWaveForm)const;
|
||||
bool operator<<(FileHandle &waveFile);
|
||||
FormatChunk &getFormatChunk(void);
|
||||
PureSample &getPureSample(void);
|
||||
bool save(String wavePathFileName,const PureSample &somePureSample,DWORD samplesPerSecond,DWORD avgBytesPerSecond);
|
||||
bool save(String wavePathFileName);
|
||||
const String &wavePathFileName(void)const;
|
||||
bool isOkay(void)const;
|
||||
String toString(void)const;
|
||||
private:
|
||||
enum {MaxLength=4};
|
||||
void initWaveForm(void);
|
||||
|
||||
char mHeaderString[MaxLength];
|
||||
DWORD mLengthData;
|
||||
char mSubHeaderString[MaxLength];
|
||||
FormatChunk mFormatChunk;
|
||||
Block<GenericChunk> mGenericChunks;
|
||||
DataChunk mDataChunk;
|
||||
PureSample mSampleData;
|
||||
String mWavePathFileName;
|
||||
String mExtensionString;
|
||||
String mWaveString;
|
||||
String mRiffString;
|
||||
};
|
||||
|
||||
inline
|
||||
WaveForm::WaveForm(void)
|
||||
{
|
||||
initWaveForm();
|
||||
}
|
||||
|
||||
inline
|
||||
WaveForm::WaveForm(const WaveForm &someWaveForm)
|
||||
{
|
||||
*this=someWaveForm;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveForm::~WaveForm()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
WaveForm &WaveForm::operator=(const String &wavePathFileName)
|
||||
{
|
||||
*this=WaveForm(wavePathFileName);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
bool WaveForm::isOkay(void)const
|
||||
{
|
||||
return mSampleData.isOkay();
|
||||
}
|
||||
|
||||
inline
|
||||
const String &WaveForm::wavePathFileName(void)const
|
||||
{
|
||||
return mWavePathFileName;
|
||||
}
|
||||
|
||||
inline
|
||||
FormatChunk &WaveForm::getFormatChunk(void)
|
||||
{
|
||||
return mFormatChunk;
|
||||
}
|
||||
|
||||
inline
|
||||
PureSample &WaveForm::getPureSample(void)
|
||||
{
|
||||
return mSampleData;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
172
sample/hold/WAVEFMEX.HPP
Normal file
172
sample/hold/WAVEFMEX.HPP
Normal file
@@ -0,0 +1,172 @@
|
||||
#ifndef _SAMPLE_WAVEFORMATEX_HPP_
|
||||
#define _SAMPLE_WAVEFORMATEX_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MMSYSTEM_HPP_
|
||||
#include <common/mmsystem.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_FORMATCHUNK_HPP_
|
||||
#include <sample/fmtchnk.hpp>
|
||||
#endif
|
||||
|
||||
class WaveFormatEx : private WAVEFORMATEX
|
||||
{
|
||||
public:
|
||||
enum FormatType{PulseCodeModulation=WAVE_FORMAT_PCM};
|
||||
WaveFormatEx(void);
|
||||
WaveFormatEx(const WaveFormatEx &someWaveFormatEx);
|
||||
WaveFormatEx(const FormatChunk &someFormatChunk);
|
||||
~WaveFormatEx();
|
||||
WaveFormatEx &operator=(const WaveFormatEx &someWaveFormatEx);
|
||||
WaveFormatEx &operator=(const FormatChunk &someFormatChunk);
|
||||
WORD formatTag(void)const;
|
||||
void formatTag(WORD formatTag);
|
||||
WORD channels(void)const;
|
||||
void channels(WORD channels);
|
||||
DWORD samplePerSecond(void)const;
|
||||
void samplesPerSecond(DWORD samplesPerSecond);
|
||||
DWORD averageBytesPerSecond(void)const;
|
||||
void averageBytesPerSecond(DWORD averageBytesPerSecond);
|
||||
WORD blockAlign(void)const;
|
||||
void blockAlign(WORD blockAlign);
|
||||
WORD bitsPerSample(void)const;
|
||||
void bitsPerSample(WORD bitsPerSample);
|
||||
WORD size(void)const;
|
||||
void size(WORD size);
|
||||
operator WAVEFORMATEX &(void)const;
|
||||
private:
|
||||
};
|
||||
|
||||
inline
|
||||
WaveFormatEx::WaveFormatEx(void)
|
||||
{
|
||||
::memset(this,0,sizeof(*this));
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatEx::WaveFormatEx(const WaveFormatEx &someWaveFormatEx)
|
||||
{
|
||||
*this=someWaveFormatEx;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatEx::WaveFormatEx(const FormatChunk &someFormatChunk)
|
||||
{
|
||||
*this=someFormatChunk;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatEx::~WaveFormatEx()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatEx &WaveFormatEx::operator=(const WaveFormatEx &someWaveFormatEx)
|
||||
{
|
||||
::memcpy(this,&someWaveFormatEx,sizeof(*this));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveFormatEx::formatTag(void)const
|
||||
{
|
||||
return WAVEFORMATEX::wFormatTag;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormatEx::formatTag(WORD formatTag)
|
||||
{
|
||||
WAVEFORMATEX::wFormatTag=formatTag;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveFormatEx::channels(void)const
|
||||
{
|
||||
return WAVEFORMATEX::nChannels;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormatEx::channels(WORD channels)
|
||||
{
|
||||
WAVEFORMATEX::nChannels=channels;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD WaveFormatEx::samplePerSecond(void)const
|
||||
{
|
||||
return WAVEFORMATEX::nSamplesPerSec;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormatEx::samplesPerSecond(DWORD samplesPerSecond)
|
||||
{
|
||||
WAVEFORMATEX::nSamplesPerSec=samplesPerSecond;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD WaveFormatEx::averageBytesPerSecond(void)const
|
||||
{
|
||||
return WAVEFORMATEX::nAvgBytesPerSec;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormatEx::averageBytesPerSecond(DWORD averageBytesPerSecond)
|
||||
{
|
||||
WAVEFORMATEX::nAvgBytesPerSec=averageBytesPerSecond;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveFormatEx::blockAlign(void)const
|
||||
{
|
||||
return WAVEFORMATEX::nBlockAlign;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormatEx::blockAlign(WORD blockAlign)
|
||||
{
|
||||
WAVEFORMATEX::nBlockAlign=blockAlign;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveFormatEx::bitsPerSample(void)const
|
||||
{
|
||||
return WAVEFORMATEX::wBitsPerSample;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormatEx::bitsPerSample(WORD bitsPerSample)
|
||||
{
|
||||
WAVEFORMATEX::wBitsPerSample=bitsPerSample;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveFormatEx::size(void)const
|
||||
{
|
||||
return WAVEFORMATEX::cbSize;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormatEx::size(WORD size)
|
||||
{
|
||||
WAVEFORMATEX::cbSize=size;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatEx::operator WAVEFORMATEX &(void)const
|
||||
{
|
||||
return *((WAVEFORMATEX*)this);
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormatEx &WaveFormatEx::operator=(const FormatChunk &someFormatChunk)
|
||||
{
|
||||
formatTag(someFormatChunk.formatTag());
|
||||
channels(someFormatChunk.channels());
|
||||
samplesPerSecond(someFormatChunk.samplesPerSecond());
|
||||
averageBytesPerSecond(someFormatChunk.averageBytesPerSecond());
|
||||
blockAlign(someFormatChunk.blockAlign());
|
||||
bitsPerSample(someFormatChunk.bitsPerSample());
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
143
sample/hold/WAVEFORM.HPP
Normal file
143
sample/hold/WAVEFORM.HPP
Normal file
@@ -0,0 +1,143 @@
|
||||
#ifndef _SAMPLE_WAVEFORMAT_HPP_
|
||||
#define _SAMPLE_WAVEFORMAT_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MMSYSTEM_HPP_
|
||||
#include <common/mmsystem.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_FORMATCHUNK_HPP_
|
||||
#include <sample/fmtchnk.hpp>
|
||||
#endif
|
||||
|
||||
class WaveFormat : private WAVEFORMAT
|
||||
{
|
||||
public:
|
||||
enum FormatType{PulseCodeModulation=WAVE_FORMAT_PCM};
|
||||
WaveFormat(void);
|
||||
WaveFormat(const WaveFormat &someWaveFormat);
|
||||
WaveFormat(const FormatChunk &someFormatChunk);
|
||||
virtual ~WaveFormat();
|
||||
WaveFormat &operator=(const WaveFormat &someWaveFormat);
|
||||
WaveFormat &operator=(const FormatChunk &someFormatChunk);
|
||||
WORD formatTag(void)const;
|
||||
void formatTag(WORD formatTag);
|
||||
WORD channels(void)const;
|
||||
void channels(WORD channels);
|
||||
DWORD samplePerSecond(void)const;
|
||||
void samplesPerSecond(DWORD samplesPerSecond);
|
||||
DWORD averageBytesPerSecond(void)const;
|
||||
void averageBytesPerSecond(DWORD averageBytesPerSecond);
|
||||
WORD blockAlign(void)const;
|
||||
void blockAlign(WORD blockAlign);
|
||||
operator WAVEFORMAT &(void)const;
|
||||
private:
|
||||
};
|
||||
|
||||
inline
|
||||
WaveFormat::WaveFormat(void)
|
||||
{
|
||||
::memset(this,0,sizeof(*this));
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormat::WaveFormat(const WaveFormat &someWaveFormat)
|
||||
{
|
||||
*this=someWaveFormat;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormat::WaveFormat(const FormatChunk &someFormatChunk)
|
||||
{
|
||||
*this=someFormatChunk;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormat::~WaveFormat()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormat &WaveFormat::operator=(const WaveFormat &someWaveFormat)
|
||||
{
|
||||
::memcpy(this,&someWaveFormat,sizeof(*this));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveFormat::formatTag(void)const
|
||||
{
|
||||
return WAVEFORMAT::wFormatTag;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormat::formatTag(WORD formatTag)
|
||||
{
|
||||
WAVEFORMAT::wFormatTag=formatTag;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveFormat::channels(void)const
|
||||
{
|
||||
return WAVEFORMAT::nChannels;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormat::channels(WORD channels)
|
||||
{
|
||||
WAVEFORMAT::nChannels=channels;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD WaveFormat::samplePerSecond(void)const
|
||||
{
|
||||
return WAVEFORMAT::nSamplesPerSec;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormat::samplesPerSecond(DWORD samplesPerSecond)
|
||||
{
|
||||
WAVEFORMAT::nSamplesPerSec=samplesPerSecond;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD WaveFormat::averageBytesPerSecond(void)const
|
||||
{
|
||||
return WAVEFORMAT::nAvgBytesPerSec;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormat::averageBytesPerSecond(DWORD averageBytesPerSecond)
|
||||
{
|
||||
WAVEFORMAT::nAvgBytesPerSec=averageBytesPerSecond;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveFormat::blockAlign(void)const
|
||||
{
|
||||
return WAVEFORMAT::nBlockAlign;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveFormat::blockAlign(WORD blockAlign)
|
||||
{
|
||||
WAVEFORMAT::nBlockAlign=blockAlign;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormat::operator WAVEFORMAT &(void)const
|
||||
{
|
||||
return *((WAVEFORMAT*)this);
|
||||
}
|
||||
|
||||
inline
|
||||
WaveFormat &WaveFormat::operator=(const FormatChunk &someFormatChunk)
|
||||
{
|
||||
formatTag(someFormatChunk.formatTag());
|
||||
channels(someFormatChunk.channels());
|
||||
samplesPerSecond(someFormatChunk.samplesPerSecond());
|
||||
averageBytesPerSecond(someFormatChunk.averageBytesPerSecond());
|
||||
blockAlign(someFormatChunk.blockAlign());
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
97
sample/hold/WAVEHDR.HPP
Normal file
97
sample/hold/WAVEHDR.HPP
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef _SAMPLE_WAVEHEADER_HPP_
|
||||
#define _SAMPLE_WAVEHEADER_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_MMSYSTEM_HPP_
|
||||
#include <common/mmsystem.hpp>
|
||||
#endif
|
||||
|
||||
class WaveHeader : private WAVEHDR
|
||||
{
|
||||
public:
|
||||
WaveHeader(void);
|
||||
WaveHeader(const WaveHeader &someWaveHeader);
|
||||
~WaveHeader();
|
||||
WaveHeader &operator=(const WaveHeader &someWaveHeader);
|
||||
WORD operator==(const WaveHeader &someWaveHeader);
|
||||
void setData(LPSTR lpData);
|
||||
void setBufferLength(DWORD bufferLength);
|
||||
void userData(DWORD userData);
|
||||
DWORD userData(void)const;
|
||||
// operator WAVEHDR &(void)const;
|
||||
private:
|
||||
void initHeader(void);
|
||||
};
|
||||
|
||||
inline
|
||||
WaveHeader::WaveHeader(void)
|
||||
{
|
||||
initHeader();
|
||||
}
|
||||
|
||||
inline
|
||||
WaveHeader::WaveHeader(const WaveHeader &someWaveHeader)
|
||||
{
|
||||
*this=someWaveHeader;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveHeader::~WaveHeader()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveHeader::initHeader(void)
|
||||
{
|
||||
::memset(&((WAVEHDR&)*this),0,sizeof(WAVEHDR));
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveHeader::setData(LPSTR lpData)
|
||||
{
|
||||
WAVEHDR::lpData=lpData;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveHeader::setBufferLength(DWORD bufferLength)
|
||||
{
|
||||
WAVEHDR::dwBufferLength=bufferLength;
|
||||
}
|
||||
|
||||
inline
|
||||
void WaveHeader::userData(DWORD userData)
|
||||
{
|
||||
WAVEHDR::dwUser=userData;
|
||||
}
|
||||
|
||||
inline
|
||||
DWORD WaveHeader::userData(void)const
|
||||
{
|
||||
return WAVEHDR::dwUser;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveHeader &WaveHeader::operator=(const WaveHeader &someWaveHeader)
|
||||
{
|
||||
initHeader();
|
||||
setData(someWaveHeader.WAVEHDR::lpData);
|
||||
setBufferLength(someWaveHeader.WAVEHDR::dwBufferLength);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
WORD WaveHeader::operator==(const WaveHeader &someWaveHeader)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
inline
|
||||
WaveHeader::operator WAVEHDR &(void)const
|
||||
{
|
||||
return *((WAVEHDR*)this);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
35
sample/hold/WAVEIN.CPP
Normal file
35
sample/hold/WAVEIN.CPP
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <sample/wavein.hpp>
|
||||
|
||||
WORD WaveInDevice::openDevice(WaveFormatPCM &/*waveFormatPCM*/)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WORD WaveInDevice::closeDevice(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WORD WaveInDevice::record(WaveForm &/*waveForm*/)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// virtuals
|
||||
|
||||
void WaveInDevice::openHandler(CallbackData &/*someCallbackData*/)
|
||||
{
|
||||
}
|
||||
|
||||
void WaveInDevice::closeHandler(CallbackData &/*someCallbackData*/)
|
||||
{
|
||||
}
|
||||
|
||||
void WaveInDevice::doneHandler(CallbackData &/*someCallbackData*/)
|
||||
{
|
||||
}
|
||||
|
||||
void WaveInDevice::message(const String &strErrorMessage)const
|
||||
{
|
||||
::OutputDebugString((String&)strErrorMessage+String("\n"));
|
||||
}
|
||||
76
sample/hold/WAVEIN.HPP
Normal file
76
sample/hold/WAVEIN.HPP
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef _SAMPLE_WAVEINDEVICE_HPP_
|
||||
#define _SAMPLE_WAVEINDEVICE_HPP_
|
||||
#ifndef _COMMON_WINDOWS_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_GLOBALDATA_HPP_
|
||||
#include <common/gdata.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEINCAPS_HPP_
|
||||
#include <sample/incaps.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEHEADER_HPP_
|
||||
#include <sample/wavehdr.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEFORM_HPP_
|
||||
#include <sample/wave.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_DEVICEHANDLER_HPP_
|
||||
#include <sample/devhndlr.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEFORMATPCM_HPP_
|
||||
#include <sample/pcmform.hpp>
|
||||
#endif
|
||||
|
||||
class WaveInDevice : public DeviceHandler
|
||||
{
|
||||
public:
|
||||
WaveInDevice(UINT waveDeviceID,Window &windowHandler);
|
||||
WaveInDevice(const WaveInDevice &someWaveInDevice);
|
||||
virtual ~WaveInDevice();
|
||||
WaveInDevice &operator=(const WaveInDevice &someWaveInDevice);
|
||||
WORD record(WaveForm &waveForm);
|
||||
protected:
|
||||
virtual void openHandler(CallbackData &someCallbackData);
|
||||
virtual void closeHandler(CallbackData &someCallbackData);
|
||||
virtual void doneHandler(CallbackData &someCallbackData);
|
||||
virtual void message(const String &strErrorMessage)const;
|
||||
private:
|
||||
WORD openDevice(WaveFormatPCM &waveFormatPCM);
|
||||
WORD closeDevice(void);
|
||||
UINT mWaveDeviceID;
|
||||
GlobalData<WaveHeader> mGlobalWaveHeader;
|
||||
WaveInCaps mWaveInCaps;
|
||||
HWAVEIN mhWaveIn;
|
||||
Window &mWindowHandler;
|
||||
};
|
||||
|
||||
inline
|
||||
WaveInDevice::WaveInDevice(UINT waveDeviceID,Window &windowHandler)
|
||||
: mWaveDeviceID(waveDeviceID), mhWaveIn(0), mGlobalWaveHeader(1,GMEM_MOVEABLE|GMEM_ZEROINIT),
|
||||
mWindowHandler(windowHandler), DeviceHandler(windowHandler)
|
||||
{
|
||||
::waveInGetDevCaps(mWaveDeviceID,&((WAVEINCAPS&)mWaveInCaps),sizeof(mWaveInCaps));
|
||||
}
|
||||
|
||||
inline
|
||||
WaveInDevice::WaveInDevice(const WaveInDevice &someWaveInDevice)
|
||||
: mWaveDeviceID(someWaveInDevice.mWaveDeviceID), mGlobalWaveHeader(1,GMEM_MOVEABLE|GMEM_ZEROINIT),
|
||||
mhWaveIn(0), mWindowHandler(someWaveInDevice.mWindowHandler), DeviceHandler(someWaveInDevice.mWindowHandler)
|
||||
{
|
||||
*this=someWaveInDevice;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveInDevice &WaveInDevice::operator=(const WaveInDevice &someWaveInDevice)
|
||||
{
|
||||
mWaveInCaps=someWaveInDevice.mWaveInCaps;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
WaveInDevice::~WaveInDevice()
|
||||
{
|
||||
closeDevice();
|
||||
}
|
||||
#endif
|
||||
140
sample/hold/WAVEOUT.CPP
Normal file
140
sample/hold/WAVEOUT.CPP
Normal file
@@ -0,0 +1,140 @@
|
||||
#include <sample/waveout.hpp>
|
||||
|
||||
WaveOutDevice::WaveOutDevice(UINT waveDeviceID,Window &windowHandler)
|
||||
: mWaveDeviceID(waveDeviceID), mhWaveOut(0),
|
||||
mGlobalWaveHeader(1,GMEM_MOVEABLE|GMEM_ZEROINIT),
|
||||
mWindowHandler(windowHandler), DeviceHandler(windowHandler),
|
||||
mDisposition(InClose)
|
||||
{
|
||||
::waveOutGetDevCaps(mWaveDeviceID,&((WAVEOUTCAPS&)mWaveOutCaps),sizeof(mWaveOutCaps));
|
||||
}
|
||||
|
||||
WaveOutDevice::WaveOutDevice(const WaveOutDevice &someWaveOutDevice)
|
||||
: mWindowHandler(someWaveOutDevice.mWindowHandler), mhWaveOut(0),
|
||||
mGlobalWaveHeader(1,GMEM_MOVEABLE|GMEM_ZEROINIT),
|
||||
mWaveDeviceID(someWaveOutDevice.mWaveDeviceID),
|
||||
DeviceHandler(someWaveOutDevice.mWindowHandler),
|
||||
mDisposition(someWaveOutDevice.mDisposition)
|
||||
{
|
||||
*this=someWaveOutDevice;
|
||||
}
|
||||
|
||||
WaveOutDevice::~WaveOutDevice()
|
||||
{
|
||||
closeDevice();
|
||||
}
|
||||
|
||||
WaveOutDevice &WaveOutDevice::operator=(const WaveOutDevice &someWaveOutDevice)
|
||||
{
|
||||
mWaveOutCaps=someWaveOutDevice.mWaveOutCaps;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BOOL WaveOutDevice::openDevice(WaveFormatPCM &waveFormatPCM)
|
||||
{
|
||||
MMRESULT mmResult;
|
||||
|
||||
closeDevice();
|
||||
mmResult=::waveOutOpen(&mhWaveOut,mWaveDeviceID,(LPWAVEFORMATEX)&waveFormatPCM,(UINT)((HWND)mWindowHandler),0L,WAVE_ALLOWSYNC|CALLBACK_WINDOW);
|
||||
if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;}
|
||||
mDisposition=InOpen;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WaveOutDevice::closeDevice(void)
|
||||
{
|
||||
MMRESULT mmResult;
|
||||
|
||||
if(!mhWaveOut||InClose==mDisposition)return TRUE;
|
||||
if(InPlay==mDisposition)
|
||||
{
|
||||
mmResult=::waveOutReset(mhWaveOut);
|
||||
if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;}
|
||||
}
|
||||
while(InPlay==mDisposition)mWindowHandler.yieldTask();
|
||||
mmResult=::waveOutClose(mhWaveOut);
|
||||
if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;}
|
||||
mDisposition=InClose;
|
||||
mhWaveOut=0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WaveOutDevice::pause(void)
|
||||
{
|
||||
MMRESULT mmResult;
|
||||
|
||||
if(InPlay!=mDisposition)return FALSE;
|
||||
if(0!=(mmResult=::waveOutPause(mhWaveOut))){mmSystemErrorMessage(mmResult);return FALSE;}
|
||||
mDisposition=InPause;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WaveOutDevice::restart(void)
|
||||
{
|
||||
MMRESULT mmResult;
|
||||
|
||||
if(InPause!=mDisposition)return FALSE;
|
||||
if(0!=(mmResult=::waveOutRestart(mhWaveOut))){mmSystemErrorMessage(mmResult);return FALSE;}
|
||||
mDisposition=InPlay;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WaveOutDevice::play(WaveForm &someWaveForm,DeviceHandler::PlayMode playMode)
|
||||
{
|
||||
MMRESULT mmResult;
|
||||
WaveFormatPCM waveFormatPCM((FormatChunk&)someWaveForm);
|
||||
if(WaveFormatEx::PulseCodeModulation!=waveFormatPCM.formatTag()){genericErrorMessage(InvalidFormat);return FALSE;}
|
||||
if(!openDevice(waveFormatPCM))return FALSE;
|
||||
((WaveHeader*)&mGlobalWaveHeader[0])->setData((char*)(((PureSample&)someWaveForm).sampleData()));
|
||||
((WaveHeader*)&mGlobalWaveHeader[0])->setBufferLength(((PureSample&)someWaveForm).numSamples());
|
||||
((WaveHeader*)&mGlobalWaveHeader[0])->userData((DWORD)this);
|
||||
mmResult=::waveOutPrepareHeader(mhWaveOut,(WAVEHDR*)((WaveHeader*)&mGlobalWaveHeader[0]),sizeof(WAVEHDR));
|
||||
if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;}
|
||||
mmResult=::waveOutWrite(mhWaveOut,(WAVEHDR*)((WaveHeader*)&mGlobalWaveHeader[0]),sizeof(WAVEHDR));
|
||||
if(mmResult){mmSystemErrorMessage(mmResult);return FALSE;}
|
||||
mDisposition=InPlay;
|
||||
if(mmResult){mmSystemErrorMessage(mmResult);unprepareHeader();return FALSE;}
|
||||
if(DeviceHandler::Wait==playMode)
|
||||
{
|
||||
while(InPlay==mDisposition)mWindowHandler.yieldTask();
|
||||
closeDevice();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void WaveOutDevice::unprepareHeader(void)
|
||||
{
|
||||
if(!mhWaveOut){genericErrorMessage(DeviceHandler::InvalidDeviceHandle);return;}
|
||||
if(!mGlobalWaveHeader.isOkay()){genericErrorMessage(DeviceHandler::InvalidHeader);return;}
|
||||
::waveOutUnprepareHeader(mhWaveOut,(WAVEHDR*)((WaveHeader*)&mGlobalWaveHeader[0]),sizeof(WaveHeader));
|
||||
}
|
||||
|
||||
// virtuals
|
||||
|
||||
void WaveOutDevice::openHandler(CallbackData &/*someCallbackData*/)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void WaveOutDevice::closeHandler(CallbackData &/*someCallbackData*/)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void WaveOutDevice::doneHandler(CallbackData &someCallbackData)
|
||||
{
|
||||
WaveHeader &waveHeader=(*((WaveHeader*)someCallbackData.lParam()));
|
||||
|
||||
if(waveHeader.userData()==(DWORD)this)
|
||||
{
|
||||
unprepareHeader();
|
||||
mDisposition=InIdle;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void WaveOutDevice::message(const String &strErrorMessage)const
|
||||
{
|
||||
::OutputDebugString((String&)strErrorMessage+String("\n"));
|
||||
}
|
||||
|
||||
52
sample/hold/WAVEOUT.HPP
Normal file
52
sample/hold/WAVEOUT.HPP
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef _SAMPLE_WAVEOUTDEVICE_HPP_
|
||||
#define _SAMPLE_WAVEOUTDEVICE_HPP_
|
||||
#ifndef _COMMON_WINDOW_HPP_
|
||||
#include <common/windows.hpp>
|
||||
#endif
|
||||
#ifndef _COMMON_GLOBALDATA_HPP_
|
||||
#include <common/gdata.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_DEVICEHANDLER_HPP_
|
||||
#include <sample/devhndlr.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEOUTCAPS_HPP_
|
||||
#include <sample/outcaps.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEHEADER_HPP_
|
||||
#include <sample/wavehdr.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEFORM_HPP_
|
||||
#include <sample/wave.hpp>
|
||||
#endif
|
||||
#ifndef _SAMPLE_WAVEFORMATPCM_HPP_
|
||||
#include <sample/pcmform.hpp>
|
||||
#endif
|
||||
|
||||
class WaveOutDevice : public DeviceHandler
|
||||
{
|
||||
public:
|
||||
WaveOutDevice(UINT waveDeviceID,Window &windowHander);
|
||||
WaveOutDevice(const WaveOutDevice &someWaveOutDevice);
|
||||
virtual ~WaveOutDevice();
|
||||
WaveOutDevice &operator=(const WaveOutDevice &someWaveOutDevice);
|
||||
BOOL play(WaveForm &waveForm,DeviceHandler::PlayMode playMode=DeviceHandler::NoWait);
|
||||
BOOL pause(void);
|
||||
BOOL restart(void);
|
||||
protected:
|
||||
virtual void openHandler(CallbackData &someCallbackData);
|
||||
virtual void closeHandler(CallbackData &someCallbackData);
|
||||
virtual void doneHandler(CallbackData &someCallbackData);
|
||||
virtual void message(const String &strErrorMessage)const;
|
||||
private:
|
||||
enum Disposition{InPause,InPlay,InClose,InOpen,InIdle};
|
||||
BOOL openDevice(WaveFormatPCM &waveFormatPCM);
|
||||
BOOL closeDevice(void);
|
||||
void unprepareHeader(void);
|
||||
WaveOutCaps mWaveOutCaps;
|
||||
Window &mWindowHandler;
|
||||
UINT mWaveDeviceID;
|
||||
GlobalData<WaveHeader> mGlobalWaveHeader;
|
||||
HWAVEOUT mhWaveOut;
|
||||
Disposition mDisposition;
|
||||
};
|
||||
#endif
|
||||
56
sample/hold/fmtchnk.cpp
Normal file
56
sample/hold/fmtchnk.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <sample/fmtchnk.hpp>
|
||||
|
||||
FormatChunk &FormatChunk::operator=(const FormatChunk &someFormatChunk)
|
||||
{
|
||||
formatTag(someFormatChunk.formatTag());
|
||||
channels(someFormatChunk.channels());
|
||||
samplesPerSecond(someFormatChunk.samplesPerSecond());
|
||||
averageBytesPerSecond(someFormatChunk.averageBytesPerSecond());
|
||||
blockAlign(someFormatChunk.blockAlign());
|
||||
bitsPerSample(someFormatChunk.bitsPerSample());
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemFile &FormatChunk::operator>>(MemFile &someMemFile)const
|
||||
{
|
||||
mChunkID>>someMemFile;
|
||||
someMemFile.write((char*)&mSize,sizeof(mSize));
|
||||
someMemFile.write((char*)&mFormatTag,sizeof(mFormatTag));
|
||||
someMemFile.write((char*)&mChannels,sizeof(mChannels));
|
||||
someMemFile.write((char*)&mSamplesPerSecond,sizeof(mSamplesPerSecond));
|
||||
someMemFile.write((char*)&mAvgBytesPerSecond,sizeof(mAvgBytesPerSecond));
|
||||
someMemFile.write((char*)&mBlockAlign,sizeof(mBlockAlign));
|
||||
someMemFile.write((char*)&mBitsPerSample,sizeof(mBitsPerSample));
|
||||
if(mSize==sizeof(mFormatTag)+sizeof(mChannels)+sizeof(mSamplesPerSecond)+sizeof(mAvgBytesPerSecond)+sizeof(mBlockAlign)+sizeof(mBitsPerSample)+sizeof(mExtraInfo))someMemFile.write((char*)&mExtraInfo,sizeof(mExtraInfo));
|
||||
return someMemFile;
|
||||
}
|
||||
|
||||
FileHandle &FormatChunk::operator<<(FileHandle &someFileHandle)
|
||||
{
|
||||
mChunkID<<someFileHandle;
|
||||
someFileHandle.read((BYTE*)&mSize,sizeof(mSize));
|
||||
someFileHandle.read((BYTE*)&mFormatTag,sizeof(mFormatTag));
|
||||
someFileHandle.read((BYTE*)&mChannels,sizeof(mChannels));
|
||||
someFileHandle.read((BYTE*)&mSamplesPerSecond,sizeof(mSamplesPerSecond));
|
||||
someFileHandle.read((BYTE*)&mAvgBytesPerSecond,sizeof(mAvgBytesPerSecond));
|
||||
someFileHandle.read((BYTE*)&mBlockAlign,sizeof(mBlockAlign));
|
||||
someFileHandle.read((BYTE*)&mBitsPerSample,sizeof(mBitsPerSample));
|
||||
if(mSize==sizeof(mFormatTag)+sizeof(mChannels)+sizeof(mSamplesPerSecond)+sizeof(mAvgBytesPerSecond)+sizeof(mBlockAlign)+sizeof(mBitsPerSample)+sizeof(mExtraInfo))someFileHandle.read((BYTE*)&mExtraInfo,sizeof(mExtraInfo));
|
||||
return someFileHandle;
|
||||
}
|
||||
|
||||
String FormatChunk::toString(void)const
|
||||
{
|
||||
String strChunk;
|
||||
strChunk+=String("<FORMATCHUNK>");
|
||||
strChunk+=mChunkID.toString();
|
||||
strChunk+=String(" Size=")+String().fromInt(mSize).quotes();
|
||||
strChunk+=String(" FormatTag=")+String().fromInt(mFormatTag).quotes();
|
||||
strChunk+=String(" Channels=")+String().fromInt(mChannels).quotes();
|
||||
strChunk+=String(" SamplesPerSecond=")+String().fromInt(mSamplesPerSecond).quotes();
|
||||
strChunk+=String(" AvgBytesPerSecond=")+String().fromInt(mAvgBytesPerSecond).quotes();
|
||||
strChunk+=String(" BlockAlign=")+String().fromInt(mBlockAlign).quotes();
|
||||
strChunk+=String(" BitsPerSample=")+String().fromInt(mBitsPerSample).quotes();
|
||||
strChunk+=String(" ExtraInfo=")+String().fromInt(mExtraInfo).quotes()+String("</FORMATCHUNK>");
|
||||
return strChunk;
|
||||
}
|
||||
Reference in New Issue
Block a user