⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hsound.cpp

📁 一个使用tapi实现的自动语音应答的例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 /*****************************************************************
 * HSound.cpp: implementation of the CHSound class.
 *
 * WARNINGS:
 *			  - Just 1 and only 1 instance of this class must be
 *				created.
 *
 *
 * Auther: Hamed.M.
 * eMail : HamedMosavi @ hotmail.com
 *		   HamedMosavi @ gmail.com
 *****************************************************************/
 
#include "stdafx.h"
#include "HSound.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define SET			 0
#define KILL		 1

DWORD	CHSound::m_dwStatus = STT_ASLEEP;
BOOL	CHSound::m_bContinue = TRUE;
BOOL	CHSound::m_bThreadContinue = TRUE;
HANDLE	CHSound::m_hStatEvent = NULL;
LPWAVEHDR		CHSound::m_lpWHdr = NULL;

 /*****************************************************************
 * Constructor
 *****************************************************************/
//HANDLE CHSound::s_hEvent = NULL;
CHSound::CHSound()
{
	InitializeCriticalSection(&m_statusCrtcSec);
	InitializeCriticalSection(&m_externalResetCrtcSec);
	
	m_hStatEvent = CreateEvent(NULL, TRUE/*ManualReset*/, FALSE, NULL);

	m_bThreadContinue = TRUE;			/* Don't exit the thread */
						  /* Run a thread to cleanup wave buffer */
	m_pCallBackThread = AfxBeginThread (
		CallBackThread,
		(LPVOID) this,
		THREAD_PRIORITY_NORMAL);

	m_dwMinBufSize	= 10240;//61440;//10240;//5120;					// = 5 KBytes

	m_bExitAfter = FALSE;
	m_bForceClose = FALSE;
	m_sndIndex   = 0;
	m_wndTimer   = NULL;
	m_dwDevId	 = 0;

	m_playList.Reset();
}

 /*****************************************************************
 * Destructor
 *****************************************************************/
CHSound::~CHSound()
{
	m_bThreadContinue = FALSE;
	DeleteCriticalSection(&m_statusCrtcSec);
	DeleteCriticalSection(&m_externalResetCrtcSec);
}

 /*****************************************************************
 * Plays a given file, to the given device
 *****************************************************************/
BOOL CHSound::Play(DWORD dwDevId, LPCTSTR szWaveFile)
{
	if (GetStatus() != STT_ASLEEP)
		return FALSE;

	SetStatus(STT_PREPARE);

	m_dwDevId	 = dwDevId;
	HPSTR lpData = NULL;				 /* Pointer to Wave data */
	LPWAVEFORMATEX	lpWaveFormatEx = NULL;
	MMRESULT mmRes;
	LPWAVEHDR		lpWaveHdr = NULL;

	m_dwBufCnt		= 0;
	m_dwCurrtBufIndex=0;
	m_dwDataSize	= 0;


	SetStatus(STT_FILEOPN);
	lpData = Open( szWaveFile,			 /* Open & read WaveFile */
		  lpWaveFormatEx,
		  m_dwDataSize);
	SetStatus(STT_PREPARE);

	if ( NULL == lpData )	{			   /* File opening error */
		goto CLEAN_EXIT;
	}

	if (!m_bContinue) {
		goto CLEAN_EXIT;
	}
								 /* Allocate a buffer for header */
	lpWaveHdr = (LPWAVEHDR) calloc (1,(DWORD)sizeof(WAVEHDR));
	
	if (! lpWaveHdr) {						/* Can't allocate memory */
		goto CLEAN_EXIT;
	}

	if (!m_bContinue) {
		goto CLEAN_EXIT;
	}

	if (m_dwDataSize>m_dwMinBufSize) {
		m_dwBufCnt = m_dwDataSize / m_dwMinBufSize;

		// a 13 KB file for example
		if ( (m_dwBufCnt*m_dwMinBufSize) < m_dwDataSize)
			m_dwBufCnt++;
	
		lpWaveHdr->dwBufferLength = m_dwMinBufSize;
		m_dwBLength = ( (m_dwDataSize-m_dwMinBufSize)>m_dwMinBufSize)?m_dwMinBufSize:(m_dwDataSize-m_dwMinBufSize);
		m_lpBuf2 = lpData;
		m_lpBuf2 += m_dwMinBufSize;
	} else {
		lpWaveHdr->dwBufferLength = m_dwDataSize;
	}

	m_lpWHdr = lpWaveHdr;
	lpWaveHdr->lpData = lpData;
	m_lpData = lpData;

	SetStatus(STT_OPENING);
				   /* Open the device, and set callback function */
	mmRes = waveOutOpen (
		&m_hWaveOut,
		dwDevId,
		lpWaveFormatEx,
		(DWORD)m_pCallBackThread->m_nThreadID,
		0L,
		CALLBACK_THREAD | WAVE_MAPPED);
	
								  /* Can't Open specified device */
	if ( MMSYSERR_NOERROR != mmRes ) {
		SetStatus(STT_CLOSING);
		waveOutClose(m_hWaveOut);
		return FALSE;
	}
	
	free(lpWaveFormatEx);
	lpWaveFormatEx = NULL;

	if (!m_bContinue) {
		SetStatus(STT_CLOSING);
		waveOutClose(m_hWaveOut);
		goto CLEAN_EXIT;
	}
											   /* Prepare header */
	mmRes = waveOutPrepareHeader(
		m_hWaveOut,
		lpWaveHdr,
		sizeof (WAVEHDR) );

										 /* Can't Prepare header */
	if ( MMSYSERR_NOERROR != mmRes ) {
		SetStatus(STT_CLOSING);
		waveOutClose(m_hWaveOut);
		goto CLEAN_EXIT;
	}

	if (!m_bContinue) {
		SetStatus(STT_RSTTING);
		waveOutUnprepareHeader(m_hWaveOut,lpWaveHdr,sizeof(WAVEHDR));
		SetStatus(STT_CLOSING);
		waveOutClose(m_hWaveOut);
		goto CLEAN_EXIT;
	}
				   /* Modem's are weak! Loud as much as possible */
	waveOutSetVolume(m_hWaveOut,0xFF00FF00);

	SetStatus(STT_PLAYING);
						  /* Write a block of data to the device */
	mmRes = waveOutWrite(
		m_hWaveOut,
		lpWaveHdr,
		sizeof(WAVEHDR) );

									/* Can't Do the last job :(( */
	if ( MMSYSERR_NOERROR != mmRes ) {
		SetStatus(STT_RSTTING);
		waveOutUnprepareHeader(m_hWaveOut,lpWaveHdr,sizeof(WAVEHDR));
		SetStatus(STT_CLOSING);
		waveOutClose(m_hWaveOut);
		goto CLEAN_EXIT;
	}

	if (m_dwDataSize>m_dwMinBufSize) {
		m_lpWHdr->lpData = m_lpBuf2;
		m_lpWHdr->dwBufferLength = m_dwBLength;
		m_dwCurrtBufIndex++;
	}
	/* Playback started, events will be received by callback
	   function, then it will notify thread to cleanup.			 */
	return TRUE;

CLEAN_EXIT:;
	SetStatus(STT_RSTTING);

	if (lpData)
		free(lpData);
	
	if (lpWaveFormatEx)
		free(lpWaveFormatEx);

	if (lpWaveHdr)
		free(lpWaveHdr);

	SetStatus(STT_ASLEEP);

	return FALSE;
}

 /*****************************************************************
 * Opens a wave file, buffers wave data
 * Returns a pointer to buffer
 *****************************************************************/
HPSTR CHSound::Open(LPCTSTR szWaveFile, LPWAVEFORMATEX& lpWaveFmt, DWORD& dwDataSize)
{
	HMMIO hmmio;
    MMCKINFO        mmckinfoParent;
    MMCKINFO        mmckinfoSubchunk;
	DWORD			dwFmtSize = 0;

    hmmio = mmioOpen((unsigned short*)		   /* Open Wave file */
		szWaveFile, NULL, MMIO_READ | MMIO_ALLOCBUF);

    if(!hmmio)									   /* Can't open */
    {
        return NULL;
    }

	if (!m_bContinue)
	{
        mmioClose(hmmio, 0);
        return NULL;
	}

								/* Make sure file format is Wave */
    mmckinfoParent.fccType = MAKEFOURCC('W', 'A', 'V', 'E');
    if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, 
		NULL, MMIO_FINDRIFF))
    {								/* File format is NOT 'Wave' */
        mmioClose(hmmio, 0);
        return NULL;
    }

	if (!m_bContinue)
	{
        mmioClose(hmmio, 0);
        return NULL;
	}
    
							/* Make sure there is a 'fmt ' chunk */
    mmckinfoSubchunk.ckid = MAKEFOURCC('f', 'm', 't', ' ');
    if (mmioDescend(hmmio, (LPMMCKINFO)&mmckinfoSubchunk, 
		(LPMMCKINFO)&mmckinfoParent, MMIO_FINDCHUNK))
    {										  /* No 'fmt ' chunk */
        mmioClose(hmmio, 0);
        return NULL;
    }
	if (!m_bContinue)
	{
        mmioClose(hmmio, 0);
        return NULL;
	}

								/* Find size of the 'fmt ' chunk */
    dwFmtSize = mmckinfoSubchunk.cksize;

							 /* Allocate memory for format chunk */
    lpWaveFmt = (LPWAVEFORMATEX) calloc (1, dwFmtSize);
//		HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY, dwFmtSize);
    if (!lpWaveFmt)				 /* Can't alocate memory */
    {
        mmioClose(hmmio, 0);
        return NULL;
    }

	if (!m_bContinue)
	{
		free(lpWaveFmt);
        mmioClose(hmmio, 0);
        return NULL;
	}
											/* Read 'fmt ' chunk */
    if (mmioRead(hmmio, (HPSTR) lpWaveFmt, dwFmtSize) != 
		(LONG) dwFmtSize)
    {									 /* Corrupt 'fmt ' chunk */
		free(lpWaveFmt);
        mmioClose(hmmio, 0);
        return NULL;
    }
	if (!m_bContinue)
	{
		free(lpWaveFmt);
        mmioClose(hmmio, 0);
        return NULL;
	}
							/* Ascend out of the 'fmt ' subchunk */
    mmioAscend(hmmio, &mmckinfoSubchunk, 0);

									   /* Find the data subchunk */
    mmckinfoSubchunk.ckid = MAKEFOURCC('d', 'a', 't', 'a');
    if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, 
		MMIO_FINDCHUNK))
    {										/* No data subchunk! */
		free(lpWaveFmt);
        mmioClose(hmmio, 0);
        return NULL;
    }

							/* Get the size of the data subchunk */
    dwDataSize = mmckinfoSubchunk.cksize;
    if ( 0L == dwDataSize )	 /* No data in the data subchunk */
    {
		free(lpWaveFmt);
        mmioClose(hmmio, 0);
        return NULL;
    }

	if (!m_bContinue)
	{
		free(lpWaveFmt);
        mmioClose(hmmio, 0);
		dwDataSize = 0;
        return NULL;
	}
					/* Allocate memory for data, no need to lock */
	HPSTR lpData = (HPSTR) calloc (1, dwDataSize );
//		HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY, dwDataSize);

							  /* Read the waveform data subchunk */
    if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) 
		!= (LONG) dwDataSize)
    {
		free(lpWaveFmt);
		free(lpData);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -