www.pudn.com > hmmPlatform.rar > SmallFileWaveOut.cpp


#include "StdAfx.h" 
#include ".\smallfilewaveout.h" 
#include "math.h" 
 
CSmallFileWaveOut::CSmallFileWaveOut(void) 
{ 
	this->m_allocData.lpData = NULL; 
} 
 
CSmallFileWaveOut::~CSmallFileWaveOut(void) 
{ 
	this->Stop(); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 打开输出设备,设置回调方式,并分配播放缓冲,读入全部裸音频数据  
BOOL CSmallFileWaveOut::Init(WAVEFORMATEX fmt, DWORD hWnd) 
{ 
	// 打开输出设备,设置回调方式 
	BOOL bRet = CWaveOut::Init(fmt, hWnd); 
	// 读取字节数 
	UINT nRead = 0; 
 
	// 全部读入裸音频数据 
	if (bRet) 
	{ 
		// 分配缓冲块结构 
		nRead = this->m_wavFile.GetDataChunkSize(); 
		this->m_allocData.lpData = new char[nRead]; 
 
		if (this->m_allocData.lpData != NULL) 
		{ 
			this->m_wavFile.Reset(); 
			// 获取实际读取得byte数 
			nRead = this->m_wavFile.ReadBytes(this->m_allocData.lpData, nRead); 
			 
			// 填写缓冲块格式信息 
			this->m_allocData.dwBufferLength = nRead; 
			this->m_allocData.dwBytesRecorded = 0; 
			this->m_allocData.dwFlags = 0; 
			this->m_allocData.dwLoops = 0; 
			this->m_allocData.dwUser = nRead; 
 
			// 预制缓冲块 
			waveOutPrepareHeader(this->m_hWaveOut,  
				&this->m_allocData, sizeof(WAVEHDR)); 
		} 
	} 
 
	return bRet; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 处理WOM_DONE消息,继续播放下一个缓冲块 
LRESULT CSmallFileWaveOut::OnDone(DWORD dwParam) 
{ 
	return 0; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 获得指定范围内的样本点 
void CSmallFileWaveOut::GetSamples(WAVEHDR* pWaveHdr, unsigned int nFrom, unsigned int nCount) const 
{ 
	// 计算实际起始字节位置 
	unsigned nBytesFrom = 0; 
	// 计算实际包含字节数 
	unsigned int nTotalBytes = 0; 
	// wave文件格式信息 
	WAVEFORMATEX fmt = this->m_wavFile.GetWaveFormat(); 
	// 尚可播放的音频数据字节数 
	unsigned int nRest = 0; 
 
	if (pWaveHdr != NULL && this->m_allocData.lpData != NULL) 
	{ 
		nBytesFrom = nFrom * fmt.nBlockAlign; 
		nTotalBytes = nCount * fmt.nBlockAlign; 
		nRest = this->m_wavFile.GetDataChunkSize() - nBytesFrom; 
		nTotalBytes = ((nTotalBytes > nRest || nTotalBytes <= 0) ? nRest : nTotalBytes); 
 
		pWaveHdr->dwBufferLength = nTotalBytes; 
		pWaveHdr->dwUser = nTotalBytes; 
		pWaveHdr->lpData = &this->m_allocData.lpData[nBytesFrom]; 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 播放指定范围内的样本点 
void CSmallFileWaveOut::PlaySamples(unsigned int nFrom, unsigned int nCount) 
{ 
	// 计算实际起始字节位置 
	unsigned nBytesFrom = 0; 
	// 计算实际包含字节数 
	unsigned int nTotalBytes = 0; 
	// wave文件格式信息 
	WAVEFORMATEX fmt = this->m_wavFile.GetWaveFormat(); 
	// 尚可播放的音频数据字节数 
	unsigned int nRest = 0; 
 
	nBytesFrom = nFrom * fmt.nBlockAlign; 
	nTotalBytes = nCount * fmt.nBlockAlign; 
	nRest = this->m_wavFile.GetDataChunkSize() - nBytesFrom; 
	nTotalBytes = (nTotalBytes > nRest ? nRest : nTotalBytes); 
 
	if (nTotalBytes > 0 && this->m_allocData.lpData != NULL) 
	{ 
		this->m_playBuffer.lpData = &this->m_allocData.lpData[nBytesFrom]; 
		this->m_playBuffer.dwBufferLength = nTotalBytes; 
		this->m_playBuffer.dwBytesRecorded = 0; 
		this->m_playBuffer.dwFlags = 0; 
		this->m_playBuffer.dwUser = nTotalBytes; 
 
		// 预制缓冲块 
		waveOutPrepareHeader(this->m_hWaveOut,  
			&this->m_playBuffer, sizeof(WAVEHDR)); 
 
		// 发送缓冲块 
		waveOutWrite(this->m_hWaveOut, &this->m_playBuffer, sizeof(WAVEHDR)); 
 
		// unprepared音频块 
		waveOutUnprepareHeader( 
			this->m_hWaveOut, &this->m_playBuffer, sizeof(WAVEHDR)); 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 播放音频逻数据 
void CSmallFileWaveOut::Start() 
{ 
	if (this->m_allocData.lpData != NULL) 
	{ 
		CWaveOut::Start(); 
 
		// 发送缓冲块 
		waveOutWrite(this->m_hWaveOut, &this->m_allocData, sizeof(WAVEHDR)); 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 停止播放,关闭输出设备, UnPrepare缓冲块 
void CSmallFileWaveOut::Stop() 
{ 
	// 停止播放 
	CWaveOut::Stop(); 
 
	// unprepared音频块 
	waveOutUnprepareHeader( 
		this->m_hWaveOut, &this->m_allocData, sizeof(WAVEHDR)); 
 
	// 关闭输出设备 
	CWaveOut::CloseDev(); 
 
	// 清除缓冲区,初始化数据 
	this->Dispose(); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 清除缓冲区,初始化数据 
void CSmallFileWaveOut::Dispose() 
{ 
	if (this->m_allocData.lpData != NULL) 
	{ 
		delete[] this->m_allocData.lpData; 
		 
		this->m_allocData.lpData = NULL; 
	} 
 
	// 关闭所打开文件 
	CFileWaveOut::Dispose(); 
}