2025-11-27 16:46:48 +09:00

361 lines
9.6 KiB
C++

// ==========================================================================
// Class Specification : COXSound
// ==========================================================================
//
// Version: 9.3
//
// This software along with its related components, documentation and files ("The Libraries")
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office. For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
//
// //////////////////////////////////////////////////////////////////////////
// Properties:
//
// NO Abstract class (does not have any objects)
// YES Derived from CObject
// NO Is a CWnd
// NO Two stage creation (constructor & Create())
// NO Has a message map
// NO Needs a resource template
//
// NO Persistant objects
// NO Uses exceptions
// //////////////////////////////////////////////////////////////////////////
// Description :
// The COXSound class is an easy way to have an application play WAVE sounds.
// WAVES can be loaded from WAVE files (*.wav), WAVE resources or
// streamed in from a CFile object.
// Once a wave is loaded it may be played either synchronously or asynchronously.
// In the case of the latter, the sound may be looped.
// Remark :
// Prerequisites (necessary conditions):
/////////////////////////////////////////////////////////////////////////////
#ifndef __OXSOUND_H__
#define __OXSOUND_H__
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "OXDllExt.h"
#ifndef __AFXTEMPL_H__
#include <afxtempl.h>
#endif
#ifndef __OXMFCPRIV_H__
#include "..\include\afxpriv.h"
#define __OXMFCPRIV_H__
#endif
#ifndef __OXMFCIMPL_H__
#if _MFC_VER < 0x0700
#include <..\src\afximpl.h>
#else
#include <..\src\mfc\afximpl.h>
#endif
#define __OXMFCIMPL_H__
#endif
#pragma warning(disable : 4201)
#include <mmsystem.h>
#include "OXSoundWnd.h"
#include "OXMainRes.h"
#include "UTB64Bit.h"
// ... Make sure linker uses the the multi media library
#pragma comment(lib, "winmm.lib ")
// all possible sound sources
//
enum SoundSource
{
SNDSRC_FILE=0,
SNDSRC_CFILE=1,
SNDSRC_INTRESOURCE=2,
SNDSRC_UNKNOWN=3
};
//
// Following are defined:
//
// SNDSRC_FILE - name of the file
// SNDSRC_CFILE - pointer to opened CFile
// SNDSRC_INTRESOURCE - resource ID
// SNDSRC_UNKNOWN - unknown source, used to initialize variables
//
////////////////////////////////////////////////////////////////////////////
// Following structure was defined specifically to save information about
// the sound source
//
typedef struct _tagSOUNDSOURCEINFO
{
enum SoundSource source;
HINSTANCE hInstance;
UINT nResourceID;
CString sFileName;
// constructor
_tagSOUNDSOURCEINFO()
{
Reset();
}
// destructor
void Reset()
{
source=SNDSRC_UNKNOWN;
hInstance=NULL;
sFileName=_T("");
nResourceID=0;
}
// serialization
void Serialize(CArchive& ar)
{
// Only CObject-derived objects and six data-type
// primitives are serializable. However, you
// can cast any data type to a serializable data type,
// and then you can serialize your data. The serializable
// data types are
// BYTE: 8 bits unsigned
// WORD: 16 bits unsigned
// LONG: 32 bits unsigned
// DWORD: 32 bits unsigned
// float 32 bits
// double 64 bits, IEEE standard
if (ar.IsStoring())
{
ar << (DWORD)source;
ar << (DWORD)PtrToUlong(hInstance);
ar << (DWORD)nResourceID;
ar << sFileName;
}
else
{
DWORD dwDummy;
ar >> dwDummy;
if(dwDummy!=(DWORD)SNDSRC_CFILE)
{
source=(enum SoundSource)dwDummy;
ar >> dwDummy;
hInstance=(HINSTANCE)(INT_PTR)dwDummy;
ar >> dwDummy;
nResourceID=(UINT)dwDummy;
ar >> sFileName;
}
}
}
// assignment operator
_tagSOUNDSOURCEINFO& operator=( const _tagSOUNDSOURCEINFO& ssi )
{
if(this==&ssi)
return *this;
source=ssi.source;
hInstance=ssi.hInstance;
nResourceID=ssi.nResourceID;
sFileName=ssi.sFileName;
return *this;
}
} SOUNDSOURCEINFO, * LPSOUNDSOURCEINFO;
//
// Below you will find the description of all structure's elements:
//
// source - type of sound source. Refere to the description of
// enum SoundSource for details
// hInstance - handle of the instance that contains the nResourceID
// resource if source==SNDSRC_INTRESOURCE, otherwise
// it is not used
// nResourceID - resource ID that is used as sound source; valid only
// if source==SNDSRC_INTRESOURCE, otherwise it is not used
// sFileName - name of the file that is used as sound source; valid only
// if source==SNDSRC_FILE, otherwise it is not used
//
////////////////////////////////////////////////////////////////////////////
class OX_CLASS_DECL COXSound : public CObject
{
friend class COXSoundWnd;
DECLARE_SERIAL(COXSound);
// Data members --------------------------------------------
public:
protected:
static CMap<COXSound*, COXSound*, DWORD, DWORD> m_allSoundObjects;
HWND m_hCallbackWnd;
UINT m_nRes;
CString m_sFilename;
HGLOBAL m_hWave;
LPVOID m_lpWave;
BOOL m_bIsPlaying;
BOOL m_bIsLoaded;
BOOL m_bLooping;
MMRESULT m_mmLastResult;
LPVOID m_lpWaveData;
WAVEHDR m_waveHdr;
LPWAVEHDR m_lpWaveHdr;
HWAVEOUT m_hWaveOut;
WAVEFORMATEX m_waveFormatEx;
SOUNDSOURCEINFO m_SoundSourceInfo;
private:
// Member functions --------------------------------------------
public:
// --- In:
// --- Out:
// --- Returns:
// --- Effect: Constructor
COXSound();
// --- In: pCallbackWnd : CWnd which notification messages are sent
// --- Out:
// --- Returns:
// --- Effect: Stores the callback CWnd for notification messages
void SetCallbackWnd(CWnd* pCallbackWnd);
// --- In:
// --- Out:
// --- Returns: BOOL : TRUE if wave playback device exists
// --- Effect: Determines if any wave playback devices exist
static BOOL CanPlay();
// --- In: pszFilename : complete path and filename for a WAVE file
// --- Out:
// --- Returns: BOOL : TRUE if the file is opened successfully
// --- Effect: Opens a WAVE file and loads data
BOOL Open(LPCTSTR pszFileName);
// --- In: nSoundResource : Resource ID for a WAVE resource
// hResInstance : Instance handle for resource (defaults to current executable)
// --- Out:
// --- Returns: BOOL - TRUE if the wave resource is opened
// --- Effect: Opens a WAVE resource and loads its data
BOOL Open(UINT nSoundResource, HINSTANCE hResInstance = AfxGetResourceHandle());
// --- In: pOpenedFile : CFile object from which to read WAVE data
// --- Out:
// --- Returns: BOOL : TRUE if the file is opened successfully
// --- Effect: Streams in WAVE data from an existing CFile object
BOOL Open(CFile* pOpenedFile);
// --- In: bLoop : Boolean flag to specify if the wave should loop (only works on async playback)
// bAsync : Boolean flag to specify if the wave should be played asynchronously
// --- Out:
// --- Returns: BOOL : TRUE if the WAVE is played successfully
// --- Effect: Plays a loaded WAVE
BOOL Play(BOOL bLoop = FALSE, BOOL bAsync = TRUE);
// --- In:
// --- Out:
// --- Returns:
// --- Effect: Stops a playing wave
void Stop();
// --- In:
// --- Out:
// --- Returns: BOOL : TRUE if a wave is loaded
// --- Effect: Determines if any wave data is loaded
BOOL IsWaveLoaded() const;
// --- In:
// --- Out:
// --- Returns: BOOL : TRUE if a wave is playing
// --- Effect: Determines if any wave is being played
BOOL IsPlaying() const;
// --- In:
// --- Out: waveFormatEx : WAVEFORMATEX structure to receive data
// --- Returns: BOOL : TRUE if the WAVEFORMATEX structure is valid
// --- Effect: Gets format information about the loaded WAVE
BOOL GetWaveFormat(WAVEFORMATEX* waveFormatEx);
// --- In:
// --- Out:
// --- Returns: The last multi media error that has occured
// --- Effect:
MMRESULT GetLastMMError() const;
// --- In: hResult : MMRESULT for which to get the error description
// --- Out: szDesc : Return buffer for text message
// --- Returns:
// --- Effect: Utility function which gets a text message for a passed MMRESULT
static void GetErrorText(MMRESULT hResult, CString& sDesc);
// --- In:
// --- Out: pMMTime : MMTIME structure which returns the current position of the playing WAVE
// --- Returns:
// --- Effect: Gets the current position of the playing WAVE
BOOL GetCurrentPosition(MMTIME* pMMTime) const;
// --- In:
// --- Out:
// --- Returns:
// --- Effect: Handles callback processing for COXSound - called from the callback window.
void HandleCallback();
// --- In:
// --- Out:
// --- Returns: pointer to the sound source info structure
// --- Effect:
inline LPSOUNDSOURCEINFO GetSoundSourceInfo() { return &m_SoundSourceInfo; }
// --- In:
// --- Out:
// --- Returns:
// --- Effect: Destructor
virtual ~COXSound();
protected:
void FreeMem();
void FreeBuffer();
static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uiMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
BOOL PrepareWaveHeader();
BOOL PlayWithCallback();
BOOL ParseWaveData(void* pvRes, WAVEFORMATEX** ppWaveHeader, BYTE** ppbWaveData, DWORD* pcbWaveSize);
void CloseWaveOutDevice();
LPVOID GlobalAllocPtr(UINT uiFlags, DWORD dwBytes) ;
void GlobalFreePtr(LPVOID pPtr) ;
BOOL CanPlayLoadedData();
private:
public:
virtual void Serialize(CArchive& ar);
};
#endif // __OXSOUND_H__