Click here to Skip to main content
15,895,799 members
Articles / Multimedia / DirectX

DirectSound Wrapper Classes

Rate me:
Please Sign up or sign in to vote.
4.79/5 (20 votes)
6 Aug 2006CPOL4 min read 130.4K   4.5K   38  
An article on multimedia - playing Waves by using the DirectSound component.
// Wave.cpp

#include "StdAfx.h"
#include "Wave.h"
#include "MMIO.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif


CWave::CWave() : m_dwImageLen(0)
				,m_bResource(FALSE)
				,m_pImageData(NULL)
{
}

CWave::CWave(LPCTSTR lpszFileName) : m_dwImageLen(0)
									,m_bResource(FALSE)
									,m_pImageData(NULL)
{
	Create(lpszFileName);
}

CWave::CWave(UINT uiResID, HMODULE hmod) : m_dwImageLen(0)
										,m_bResource(TRUE)
										,m_pImageData(NULL)
{
	Create(uiResID, hmod);
}

CWave::~CWave()
{
	Free();
}

BOOL CWave::Create(LPCTSTR lpszFileName)
{
	// Free any previous wave image data
	Free();

	// Flag as regular memory
	m_bResource = FALSE;

	// Open the wave file
	CFile fileWave;
	if (!fileWave.Open(lpszFileName, CFile::modeRead))
		return FALSE;

	// Get the file length
	m_dwImageLen = fileWave.GetLength();

	// Allocate and lock memory for the image data
	m_pImageData = (BYTE*)::GlobalLock(::GlobalAlloc(GMEM_MOVEABLE |
	GMEM_SHARE, m_dwImageLen));
	if (!m_pImageData)
		return FALSE;

	// Read the image data from the file
	fileWave.Read(m_pImageData, m_dwImageLen);

	return TRUE;
}

BOOL CWave::Create(UINT uiResID, HMODULE hmod)
{
	// Free any previous wave image data
	Free();

	// Flag as resource memory
	m_bResource = TRUE;

	// Find the wave resource
	HRSRC hresInfo;
	hresInfo = ::FindResource(hmod, MAKEINTRESOURCE(uiResID), "WAVE");
	if (!hresInfo)
		return FALSE;

	// Load the wave resource
	HGLOBAL hgmemWave = ::LoadResource(hmod, hresInfo);

	if (hgmemWave) {
		// Get pointer to and length of the wave image data
		m_pImageData= (BYTE*)::LockResource(hgmemWave);
		m_dwImageLen = ::SizeofResource(hmod, hresInfo);
	}

	return (m_pImageData ? TRUE : FALSE);
}

BOOL CWave::Play(BOOL bAsync, BOOL bLooped) const
{
	// Check validity
	if (!IsValid())
		return FALSE;

	// Play the wave
	return ::PlaySound((LPCSTR)m_pImageData, NULL, SND_MEMORY |	SND_NODEFAULT |
		(bAsync ? SND_ASYNC : SND_SYNC) | (bLooped ? (SND_LOOP | SND_ASYNC) : 0));
}

BOOL CWave::GetFormat(WAVEFORMATEX& wfFormat) const
{
	// Check validity
	if (!IsValid())
		return FALSE;

	// Setup and open the MMINFO structure
	CMMMemoryIOInfo mmioInfo((HPSTR)m_pImageData, m_dwImageLen);
	CMMIO mmio(mmioInfo);

	// Find the WAVE chunk
	CMMTypeChunk mmckParent('W','A','V','E');
	mmio.Descend(mmckParent, MMIO_FINDRIFF);

	// Find and read the format subchunk
	CMMIdChunk mmckSubchunk('f','m','t',' ');
	mmio.Descend(mmckSubchunk, mmckParent, MMIO_FINDCHUNK);
	mmio.Read((HPSTR)&wfFormat, sizeof(WAVEFORMATEX));
	mmio.Ascend(mmckSubchunk);

	return TRUE;
}

DWORD CWave::GetDataLen() const
{
	// Check validity
	if (!IsValid())
		return 0;

	// Setup and open the MMINFO structure
	CMMMemoryIOInfo mmioInfo((HPSTR)m_pImageData, m_dwImageLen);
	CMMIO mmio(mmioInfo);

	// Find the WAVE chunk
	CMMTypeChunk mmckParent('W','A','V','E');
	mmio.Descend(mmckParent, MMIO_FINDRIFF);

	// Find and get the size of the data subchunk
	CMMIdChunk mmckSubchunk('d','a','t','a');
	mmio.Descend(mmckSubchunk, mmckParent, MMIO_FINDCHUNK);
	return mmckSubchunk.cksize;
}

DWORD CWave::GetData(BYTE*& pWaveData, DWORD dwMaxLen) const
{
	// Check validity
	if (!IsValid())
		return 0;

	// Setup and open the MMINFO structure
	CMMMemoryIOInfo mmioInfo((HPSTR)m_pImageData, m_dwImageLen);
	CMMIO mmio(mmioInfo);

	// Find the WAVE chunk
	CMMTypeChunk mmckParent('W','A','V','E');
	mmio.Descend(mmckParent, MMIO_FINDRIFF);

	// Find and get the size of the data subchunk
	CMMIdChunk mmckSubchunk('d','a','t','a');
	mmio.Descend(mmckSubchunk, mmckParent, MMIO_FINDCHUNK);
	DWORD dwLenToCopy = mmckSubchunk.cksize;

	// Allocate memory if the passed in pWaveData was NULL
	if (pWaveData == NULL)
		pWaveData = (BYTE*)::GlobalLock(::GlobalAlloc(GMEM_MOVEABLE, dwLenToCopy));
	else
	// If we didn't allocate our own memory, honor dwMaxLen
	if (dwMaxLen < dwLenToCopy)
		dwLenToCopy = dwMaxLen;
	if (pWaveData)
		// Read waveform data into the buffer
		mmio.Read((HPSTR)pWaveData, dwLenToCopy);

	return dwLenToCopy;
}

// Protected
BOOL CWave::Free()
{
	// Free any previous wave data
	if (m_pImageData)
	{
#ifndef WIN32
		HGLOBAL  hgmemWave = ::GlobalHandle(m_pImageData);

		if (hgmemWave)
		{
			if (m_bResource)
				// Free resource (Win95 does NOT automatically do this)
				::FreeResource(hgmemWave);
			else {
				// Unlock and free memory
				::GlobalUnlock(hgmemWave);
				::GlobalFree(hgmemWave);
			}
			m_pImageData = NULL;
			m_dwImageLen = 0;
			return TRUE;
		}
#endif // WIN32
		m_pImageData = NULL;
		m_dwImageLen = 0;
	}
	return FALSE;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer 13
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions