/** 
 * \file Sound.h
 * \brief Header file containing CSound class - encapsulation class for DirectSound.
 * It uses CWaveFile for playing wav files, providing user only simple 'Init and Play' interface.
 * 
 * \author Petar Bajic, MPE (C) All Rights Reserved, Homepage: www.mystic-peanut.com
 * \date January, 16 2007.
 */

#include <Windows.h>
#include "d3dx9.h"
#include <dsound.h>

#ifndef MPE_SOUND
#define MPE_SOUND

#ifndef V
#define V(x)           { hr = x; }
#endif
#ifndef V_RETURN
#define V_RETURN(x)    { hr = x; if( FAILED(hr) ) { return hr; } }
#endif

#ifndef SAFE_DELETE
#define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } }
#endif    
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p);   (p)=NULL; } }
#endif    
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }
#endif

/**
 * \brief Encapsulates reading or writing sound data to or from a wave file.
 *
 * This class and its functions are taken from Microsoft DirectX 9.0c SDK (august 2005) Example on using DirectSound buffer.
 * \author Petar Bajic \date January, 16 2007.
 */
class CWaveFile
{
public:
    WAVEFORMATEX* m_pwfx;        // Pointer to WAVEFORMATEX structure
    HMMIO         m_hmmio;       // MM I/O handle for the WAVE
    MMCKINFO      m_ck;          // Multimedia RIFF chunk
    MMCKINFO      m_ckRiff;      // Use in opening a WAVE file
    DWORD         m_dwSize;      // The size of the wave file
    MMIOINFO      m_mmioinfoOut;
    BYTE*         m_pbData;
    BYTE*         m_pbDataCur;
    ULONG         m_ulDataSize;
    CHAR*         m_pResourceBuffer;

protected:
    HRESULT ReadMMIO();

public:
    CWaveFile();
    ~CWaveFile();

    HRESULT Open( LPWSTR strFileName);
    HRESULT Close();
    HRESULT Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead );
    DWORD   GetSize();
    HRESULT ResetFile();
};


/**
 * \brief Encapsulates functionality of a DirectSound buffer.
 *
 * \author Petar Bajic \date January, 16 2007.
 */
class CSound
{
protected:
    LPDIRECTSOUNDBUFFER* m_apDSBuffer;
    DWORD                m_dwDSBufferSize;
    CWaveFile*           m_pWaveFile;

public:
	CSound();
    ~CSound();

    bool Init(IDirectSound8* pDS, LPWSTR strWaveFileName);

    HRESULT Play();
    HRESULT Stop();
    HRESULT Reset();
    BOOL    IsSoundPlaying();
};

#endif //MPE_SOUND
