#include <mmsystem.h>
#include <mmreg.h>
#include <dsound.h>

#if !defined(__ATPDIRECTSOUND_H__)
#define __ATPDIRECTSOUND_H__


// Wave mode
// This is the same as the declarations in VAIBODef.h, such as ATP16K_16BIT_STEREO.
enum {
	eWaveMode16k16bStereo,		// 16kHz/16Bit/Stereo 
	eWaveMode16k16bMonoL,		// 16kHz/16Bit/Mono-L 
	eWaveMode16k16bMonoR,		// 16kHz/16Bit/Mono-R 
	eWaveMode16k16bMonoMix,		// 16kHz/16Bit/Mono-Mix 

	eWaveMode8k16bStereo,		//  8kHz/16Bit/Stereo 
	eWaveMode8k16bMonoL,		//  8kHz/16Bit/Mono-L 
	eWaveMode8k16bMonoR,		//  8kHz/16Bit/Mono-R 
	eWaveMode8k16bMonoMix,		//  8kHz/16Bit/Mono-Mix 

	eWaveMode16k8bStereo,		// 16kHz/ 8Bit/Stereo 
	eWaveMode16k8bMonoR,		// 16kHz/ 8Bit/Mono-L 
	eWaveMode16k8bMonoL,		// 16kHz/ 8Bit/Mono-R 
	eWaveMode16k8bMonoMix,		// 16kHz/ 8Bit/Mono-Mix 

	eWaveMode8k8bStereo,		//  8kHz/ 8Bit/Stereo 
	eWaveMode8k8bMonoR,			//  8kHz/ 8Bit/Mono-L 
	eWaveMode8k8bMonoL,			//  8kHz/ 8Bit/Mono-R 
	eWaveMode8k8bMonoMix		//  8kHz/ 8Bit/Mono-Mix 
};

// Define 
#define		PLAYBUFF_TIME			( 1 )		// The duration (Sec) of the play buffer
#define		CAPTUREBUFF_TIME		( 1 )		// The duration (Sec) of the capture buffer
#define		CAPTURE_UNIT_SIZE		( 4096 )	// Capture unit 

// The thread function that the capture notices are sent to
DWORD WINAPI	GetCaptureThread( LPVOID lpParam );

// DirectSound Wrapper class 
#ifdef _VAIBO_DLLEXPORT
class __declspec( dllexport ) CATPDirectSound {
#else
class __declspec( dllimport ) CATPDirectSound {
#endif // _VAIBO_DLLEXPORT 

private:

	// DirectSound 
	LPDIRECTSOUND				m_pDS;					// DirectSound object 
	LPDIRECTSOUNDBUFFER			m_pPrimaryBuff;			// A primary sound buffer 

	// Secondary buffer 
	LPDIRECTSOUNDBUFFER			m_pSecondaryBuff;
	DWORD						m_dwWriteBufferSize;	// Writing buffer size 
	DWORD						m_dwWriteOffset;		// Writing offset 


	// Capture 
	LPDIRECTSOUNDCAPTURE		m_pDSCapture;			// Capture object 
	LPDIRECTSOUNDCAPTUREBUFFER	m_pDSCBuffer;			// Capture buffer 
	DWORD						m_dwCaptureSize;		// Capture buffer size 
	DWORD						m_dwCaptureOffset;		// Capture offset 
	BOOL						m_isCapture;			// During capture, flag serves to inform Capture thread of the end of the capture.

	// A notice object for the capture 
	LPDIRECTSOUNDNOTIFY			m_pDSNotify;
	DSBPOSITIONNOTIFY*			m_pDSNotifyPos;			// Notice position
	HANDLE						m_hDSNotifyEvent[ 2 ];	// Occurrence event 
	int							m_nNotifySize;			// The interval of notice position
	int							m_nNotifyPointNum;		// The number of notice position

	// Capture thread 
	HANDLE	m_hCaptureThread;		// HANDLE 
	DWORD	m_dwCaptureThreadID;	// ID 

	// The function of the user definition called when a capture event occurs
	BOOL	( *m_pCaptureProc )( void* pCaptureData, DWORD dwCaptureLength, BOOL isEnd, void* pParam );
	void*	m_pCaptureProcParam;	// parameter 

public:

	// Constructor/Destructor 
	CATPDirectSound();
	~CATPDirectSound();

	// Initialize 
	BOOL	Init( HWND hAppWnd );
	// Start playing sound (AIBO -> PC)
	BOOL	StartPlay( int nMode );
	// End playing sound (AIBO -> PC)
	BOOL	EndPlay();
	// Input wave data to play 
	BOOL	PlayWaveData( char* pData, int nSize );
	// Start capturing sound 
	BOOL	CATPDirectSound::StartCapture( int nMode, BOOL ( *pCaptureProc )( void* pCaptureData, DWORD dwCaptureLength, BOOL isEnd, void* pParam ), void* pParam );
	// End capturing sound 
	BOOL	CATPDirectSound::EndCapture();


	// Internal use
	void	MakeWaveFomat( int nMode, WAVEFORMATEX* pWaveFormat );
	HANDLE*	GetNotifyEvent();
	BOOL	CATPDirectSound::GetCaptureFlag();
	BOOL	GetCaptureData( BOOL isEnd = false );
	void	SetCaptureOffset( DWORD dwOffset );
	void	AddCaptureOffset( DWORD dwAdd );
	BOOL	GetCaptureDataArea( DWORD* pReadOffset, DWORD* pLockSize );
	BOOL	LockCaptureDataArea( DWORD dwReadOffset, DWORD dwLockSize, void* pCaptureData[ 2 ], DWORD dwCaptureLength[ 2 ] );
	BOOL	UnLockCaptureDataArea( void* pCaptureData, DWORD dwCaptureLength );
	void	DoCaptureProc( void* pCaptureData, DWORD dwCaptureLength, BOOL isEnd = false );

};


#endif // __ATPDIRECTSOUND_H__ 

