www.pudn.com > AM.rar > WAVE.CPP


#include        
#include  
#include 	    
#include  
#include "Wave.h"
char lpErrMsg[100];	 // save wave error message 
//--------------------------------------------------------------------------- 
//play wave by WavePlay 
//--------------------------------------------------------------------------- 
HWAVEOUT WavePlay(DWORD nID, LPSTR lpFileName ,LPLINEINFO pLineData)	 
{  
	WAVEFORMATEX *lpWaveFormat = NULL; 
	WAVEHDR *lpWaveHdr = NULL; 
	WAVEHDR *lpWaveHdr2 = NULL; 
	HMMIO hmmioH;       
	HWAVEOUT hWaveOut = NULL; 
	MMCKINFO mmParent, mmSubchunk; 
	DWORD dwFmtSize, dwDataSize; 
	HPSTR lpWaveData = NULL; 
	MMRESULT mmrc; 
	 
	// Open wave file  
    hmmioH = mmioOpen(lpFileName, NULL, MMIO_READ);  
    if(!hmmioH) 
    {    
		printf("\n###Line %d Input WAVE file open failed",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d Input WAVE file open failed", pLineData->nLineID); 
		MessageBox(NULL,"lpErrMsg","WavePlay",MB_OK); 
        return NULL; 
    }                  
     
    // Locate a RIFF?  chunk with a WAVE?   Form type  
    mmParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); 
    if (mmioDescend(hmmioH, (LPMMCKINFO) &mmParent, NULL, MMIO_FINDRIFF)) 
	{  
		mmioClose(hmmioH, 0); 
        printf("\n###Line %d Corrupted WAVE file(no WAVE form type)",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d Corrupted WAVE file(no WAVE form type)", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
		return NULL; 
	} 
 
	// Find the format chunk  
    mmSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' '); 
    if (mmioDescend(hmmioH, &mmSubchunk, &mmParent, MMIO_FINDCHUNK)) 
    { 
        mmioClose(hmmioH, 0); 
        printf("\n###Line %d Corrupted WAVE file(no fmt chunk)",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d Corrupted WAVE file(no fmt chunk)", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
        return NULL; 
    } 
	 
    // Get the size of the format chunk, allocate memory for it  
    dwFmtSize = mmSubchunk.cksize; 
    lpWaveFormat = (WAVEFORMATEX *) malloc(dwFmtSize); 
 
    if (!lpWaveFormat) 
    { 
        printf("\n###Line %d Memory alloc for waveformat failed",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d Memory alloc for waveformat failed", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
        mmioClose(hmmioH, 0); 
        return NULL; 
    } 
 
	ZeroMemory((PVOID)lpWaveFormat, dwFmtSize); 
 
    // Read the format chunk  
    if (mmioRead(hmmioH, (HPSTR) lpWaveFormat, dwFmtSize) != (LONG) dwFmtSize) 
    { 
        printf("\n###Line %d Read fmt chunk failed",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d Read fmt chunk failed", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
        mmioClose(hmmioH, 0); 
		goto PlayFailed; 
    } 
     
    // Ascend out of the format subchunk  
    mmioAscend(hmmioH, &mmSubchunk, 0); 
     
    // Find the data subchunk  
    mmSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); 
    if (mmioDescend(hmmioH, &mmSubchunk, &mmParent, MMIO_FINDCHUNK)) 
    { 
        printf("\n###Line %d Could not find data subchunk",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d Could not find data subchunk", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
        mmioClose(hmmioH, 0); 
		goto PlayFailed; 
    } 
     
    // Get the size of the data subchunk  
    dwDataSize = mmSubchunk.cksize; 
    if (dwDataSize == 0L) 
    { 
        printf("\n###Line %d No data to play",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d No data to play", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
        mmioClose(hmmioH, 0); 
		goto PlayFailed; 
    } 
	//check dwDataSize is greater than WAVEBUFSIZE(=16000) ,then assign	value to dwplaysize 
	pLineData->dwPlaySize = dwDataSize > WAVEBUFSIZE ? WAVEBUFSIZE : dwDataSize; 
 
    // Read the waveform data subchunk  
    if(mmioRead(hmmioH, (HPSTR) pLineData->lpWaveDataAlloc, pLineData->dwPlaySize)!= 
		                                                      (LONG)pLineData->dwPlaySize) 
    { 
        printf("\n###Line %d Data read failed",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d Data read failed", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
        mmioClose(hmmioH, 0); 
		goto PlayFailed; 
    } 
	dwDataSize -= pLineData->dwPlaySize;  //decrease dwDataSize after read it  
 
    // Allocate a waveform data header  
    lpWaveHdr = (WAVEHDR *) malloc((DWORD)sizeof(WAVEHDR)); 
	lpWaveHdr2 = (WAVEHDR *) malloc((DWORD)sizeof(WAVEHDR)); 
    if (!lpWaveHdr || !lpWaveHdr2) 
    { 
        printf("\n###Line %d Memory alloc for WAVE header failed",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d Memory alloc for WAVE header failed", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
		goto PlayFailed; 
    } 
 
	// Set up WAVEHDR structure and prepare it to be written to wave device  
    lpWaveHdr->lpData = pLineData->lpWaveDataAlloc; 
    lpWaveHdr->dwBufferLength = pLineData->dwPlaySize; 
    lpWaveHdr->dwFlags = 0L; 
    lpWaveHdr->dwLoops = 0L; 
    lpWaveHdr->dwUser  = (DWORD) nID; 
 
	//read enough size into hmmioH 
	pLineData->dwPlaySize = dwDataSize > WAVEBUFSIZE ? WAVEBUFSIZE : dwDataSize; 
    // Read the waveform data subchunk  
    if(mmioRead(hmmioH, (HPSTR) pLineData->lpWaveDataAlloc2, pLineData->dwPlaySize)!= 
		                                                       (LONG)pLineData->dwPlaySize) 
    { 
        printf("\n###Line %d Data read failed",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d Data read failed", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
        mmioClose(hmmioH, 0); 
		goto PlayFailed; 
    } 
	dwDataSize -= pLineData->dwPlaySize; 
	// Set up WAVEHDR2 structure and prepare it to be written to wave device  
    lpWaveHdr2->lpData = pLineData->lpWaveDataAlloc2; 
    lpWaveHdr2->dwBufferLength = pLineData->dwPlaySize; 
    lpWaveHdr2->dwFlags = 0L; 
    lpWaveHdr2->dwLoops = 0L; 
    lpWaveHdr2->dwUser  = (DWORD) nID; 
    /* make sure wave device can play our format */ 
    if (mmrc = waveOutOpen((LPHWAVEOUT)NULL, nID, lpWaveFormat,  
                    0L, 0L, WAVE_FORMAT_QUERY | WAVE_MAPPED)) 
	{ 
		printf("\n###Line %d First waveOutOpen failed error# %x",pLineData->nLineID, mmrc); 
		wsprintf(lpErrMsg,"Line %d First waveOutOpen failed error# %x", pLineData->nLineID,mmrc); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
		goto PlayFailed; 
    } 
	 
    //open the wave device corresponding to the line  
	if (mmrc = waveOutOpen (&hWaveOut, nID, lpWaveFormat,  
          (DWORD)WaveCallBack, (DWORD)pLineData, CALLBACK_FUNCTION | WAVE_MAPPED))	   //0L 
	{                                            
		printf("\n###Line %d opening wave device error #%x",pLineData->nLineID, mmrc); 
		wsprintf(lpErrMsg,"Line %d opening wave device error #%x", pLineData->nLineID,mmrc); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
		goto PlayFailed; 
	} 
 
    //prepare the message header for playing  
    if (waveOutPrepareHeader (hWaveOut, lpWaveHdr, sizeof(WAVEHDR)) || 
		  waveOutPrepareHeader (hWaveOut, 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,"WavePlay",MB_OK); 
		goto PlayFailed; 
    } 
 
    // Set the volume before playing 
    waveOutSetVolume(hWaveOut, 0x8888); //volume level form 0x0000 ~ 0xFFFF 
 
    // play the message right from the data segment,  set the play message flag  
	// play wave data from lpwaveHdr 
    if (waveOutWrite (hWaveOut, lpWaveHdr, sizeof (WAVEHDR)) || 
		  waveOutWrite (hWaveOut, lpWaveHdr2, sizeof (WAVEHDR))) 
	{ 
		printf("\n###Line %d error writing wave message",pLineData->nLineID); 
		wsprintf(lpErrMsg,"Line %d error writing wave message", pLineData->nLineID); 
		MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); 
        goto PlayFailed; 
    } 
 
	printf("\nLine %d play %s...",pLineData->nLineID,lpFileName); 
 
	// restore to pLineData then can use later 
	pLineData->hmmioH = hmmioH; 
	pLineData->dwDataSize = dwDataSize; 
	pLineData->lpWaveHdr = lpWaveHdr; 
	pLineData->lpWaveHdr2 = lpWaveHdr2; 
	pLineData->dwWaveStage = 1; 
	pLineData->wWaveBufState = 0; 
 
    free( lpWaveFormat ); 
 
    return hWaveOut; 
 
	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) 
 
}