wave.cpp

来自「VC写的用TAPI实现的自动应答系统(Answering Machine).」· C++ 代码 · 共 422 行 · 第 1/2 页

CPP
422
字号

	PlayFailed:            

    if(lpWaveFormat) free( lpWaveFormat );
    if(lpWaveHdr) free(lpWaveHdr);
    if(lpWaveHdr2) free(lpWaveHdr2);
	if(hWaveOut) waveOutClose(hWaveOut);
    return NULL;
}
//---------------------------------------------------------------------------
//Record income call by WaveRecord
//---------------------------------------------------------------------------
HWAVEIN WaveRecord(UINT nID, DWORD dwBufSize,LPLINEINFO pLineData)
{
    HWAVEIN hWaveIn;
	WAVEFORMATEX pcWaveFormat = {WAVE_FORMAT_PCM, 1, 8000, 8000, 1,8};
	LPWAVEHDR lpWaveHdr = NULL;
	LPWAVEHDR lpWaveHdr2 = NULL;
	HMMIO hmmioH;      
	MMCKINFO mmParent, mmSubchunk;
	PWAVEININFO pCash = (PWAVEININFO)new WAVEININFO;
	WORD wrc,cSamples;
	char lpszName[15];

	//assign the dwdatasize for record
	pLineData->dwDataSize = dwBufSize < WAVEBUFSIZE*2 ? WAVEBUFSIZE*2 : dwBufSize;

	wsprintf(lpszName,"income%d.wav", pLineData->nLineID);	  //indicate file name
	//create chunk for income%d.wav
	hmmioH = mmioOpen(lpszName,NULL,MMIO_CREATE|MMIO_WRITE);
	mmParent.fccType = mmioFOURCC('W','A','V','E');
	mmParent.cksize = 0L;
	mmioCreateChunk(hmmioH,&mmParent,MMIO_CREATERIFF);

	mmSubchunk.ckid = mmioFOURCC('f','m','t',' ');
	mmSubchunk.cksize = 0L;
	mmioCreateChunk(hmmioH, &mmSubchunk, 0 );
	mmioWrite(hmmioH, (HPSTR) (LPWAVEFORMATEX)&pcWaveFormat, sizeof(pcWaveFormat));
	mmioAscend(hmmioH, &mmSubchunk, 0);
	
	mmSubchunk.ckid = mmioFOURCC('f','a','c','t');
	mmSubchunk.cksize = 0L;
	mmioCreateChunk(hmmioH, &mmSubchunk, 0);

	cSamples = 0L;
	mmioWrite(hmmioH, (HPSTR)&cSamples, sizeof(DWORD));
	mmioAscend(hmmioH, &mmSubchunk, 0);
	
	mmSubchunk.ckid = mmioFOURCC('d','a','t','a');
	mmSubchunk.cksize = 0L;
	mmioCreateChunk(hmmioH, &mmSubchunk, 0);

	if(!pCash) 
	{
		printf("\n###Line %d Memory allocation failed in record",pLineData->nLineID);
		wsprintf(lpErrMsg,"Line %d Memory allocation failed in record", pLineData->nLineID);
		MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK);
		return NULL;
	} 

	pCash->WF = pcWaveFormat ;
	// open recorder 
	if (wrc = waveInOpen( &hWaveIn, (WORD) nID, (LPWAVEFORMATEX)&pcWaveFormat,
                 (DWORD)WaveCallBack, (DWORD)pLineData, CALLBACK_FUNCTION | WAVE_MAPPED)) 
	{
		printf("\n###Line %d opening wave record device error #%x",pLineData->nLineID, wrc);
		wsprintf(lpErrMsg,"Line %d opening wave record device error #%x", pLineData->nLineID,wrc);
		MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK);
		goto RecordFailed;
	} 
	
    // allocate wave header
	lpWaveHdr = (LPWAVEHDR) malloc((long)sizeof(WAVEHDR));
	lpWaveHdr2 = (LPWAVEHDR) malloc((long)sizeof(WAVEHDR));
    if(!lpWaveHdr || !lpWaveHdr2)
	{
		printf("\n###Line %d Memory alloc for in/header failed",pLineData->nLineID);
		wsprintf(lpErrMsg,"Line %d Memory alloc for in/header failed", pLineData->nLineID);
		MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK);
		goto RecordFailed;
    }

	// Set up WAVEHDR structure and prepare it to be read from wave device 
	lpWaveHdr->lpData = pLineData->lpWaveDataAlloc;
	lpWaveHdr->dwBufferLength = WAVEBUFSIZE;
	lpWaveHdr->dwFlags=0L;
	lpWaveHdr->dwLoops=0L;
	lpWaveHdr->dwUser = (DWORD)pCash;

	lpWaveHdr2->lpData = pLineData->lpWaveDataAlloc2;
	lpWaveHdr2->dwBufferLength = WAVEBUFSIZE;
	lpWaveHdr2->dwFlags=0L;
	lpWaveHdr2->dwLoops=0L;
	lpWaveHdr2->dwUser = (DWORD)pCash;
	//prepare the message header for recording 
	if (waveInPrepareHeader(hWaveIn, lpWaveHdr, sizeof(WAVEHDR)) ||
		 waveInPrepareHeader(hWaveIn, lpWaveHdr2, sizeof(WAVEHDR))) 
	{
		printf("\n###Line %d Error preparing message header.",pLineData->nLineID);
		wsprintf(lpErrMsg,"Line %d Error preparing message header.", pLineData->nLineID);
		MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK);
		goto RecordFailed;
	}
	//add lpwavehdr into wave device
	if (waveInAddBuffer (hWaveIn, lpWaveHdr, sizeof(WAVEHDR))||
		 waveInAddBuffer (hWaveIn, lpWaveHdr2, sizeof(WAVEHDR))) 
	{
		printf("\n###Line %d Error adding buffer",pLineData->nLineID);
		wsprintf(lpErrMsg,"Line %d Error adding buffer", pLineData->nLineID);
		MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK);
		goto RecordFailed;
	}
	//start recording
	if(waveInStart(hWaveIn)) 
	{
		printf("\n###Line %d Failed to start recording",pLineData->nLineID);
		wsprintf(lpErrMsg,"Line %d Failed to start recording", pLineData->nLineID);
		MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK);
		goto RecordFailed;
	}

	//restore info to pLineData , then will be use later
	pLineData->hmmioH = hmmioH;
	pLineData->mmParent = mmParent;
	pLineData->mmSubchunk = mmSubchunk;
	pLineData->lpWaveHdr = lpWaveHdr;
	pLineData->lpWaveHdr2 = lpWaveHdr2;
	pLineData->wWaveBufState = 0;
	pLineData->dwWaveStage = 1;
	pLineData->dwDataSize -= WAVEBUFSIZE*2;

	printf("\nLine %d start recording in [income%d.wav]....(press # to stop record)",pLineData->nLineID,pLineData->nLineID);


	return hWaveIn;

	RecordFailed:   
	
	if(pCash) delete pCash;
    if(lpWaveHdr) free(lpWaveHdr);
	if(hWaveIn) waveInClose(hWaveIn);
    return NULL;

} 
//---------------------------------------------------------------------------
// WIM & WOM message handler	
// Wave call back function								    
void CALLBACK WaveCallBack( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance,	
									DWORD dwParam1,	DWORD dwParam2)
{   
	LPLINEINFO pLineData = (LPLINEINFO)dwInstance;

	//printf("\nhwo=%x,uMsg=%x,dwInstance=%x,p1=%x,p2=%x,pLineout=%x",
	//		hwo,uMsg,dwInstance,dwParam1,dwParam2,&pLineOut);
	switch ( uMsg )
	{
		case WOM_DONE :	  //wave out callback come here	
			if( pLineData->dwWaveStage )	 	  //continue read wave data ?
			{	
	     	    if ( pLineData->dwDataSize == 0)  //check wave date size
				{
				    pLineData->dwWaveStage = 0;
					break;
				}

				if ( pLineData->wWaveBufState )	  //check which buf need waveoutwrite
					lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ADDPLAYSTAGE2);
				else
					lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ADDPLAYSTAGE);
			    break;
			}

			switch (pLineData->dwCallState)
			{
				case TAPI_PLAYGREET:
					lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ENDPLAYGREET);
					break;
				case TAPI_PREPAREPLAYICM:
					lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_PREPAREPLAYICM);
					break;
				case TAPI_PLAYICM:		
					lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ENDPLAYICM);
					break;
			}
			break;
		case WIM_DATA: 	  //wave in callback come here
			if( pLineData->dwWaveStage )		 //continue record ?
			{	
	     	    if ( pLineData->dwDataSize == 0)  //check wave date size
				{
				    pLineData->dwWaveStage = 0;
					break;
				}
				if ( pLineData->wWaveBufState )	 //check which buf need to write into hmmioH
					lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ADDRECORDSTAGE2);
				else
					lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ADDRECORDSTAGE);
			    break;
			}

			if (pLineData->dwCallState & TAPI_RECORDICM)
			{
				lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ENDRECORDICM);
			}
			break;
	} //end switch case (uMsg)

}


⌨️ 快捷键说明

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