#ifndef __TDMADDON_H__
#define __TDMADDON_H__
#include <Windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")

enum {		// VOICE FORMAT
	AUDIO_CODEC_LINEAR = 0,		//线性编码，每个采样点2个字节
	AUDIO_CODEC_ULAW,			//uLaw编码，每个采样点1个字节
	AUDIO_CODEC_ALAW,			//aLaw编码，每个采样点1个字节
};

#define DEFAULT_AUDIO_LEN		80

class LCWaveSetting
{
public:
    LCWaveSetting();
    virtual ~LCWaveSetting();
	
public:
    DWORD TransWaveFileHead(LPCTSTR strFileName, LPVOID lpFMTBuf, DWORD dwBufSize);
    DWORD TransWaveDataHead(LPVOID lpWaveData, DWORD dwWaveSize, LPVOID lpFMTBuf, DWORD dwBufSize);
    DWORD Encode_IMA_ADPCM(LPVOID lpData, DWORD dwInSize, LPVOID pDataOut, DWORD dwOutSize, int nOriIndex = -1);
    DWORD Decode_IMA_ADPCM(LPVOID lpData, DWORD dwInSize, LPVOID pDataOut, DWORD dwOutSize);
private:
	int m_nEncIndex;
	int m_nDecIndex;
};

class CTDMAddon
{
public:
	CTDMAddon();
	virtual ~CTDMAddon();
public:
	UINT	m_AudioLen;
	BOOL	m_StartPlay;

public:		// For All
    BOOL	GetData(BYTE* pDataBuffer, UINT uiDataSize);
    BOOL	PutData(BYTE* pDataBuffer, UINT uiDataSize);

public:		// For Play
    BOOL LoadPcmFile(LPTSTR strFileName, BYTE byResType = AUDIO_CODEC_ULAW);
    BOOL LoadPcmResource(HMODULE hModule, UINT pcmResID, BYTE byResType = AUDIO_CODEC_ULAW, char* strResType = "PCM");
	BOOL LoadWaveFile(LPTSTR strFileName);
    BOOL LoadWaveResource(HMODULE hModule, UINT waveResID, char* strResType = "WAVE");
	BOOL SetPlayLoop(bool bLoop);
	bool GetPlayLoop();
    BOOL Play();
    BOOL Pause();
    BOOL SeekTo(DWORD pos);
    BOOL Stop();
    BOOL Close();

    DWORD GetLength();
    DWORD GetCurPos();
    BOOL  IsPlayFinished();
	BOOL  IsPlay();
	
public:		// For Record
    BOOL SaveToWaveFile(LPTSTR strFileName);
	BOOL SaveToPcmFile(LPTSTR strFileName, BYTE byResType = AUDIO_CODEC_ULAW);
	BOOL RecStart();
    BOOL RecStop();
    DWORD GetRecLength();

    void doPlay();
    void doRec();
	void*			pAddon;
protected:
    BOOL			PreLoad();
	HMMIO			m_hmmio;
	HMMIO			m_rmmio;
	BYTE			m_RunType;
	DWORD			m_CurrentPos;
	DWORD			m_TotalLength;
	BYTE			m_AudioType;
	DWORD			m_RecLength;
	BYTE*			m_pResBuf;
	BYTE*			m_pDataBuf;
	BYTE*			m_rDataBuf;

	BYTE*			m_LoopBuf;
	short			m_LoopLen;
	short			m_LoopPos;
	DWORD			m_DataBaseAddr;
	DWORD			m_nSamplesPerSec;
	WORD			m_nChannels;
	WORD			m_nResLen;
	WORD			m_nRecLen;
	enum {
		PLAY_NULL,
		PLAY_FILE_RAW_PCM,
		PLAY_FILE_WAV_PCM,
		PLAY_FILE_IMA_ADPCM,
		PLAY_MEM_RAW_PCM,
		PLAY_MEM_WAV_PCM,
		PLAY_MEM_IMA_ADPCM,
	} m_PlayMeth;

	enum {
		REC_NULL,
		REC_FILE_RAW_PCM,
		REC_FILE_WAV_PCM,
		REC_FILE_IMA_ADPCM,
	} m_RecMeth;
private:
    bool	m_bPlayRunning;
    bool	m_bRecRunning;
	BYTE*	m_playBuffer;
	UINT	m_playSize;
	BYTE*	m_recBuffer;
	UINT	m_recSize;
	bool    m_bLoop;
	LCWaveSetting	m_ImaCodec;
};

class  CTDMAudio 
{
public:
	CTDMAudio();
	virtual ~CTDMAudio();

public:		// For Play
    BOOL LoadPcmFile(LPTSTR strFileName, BYTE byResType = AUDIO_CODEC_ULAW);
    BOOL LoadPcmResource(HMODULE hModule, UINT pcmResID, BYTE byResType = AUDIO_CODEC_ULAW, char* strResType = "PCM");
	BOOL LoadWaveFile(LPTSTR strFileName);
    BOOL LoadWaveResource(HMODULE hModule, UINT waveResID, char* strResType = "WAVE");
    BOOL Play();
    BOOL Pause();
    BOOL SeekTo(DWORD pos);
    BOOL Stop();
    BOOL Close();
	BOOL SetPlayLoop(bool bLoop);
	bool GetPlayLoop();
	
    DWORD GetLength();
    DWORD GetCurPos();
    BOOL  IsPlayFinished();
	BOOL  IsPlay();
public:		// For Record
    BOOL SaveToWaveFile(LPTSTR strFileName);
	BOOL SaveToPcmFile(LPTSTR strFileName, BYTE byResType = AUDIO_CODEC_ULAW);
	BOOL RecStart();
    BOOL RecStop();
    DWORD GetRecLength();

public:		// For Echo Test
	BOOL GetData(BYTE* data, int len);
	BOOL PutData(BYTE* data, int len);
public:		// For Talking
 	void*			pAddon;
};

#endif
