// --------------------------------------------------------------
//
// Copyright (C) 2009 - All Rights Reserved.
//
// Author: LiuYin
// File: SoundBase
// Version: 1.0
// Date: 2009-8-10
//
// Purpose:
//
// --------------------------------------------------------------
#ifndef SoundBase_H
#define SoundBase_H
//
#include <Windows.h>
//
template <DWORD dwUnique>
class SoundBaseT
{
public:
SoundBaseT()
: m_lIOCounter(0)
{
}
~SoundBaseT()
{
}
private:
SoundBaseT(const SoundBaseT &);
SoundBaseT & operator = (const SoundBaseT &);
protected:
LONG m_lIOCounter;
};
//
typedef SoundBaseT<0> CSoundBase;
//
#endif
// --------------------------------------------------------------
//
// Copyright (C) 2009 - All Rights Reserved.
//
// Author: LiuYin
// File: SoundRecorder
// Version: 1.0
// Date: 2009-8-10
//
// Purpose:
//
// --------------------------------------------------------------
#ifndef SoundRecorderT_H
#define SoundRecorderT_H
//
#include "SoundBase.h"
//
#pragma comment(lib, "WinMM")
//
template <DWORD dwUnique>
class SoundRecorderT : public CSoundBase
{
public:
SoundRecorderT()
: m_hWaveIn(NULL)
{
}
virtual ~SoundRecorderT()
{
Close();
}
BOOL Open(LPCWAVEFORMATEX lpWaveFormat)
{
return (!IsOpen() && (lpWaveFormat != NULL) && (::waveInOpen(&m_hWaveIn, WAVE_MAPPER, lpWaveFormat, (DWORD) SoundRecordCallback, (DWORD) this, CALLBACK_FUNCTION) != MMSYSERR_NOERROR));
}
BOOL IsOpen() const
{
return (m_hWaveIn != NULL);
}
BOOL Close()
{
BOOL bRet = FALSE;
if (!IsOpen()) {
goto Exit;
}
while (InterlockedCompareExchange(&m_lIOCounter, 0, 0)) {
Sleep(32);
}
::waveInReset(m_hWaveIn);
::waveInClose(m_hWaveIn);
m_hWaveIn = NULL;
bRet = TRUE;
Exit:
return bRet;
}
BOOL Record(PWAVEHDR pWaveHeader)
{
BOOL bRet = FALSE;
if (!IsOpen() || (pWaveHeader->lpData == NULL) || (pWaveHeader->dwBufferLength == 0)) {
goto Exit;
}
InterlockedIncrement(&m_lIOCounter);
if (::waveInPrepareHeader(m_hWaveIn, pWaveHeader, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
goto Exit;
}
if (::waveInAddBuffer(m_hWaveIn, pWaveHeader, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
goto Exit;
}
bRet = TRUE;
Exit:
if (!bRet) {
InterlockedDecrement(&m_lIOCounter);
}
return bRet;
}
protected:
SoundRecorderT(const SoundRecorderT &soundRecorder);
SoundRecorderT & operator = (const SoundRecorderT &soundRecorder);
virtual VOID OnRecordDone(PWAVEHDR pWaveHeader) {}
private:
VOID OnOpen(HWAVEIN hWaveIn, UINT nMessage, DWORD wParam, DWORD lParam) {}
VOID OnData(HWAVEIN hWaveIn, UINT nMessage, DWORD wParam, DWORD lParam)
{
PWAVEHDR pWaveHeader = (PWAVEHDR) wParam;
if ((pWaveHeader == NULL) || (pWaveHeader->dwBufferLength == 0)) {
goto Exit;
}
::waveInUnprepareHeader(m_hWaveIn, pWaveHeader, sizeof(WAVEHDR));
OnRecordDone(pWaveHeader);
Exit:
InterlockedDecrement(&m_lIOCounter);
}
VOID OnClose(HWAVEIN hWaveIn, UINT nMessage, DWORD wParam, DWORD lParam) {}
static VOID CALLBACK SoundRecordCallback(HWAVEIN hWaveIn, UINT nMessage, DWORD dwUserData, DWORD wParam, DWORD lParam)
{
SoundRecorderT *pRecorder = (SoundRecorderT *) dwUserData;
switch (nMessage) {
case WIM_OPEN:
pRecorder->OnOpen(hWaveIn, nMessage, wParam, lParam);
break;
case WIM_DATA:
pRecorder->OnData(hWaveIn, nMessage, wParam, lParam);
break;
case WIM_CLOSE:
pRecorder->OnClose(hWaveIn, nMessage, wParam, lParam);
break;
}
}
private:
HWAVEIN m_hWaveIn;
};
//
#endif
// --------------------------------------------------------------
//
// Copyright (C) 2009 - All Rights Reserved.
//
// Author: LiuYin
// File: SoundPlayer
// Version: 1.0
// Date: 2009-8-10
//
// Purpose:
//
// --------------------------------------------------------------
#ifndef SoundPlayerT_H
#define SoundPlayerT_H
//
#include "SoundBase.h"
//
#pragma comment(lib, "WinMM")
//
template <DWORD dwUnique>
class SoundPlayerT : public CSoundBase
{
public:
SoundPlayerT()
: m_hWaveOut(NULL)
{
}
virtual ~SoundPlayerT()
{
Close();
}
BOOL Open(LPCWAVEFORMATEX lpWaveFormat)
{
return (!IsOpen() && (lpWaveFormat != NULL) && (::waveOutOpen(&m_hWaveOut, WAVE_MAPPER, lpWaveFormat, (DWORD) SoundPlayCallback, (DWORD) this, CALLBACK_FUNCTION) != MMSYSERR_NOERROR));
}
BOOL IsOpen() const
{
return (m_hWaveOut != NULL);
}
BOOL Close()
{
BOOL bRet = FALSE;
if (!IsOpen()) {
goto Exit;
}
while (InterlockedCompareExchange(&m_lIOCounter, 0, 0)) {
Sleep(32);
}
::waveOutReset(m_hWaveOut);
::waveOutClose(m_hWaveOut);
m_hWaveOut = NULL;
bRet = TRUE;
Exit:
return bRet;
}
BOOL Play(PWAVEHDR pWaveHeader)
{
BOOL bRet = FALSE;
if (!IsOpen() || (pWaveHeader->lpData == NULL) || (pWaveHeader->dwBufferLength == 0)) {
goto Exit;
}
InterlockedIncrement(&m_lIOCounter);
if (::waveOutPrepareHeader(m_hWaveOut, pWaveHeader, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
goto Exit;
}
if (::waveOutWrite(m_hWaveOut, pWaveHeader, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
goto Exit;
}
bRet = TRUE;
Exit:
if (!bRet) {
InterlockedDecrement(&m_lIOCounter);
}
return bRet;
}
protected:
SoundPlayerT(const SoundPlayerT &soundPlayer);
SoundPlayerT & operator = (const SoundPlayerT &soundPlayer);
virtual VOID OnPlayDone(PWAVEHDR pWaveHeader) {}
private:
VOID OnOpen(HWAVEOUT hWaveOut, UINT nMessage, DWORD wParam, DWORD lParam) {}
VOID OnDone(HWAVEOUT hWaveOut, UINT nMessage, DWORD wParam, DWORD lParam)
{
PWAVEHDR pWaveHeader = (PWAVEHDR) wParam;
if ((pWaveHeader == NULL) || (pWaveHeader->dwBufferLength == 0)) {
goto Exit;
}
::waveOutUnprepareHeader(m_hWaveOut, pWaveHeader, sizeof(WAVEHDR));
OnPlayDone(pWaveHeader);
Exit:
InterlockedDecrement(&m_lIOCounter);
}
VOID OnClose(HWAVEOUT hWaveOut, UINT nMessage, DWORD wParam, DWORD lParam) {}
static VOID CALLBACK SoundPlayCallback(HWAVEOUT hWaveOut, UINT nMessage, DWORD dwUserData, DWORD wParam, DWORD lParam)
{
SoundPlayerT *pPlayer = (SoundPlayerT *) dwUserData;
switch (nMessage) {
case WOM_OPEN:
pPlayer->OnOpen(hWaveOut, nMessage, wParam, lParam);
break;
case WOM_DONE:
pPlayer->OnDone(hWaveOut, nMessage, wParam, lParam);
break;
case WOM_CLOSE:
pPlayer->OnClose(hWaveOut, nMessage, wParam, lParam);
break;
}
}
private:
HWAVEOUT m_hWaveOut;
};
//
#endif
#ifndef SoundPlayer_H
#define SoundPlayer_H
//
#include <Windows.h>
#include <MMSystem.h>
//
typedef VOID (WINAPI *PlayDoneT)(HANDLE hHandle, DWORD dwContext, PWAVEHDR pWaveHeader);
//
DWORD WINAPI SP_Initialize(LPHANDLE lpHandle, PlayDoneT playDone, DWORD dwContext);
DWORD WINAPI SP_Open(HANDLE hHandle, LPCWAVEFORMATEX lpWaveFormat);
DWORD WINAPI SP_Play(HANDLE hHandle, PWAVEHDR pWaveHeader);
DWORD WINAPI SP_Close(HANDLE hHandle);
DWORD WINAPI SP_Uninitialize(HANDLE hHandle);
//
#endif
//
#include "SoundPlayer.h"
#include "OwnerPolicy.h"
#include "SoundPlayerT.h"
//
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
switch (dwReasonForCall) {
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//
class CSoundPlayer : public SoundPlayerT<0>
{
public:
DWORD Initialize(PlayDoneT playDone, DWORD dwContext)
{
m_dwContext = dwContext;
m_playDone = playDone;
return ERROR_SUCCESS;
}
protected:
void OnPlayDone(PWAVEHDR pWaveHeader)
{
if (m_playDone != NULL) {
m_playDone(this, m_dwContext, pWaveHeader);
}
}
private:
DWORD m_dwContext;
PlayDoneT m_playDone;
};
//
DWORD WINAPI SP_Initialize(LPHANDLE lpHandle, PlayDoneT playDone, DWORD dwContext)
{
if ((lpHandle == NULL) || (playDone == NULL)) {
return ERROR_INVALID_PARAMETER;
}
CSoundPlayer *pSoundPlayer = new CSoundPlayer;
*lpHandle = pSoundPlayer;
if (pSoundPlayer == NULL) {
return ERROR_NOT_ENOUGH_MEMORY;
}
return pSoundPlayer->Initialize(playDone, dwContext);
}
DWORD WINAPI SP_Open(HANDLE hHandle, LPCWAVEFORMATEX lpWaveFormat)
{
CSoundPlayer *pSoundPlayer = (CSoundPlayer *) hHandle;
if ((pSoundPlayer == NULL) || (lpWaveFormat == NULL)) {
return ERROR_INVALID_PARAMETER;
}
return pSoundPlayer->Open(lpWaveFormat);
}
DWORD WINAPI SP_Play(HANDLE hHandle, PWAVEHDR pWaveHeader)
{
CSoundPlayer *pSoundPlayer = (CSoundPlayer *) hHandle;
if ((pSoundPlayer == NULL) || (pWaveHeader == NULL)) {
return ERROR_INVALID_PARAMETER;
}
return pSoundPlayer->Play(pWaveHeader);
}
DWORD WINAPI SP_Close(HANDLE hHandle)
{
CSoundPlayer *pSoundPlayer = (CSoundPlayer *) hHandle;
if (pSoundPlayer == NULL) {
return ERROR_INVALID_PARAMETER;
}
return pSoundPlayer->Close();
}
DWORD WINAPI SP_Uninitialize(HANDLE hHandle)
{
CSoundPlayer *pSoundPlayer = (CSoundPlayer *) hHandle;
if (pSoundPlayer == NULL) {
return ERROR_INVALID_PARAMETER;
}
delete pSoundPlayer;
pSoundPlayer = NULL;
return ERROR_SUCCESS;
}
#ifndef SoundRecorder_H
#define SoundRecorder_H
//
#include <Windows.h>
#include <MMSystem.h>
//
typedef VOID (WINAPI *RecordDoneT)(HANDLE hHandle, DWORD dwContext, PWAVEHDR pWaveHeader);
//
DWORD WINAPI SR_Initialize(LPHANDLE lpHandle, RecordDoneT recordDone, DWORD dwContext);
DWORD WINAPI SR_Open(HANDLE hHandle, LPCWAVEFORMATEX lpWaveFormat);
DWORD WINAPI SR_Record(HANDLE hHandle, PWAVEHDR pWaveHeader);
DWORD WINAPI SR_Close(HANDLE hHandle);
DWORD WINAPI SR_Uninitialize(HANDLE hHandle);
//
#endif
//
#include "SoundRecorder.h"
#include "OwnerPolicy.h"
#include "SoundRecorderT.h"
//
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
switch (dwReasonForCall) {
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//
class CSoundRecorder : public SoundRecorderT<0>
{
public:
DWORD Initialize(RecordDoneT recordDone, DWORD dwContext)
{
m_dwContext = dwContext;
m_recordDone= recordDone;
return ERROR_SUCCESS;
}
protected:
void OnRecordDone(PWAVEHDR pWaveHeader)
{
if (m_recordDone != NULL) {
m_recordDone(this, m_dwContext, pWaveHeader);
}
}
private:
DWORD m_dwContext;
RecordDoneT m_recordDone;
};
//
DWORD WINAPI SR_Initialize(LPHANDLE lpHandle, RecordDoneT recordDone, DWORD dwContext)
{
if ((lpHandle == NULL) || (recordDone == NULL)) {
return ERROR_INVALID_PARAMETER;
}
CSoundRecorder *pSoundRecorder = new CSoundRecorder;
*lpHandle = pSoundRecorder;
if (pSoundRecorder == NULL) {
return ERROR_NOT_ENOUGH_MEMORY;
}
return pSoundRecorder->Initialize(recordDone, dwContext);
}
DWORD WINAPI SR_Open(HANDLE hHandle, LPCWAVEFORMATEX lpWaveFormat)
{
CSoundRecorder *pSoundRecorder = (CSoundRecorder *) hHandle;
if ((pSoundRecorder == NULL) || (lpWaveFormat == NULL)) {
return ERROR_INVALID_PARAMETER;
}
return pSoundRecorder->Open(lpWaveFormat);
}
DWORD WINAPI SR_Record(HANDLE hHandle, PWAVEHDR pWaveHeader)
{
CSoundRecorder *pSoundRecorder = (CSoundRecorder *) hHandle;
if ((pSoundRecorder == NULL) || (pWaveHeader == NULL)) {
return ERROR_INVALID_PARAMETER;
}
return pSoundRecorder->Record(pWaveHeader);
}
DWORD WINAPI SR_Close(HANDLE hHandle)
{
CSoundRecorder *pSoundRecorder = (CSoundRecorder *) hHandle;
if (pSoundRecorder == NULL) {
return ERROR_INVALID_PARAMETER;
}
return pSoundRecorder->Close();
}
DWORD WINAPI SR_Uninitialize(HANDLE hHandle)
{
CSoundRecorder *pSoundRecorder = (CSoundRecorder *) hHandle;
if (pSoundRecorder == NULL) {
return ERROR_INVALID_PARAMETER;
}
delete pSoundRecorder;
pSoundRecorder = NULL;
return ERROR_SUCCESS;
}